diff --git a/go.mod b/go.mod
index 69ad060ae..e67332667 100644
--- a/go.mod
+++ b/go.mod
@@ -1,7 +1,7 @@
module sigs.k8s.io/gcp-filestore-csi-driver
go 1.21
-toolchain go1.22.5
+toolchain go1.23.4
require (
cloud.google.com/go/compute/metadata v0.5.2
@@ -14,7 +14,7 @@ require (
github.com/kubernetes-csi/csi-lib-utils v0.13.0
github.com/kubernetes-csi/csi-test/v3 v3.1.1
github.com/onsi/ginkgo v1.16.5
- github.com/onsi/gomega v1.34.2
+ github.com/onsi/gomega v1.35.1
github.com/prashanthpai/sunrpc v0.0.0-20210303180433-689a3880d90a
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
@@ -29,12 +29,12 @@ require (
google.golang.org/protobuf v1.35.1
gopkg.in/gcfg.v1 v1.2.3
k8s.io/api v0.26.0
- k8s.io/apimachinery v0.26.0
+ k8s.io/apimachinery v0.32.0
k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible
k8s.io/component-base v0.26.0
- k8s.io/klog/v2 v2.110.1
- k8s.io/mount-utils v0.24.1
- k8s.io/utils v0.0.0-20230726121419-3b25d923346b
+ k8s.io/klog/v2 v2.130.1
+ k8s.io/mount-utils v0.32.0
+ k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738
sigs.k8s.io/boskos v0.0.0-20201002225104-ae3497d24cd7
sigs.k8s.io/controller-runtime v0.12.1
)
@@ -48,16 +48,17 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
- github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
+ github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
- github.com/go-openapi/jsonpointer v0.19.6 // indirect
+ github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
- github.com/go-openapi/swag v0.22.4 // indirect
+ github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/gnostic v0.7.0 // indirect
@@ -73,12 +74,14 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
+ github.com/moby/sys/mountinfo v0.7.2 // indirect
+ github.com/moby/sys/userns v0.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
- github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
@@ -86,6 +89,7 @@ require (
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
+ github.com/x448/float16 v0.8.4 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
@@ -106,11 +110,11 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.24.1 // indirect
- k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
+ k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
k8s.io/test-infra v0.0.0-20201007205216-b54c51c3a44a // indirect
- sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
- sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
- sigs.k8s.io/yaml v1.3.0 // indirect
+ sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
+ sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
+ sigs.k8s.io/yaml v1.4.0 // indirect
)
replace k8s.io/client-go => k8s.io/client-go v0.26.0
diff --git a/go.sum b/go.sum
index f2e91c6b9..442d47b5e 100644
--- a/go.sum
+++ b/go.sum
@@ -901,8 +901,9 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As=
github.com/denisenkom/go-mssqldb v0.0.0-20190111225525-2fea367d496d/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
@@ -995,6 +996,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fsouza/fake-gcs-server v0.0.0-20180612165233-e85be23bdaa8/go.mod h1:1/HufuJ+eaDf4KTnYdS6HJMGvMRU8d4cYTuu/1QaBbI=
github.com/fsouza/fake-gcs-server v1.19.4/go.mod h1:I0/88nHCASqJJ5M7zVF0zKODkYTcuXFW5J5yajsNJnE=
+github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
+github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
@@ -1032,7 +1035,6 @@ github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
@@ -1060,8 +1062,9 @@ github.com/go-openapi/jsonpointer v0.19.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
+github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
+github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
@@ -1103,8 +1106,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
-github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
-github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
+github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
+github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
@@ -1304,8 +1307,8 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA=
-github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
+github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg=
github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
@@ -1617,6 +1620,10 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
+github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
+github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
+github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
+github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
@@ -1679,8 +1686,8 @@ github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47
github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0=
github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
-github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo=
-github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
+github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
+github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@@ -1697,8 +1704,8 @@ github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeR
github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
-github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
-github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=
+github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
+github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@@ -1745,8 +1752,9 @@ github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6J
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/prashanthpai/sunrpc v0.0.0-20210303180433-689a3880d90a h1:51tKeE/lx4mfb2/PdL2fxnOWGqZhLnS3YKXk1uK2cLg=
@@ -1830,8 +1838,8 @@ github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
-github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
-github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
+github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
+github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -1986,6 +1994,8 @@ github.com/vdemeester/k8s-pkg-credentialprovider v1.13.12-1/go.mod h1:Fko0rTxEtD
github.com/vdemeester/k8s-pkg-credentialprovider v1.17.4/go.mod h1:inCTmtUdr5KJbreVojo06krnTgaeAz/Z7lynpPk/Q2c=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
github.com/xanzy/go-gitlab v0.32.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
@@ -2157,6 +2167,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
+golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
+golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -2637,8 +2649,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
-golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
+golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
+golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -3098,8 +3110,9 @@ k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCk
k8s.io/apimachinery v0.18.5/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
k8s.io/apimachinery v0.18.7-rc.0/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
k8s.io/apimachinery v0.24.1/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
-k8s.io/apimachinery v0.26.0 h1:1feANjElT7MvPqp0JT6F3Ss6TWDwmcjLypwoPpEf7zg=
k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74=
+k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg=
+k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/apiserver v0.0.0-20190918200908-1e17798da8c1/go.mod h1:4FuDU+iKPjdsdQSN3GsEKZLB/feQsj1y9dhhBDVV2Ns=
k8s.io/apiserver v0.16.4/go.mod h1:kbLJOak655g6W7C+muqu1F76u9wnEycfKMqbVaXIdAc=
k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg=
@@ -3156,8 +3169,8 @@ k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
-k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
+k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
+k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
@@ -3167,8 +3180,8 @@ k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C
k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29/go.mod h1:F+5wygcW0wmRTnM3cOgIqGivxkwSWIWT5YdsDbeAOaU=
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk=
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
-k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
-k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
+k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
+k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
k8s.io/kubectl v0.17.2/go.mod h1:y4rfLV0n6aPmvbRCqZQjvOp3ezxsFgpqL+zF5jH/lxk=
k8s.io/kubernetes v1.11.10/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
@@ -3176,8 +3189,8 @@ k8s.io/kubernetes v1.14.7/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/legacy-cloud-providers v0.17.0/go.mod h1:DdzaepJ3RtRy+e5YhNtrCYwlgyK87j/5+Yfp0L9Syp8=
k8s.io/legacy-cloud-providers v0.17.4/go.mod h1:FikRNoD64ECjkxO36gkDgJeiQWwyZTuBkhu+yxOc1Js=
k8s.io/metrics v0.17.2/go.mod h1:3TkNHET4ROd+NfzNxkjoVfQ0Ob4iZnaHmSEA4vYpwLw=
-k8s.io/mount-utils v0.24.1 h1:juKCvkiP4sWklb72OIk/qW7UhDns41ldcR/EHu/T1uA=
-k8s.io/mount-utils v0.24.1/go.mod h1:XrSqB3a2e8sq+aU+rlbcBtQ3EgcuDk5RP9ZsGxjoDrI=
+k8s.io/mount-utils v0.32.0 h1:KOQAhPzJICATXnc6XCkWoexKbkOexRnMCUW8APFfwg4=
+k8s.io/mount-utils v0.32.0/go.mod h1:Kun5c2svjAPx0nnvJKYQWhfeNW+O0EpzHgRhDcYoSY0=
k8s.io/test-infra v0.0.0-20181019233642-2e10a0bbe9b3/go.mod h1:2NzXB13Ji0nqpyublHeiPC4FZwU0TknfvyaaNfl/BTA=
k8s.io/test-infra v0.0.0-20191212060232-70b0b49fe247/go.mod h1:d8SKryJBXAwfCFVL4wieRez47J2NOOAb9d029sWLseQ=
k8s.io/test-infra v0.0.0-20200407001919-bc7f71ef65b8/go.mod h1:/WpJWcaDvuykB322WXP4kJbX8IpalOzuPxA62GpwkJk=
@@ -3198,8 +3211,8 @@ k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
-k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
+k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
knative.dev/caching v0.0.0-20190719140829-2032732871ff/go.mod h1:dHXFU6CGlLlbzaWc32g80cR92iuBSpsslDNBWI8C7eg=
knative.dev/caching v0.0.0-20200116200605-67bca2c83dfa/go.mod h1:dHXFU6CGlLlbzaWc32g80cR92iuBSpsslDNBWI8C7eg=
knative.dev/eventing-contrib v0.6.1-0.20190723221543-5ce18048c08b/go.mod h1:SnXZgSGgMSMLNFTwTnpaOH7hXDzTFtw0J8OmHflNx3g=
@@ -3282,8 +3295,8 @@ sigs.k8s.io/controller-runtime v0.12.1 h1:4BJY01xe9zKQti8oRjj/NeHKRXthf1YkYJAgLO
sigs.k8s.io/controller-runtime v0.12.1/go.mod h1:BKhxlA4l7FPK4AQcsuL4X6vZeWnKDXez/vp1Y8dxTU0=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
+sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
+sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/structured-merge-diff v0.0.0-20190302045857-e85c7b244fd2/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
@@ -3296,13 +3309,14 @@ sigs.k8s.io/structured-merge-diff/v3 v3.0.1-0.20200706213357-43c19bbb7fba/go.mod
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
-sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
-sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
+sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=
+sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
sigs.k8s.io/testing_frameworks v0.1.1/go.mod h1:VVBKrHmJ6Ekkfz284YKhQePcdycOzNH9qL6ht1zEr/U=
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 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
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=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
sourcegraph.com/sqs/pbtypes v1.0.0/go.mod h1:3AciMUv4qUuRHRHhOG4TZOB+72GdPVz5k+c648qsFS4=
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=
diff --git a/vendor/github.com/fxamacker/cbor/v2/.gitignore b/vendor/github.com/fxamacker/cbor/v2/.gitignore
new file mode 100644
index 000000000..f1c181ec9
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/.gitignore
@@ -0,0 +1,12 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
diff --git a/vendor/github.com/fxamacker/cbor/v2/.golangci.yml b/vendor/github.com/fxamacker/cbor/v2/.golangci.yml
new file mode 100644
index 000000000..38cb9ae10
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/.golangci.yml
@@ -0,0 +1,104 @@
+# Do not delete linter settings. Linters like gocritic can be enabled on the command line.
+
+linters-settings:
+ depguard:
+ rules:
+ prevent_unmaintained_packages:
+ list-mode: strict
+ files:
+ - $all
+ - "!$test"
+ allow:
+ - $gostd
+ - github.com/x448/float16
+ deny:
+ - pkg: io/ioutil
+ desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil"
+ dupl:
+ threshold: 100
+ funlen:
+ lines: 100
+ statements: 50
+ goconst:
+ ignore-tests: true
+ min-len: 2
+ min-occurrences: 3
+ gocritic:
+ enabled-tags:
+ - diagnostic
+ - experimental
+ - opinionated
+ - performance
+ - style
+ disabled-checks:
+ - commentedOutCode
+ - dupImport # https://github.com/go-critic/go-critic/issues/845
+ - ifElseChain
+ - octalLiteral
+ - paramTypeCombine
+ - whyNoLint
+ gofmt:
+ simplify: false
+ goimports:
+ local-prefixes: github.com/fxamacker/cbor
+ golint:
+ min-confidence: 0
+ govet:
+ check-shadowing: true
+ lll:
+ line-length: 140
+ maligned:
+ suggest-new: true
+ misspell:
+ locale: US
+ staticcheck:
+ checks: ["all"]
+
+linters:
+ disable-all: true
+ enable:
+ - asciicheck
+ - bidichk
+ - depguard
+ - errcheck
+ - exportloopref
+ - goconst
+ - gocritic
+ - gocyclo
+ - gofmt
+ - goimports
+ - goprintffuncname
+ - gosec
+ - gosimple
+ - govet
+ - ineffassign
+ - misspell
+ - nilerr
+ - revive
+ - staticcheck
+ - stylecheck
+ - typecheck
+ - unconvert
+ - unused
+
+issues:
+ # max-issues-per-linter default is 50. Set to 0 to disable limit.
+ max-issues-per-linter: 0
+ # max-same-issues default is 3. Set to 0 to disable limit.
+ max-same-issues: 0
+
+ exclude-rules:
+ - path: decode.go
+ text: "string ` overflows ` has (\\d+) occurrences, make it a constant"
+ - path: decode.go
+ text: "string ` \\(range is \\[` has (\\d+) occurrences, make it a constant"
+ - path: decode.go
+ text: "string `, ` has (\\d+) occurrences, make it a constant"
+ - path: decode.go
+ text: "string ` overflows Go's int64` has (\\d+) occurrences, make it a constant"
+ - path: decode.go
+ text: "string `\\]\\)` has (\\d+) occurrences, make it a constant"
+ - path: valid.go
+ text: "string ` for type ` has (\\d+) occurrences, make it a constant"
+ - path: valid.go
+ text: "string `cbor: ` has (\\d+) occurrences, make it a constant"
diff --git a/vendor/github.com/fxamacker/cbor/v2/CODE_OF_CONDUCT.md b/vendor/github.com/fxamacker/cbor/v2/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..c794b2b0c
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/CODE_OF_CONDUCT.md
@@ -0,0 +1,133 @@
+
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, caste, color, religion, or sexual
+identity and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the overall
+ community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or advances of
+ any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email address,
+ without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+faye.github@gmail.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series of
+actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or permanent
+ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within the
+community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.1, available at
+[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
+
+Community Impact Guidelines were inspired by
+[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
+
+For answers to common questions about this code of conduct, see the FAQ at
+[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
+[https://www.contributor-covenant.org/translations][translations].
+
+[homepage]: https://www.contributor-covenant.org
+[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
+[Mozilla CoC]: https://github.com/mozilla/diversity
+[FAQ]: https://www.contributor-covenant.org/faq
+[translations]: https://www.contributor-covenant.org/translations
diff --git a/vendor/github.com/fxamacker/cbor/v2/CONTRIBUTING.md b/vendor/github.com/fxamacker/cbor/v2/CONTRIBUTING.md
new file mode 100644
index 000000000..de0965e12
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/CONTRIBUTING.md
@@ -0,0 +1,41 @@
+# How to contribute
+
+You can contribute by using the library, opening issues, or opening pull requests.
+
+## Bug reports and security vulnerabilities
+
+Most issues are tracked publicly on [GitHub](https://github.com/fxamacker/cbor/issues).
+
+To report security vulnerabilities, please email faye.github@gmail.com and allow time for the problem to be resolved before disclosing it to the public. For more info, see [Security Policy](https://github.com/fxamacker/cbor#security-policy).
+
+Please do not send data that might contain personally identifiable information, even if you think you have permission. That type of support requires payment and a signed contract where I'm indemnified, held harmless, and defended by you for any data you send to me.
+
+## Pull requests
+
+Please [create an issue](https://github.com/fxamacker/cbor/issues/new/choose) before you begin work on a PR. The improvement may have already been considered, etc.
+
+Pull requests have signing requirements and must not be anonymous. Exceptions are usually made for docs and CI scripts.
+
+See the [Pull Request Template](https://github.com/fxamacker/cbor/blob/master/.github/pull_request_template.md) for details.
+
+Pull requests have a greater chance of being approved if:
+- it does not reduce speed, increase memory use, reduce security, etc. for people not using the new option or feature.
+- it has > 97% code coverage.
+
+## Describe your issue
+
+Clearly describe the issue:
+* If it's a bug, please provide: **version of this library** and **Go** (`go version`), **unmodified error message**, and describe **how to reproduce it**. Also state **what you expected to happen** instead of the error.
+* If you propose a change or addition, try to give an example how the improved code could look like or how to use it.
+* If you found a compilation error, please confirm you're using a supported version of Go. If you are, then provide the output of `go version` first, followed by the complete error message.
+
+## Please don't
+
+Please don't send data containing personally identifiable information, even if you think you have permission. That type of support requires payment and a contract where I'm indemnified, held harmless, and defended for any data you send to me.
+
+Please don't send CBOR data larger than 1024 bytes by email. If you want to send crash-producing CBOR data > 1024 bytes by email, please get my permission before sending it to me.
+
+## Credits
+
+- This guide used nlohmann/json contribution guidelines for inspiration as suggested in issue #22.
+- Special thanks to @lukseven for pointing out the contribution guidelines didn't mention signing requirements.
diff --git a/vendor/github.com/fxamacker/cbor/v2/LICENSE b/vendor/github.com/fxamacker/cbor/v2/LICENSE
new file mode 100644
index 000000000..eaa850492
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019-present Faye Amacker
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/vendor/github.com/fxamacker/cbor/v2/README.md b/vendor/github.com/fxamacker/cbor/v2/README.md
new file mode 100644
index 000000000..af0a79507
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/README.md
@@ -0,0 +1,691 @@
+# CBOR Codec in Go
+
+
+
+[fxamacker/cbor](https://github.com/fxamacker/cbor) is a library for encoding and decoding [CBOR](https://www.rfc-editor.org/info/std94) and [CBOR Sequences](https://www.rfc-editor.org/rfc/rfc8742.html).
+
+CBOR is a [trusted alternative](https://www.rfc-editor.org/rfc/rfc8949.html#name-comparison-of-other-binary-) to JSON, MessagePack, Protocol Buffers, etc. CBOR is an Internet Standard defined by [IETF STD 94 (RFC 8949)](https://www.rfc-editor.org/info/std94) and is designed to be relevant for decades.
+
+`fxamacker/cbor` is used in projects by Arm Ltd., Cisco, EdgeX Foundry, Flow Foundation, Fraunhofer‑AISEC, Kubernetes, Let's Encrypt (ISRG), Linux Foundation, Microsoft, Mozilla, Oasis Protocol, Tailscale, Teleport, [etc](https://github.com/fxamacker/cbor#who-uses-fxamackercbor).
+
+See [Quick Start](#quick-start) and [Releases](https://github.com/fxamacker/cbor/releases/). 🆕 `UnmarshalFirst` and `DiagnoseFirst` can decode CBOR Sequences. `cbor.MarshalToBuffer()` and `UserBufferEncMode` accepts user-specified buffer.
+
+## fxamacker/cbor
+
+[![](https://github.com/fxamacker/cbor/workflows/ci/badge.svg)](https://github.com/fxamacker/cbor/actions?query=workflow%3Aci)
+[![](https://github.com/fxamacker/cbor/workflows/cover%20%E2%89%A596%25/badge.svg)](https://github.com/fxamacker/cbor/actions?query=workflow%3A%22cover+%E2%89%A596%25%22)
+[![CodeQL](https://github.com/fxamacker/cbor/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/fxamacker/cbor/actions/workflows/codeql-analysis.yml)
+[![](https://img.shields.io/badge/fuzzing-passing-44c010)](#fuzzing-and-code-coverage)
+[![Go Report Card](https://goreportcard.com/badge/github.com/fxamacker/cbor)](https://goreportcard.com/report/github.com/fxamacker/cbor)
+
+`fxamacker/cbor` is a CBOR codec in full conformance with [IETF STD 94 (RFC 8949)](https://www.rfc-editor.org/info/std94). It also supports CBOR Sequences ([RFC 8742](https://www.rfc-editor.org/rfc/rfc8742.html)) and Extended Diagnostic Notation ([Appendix G of RFC 8610](https://www.rfc-editor.org/rfc/rfc8610.html#appendix-G)).
+
+Features include full support for CBOR tags, [Core Deterministic Encoding](https://www.rfc-editor.org/rfc/rfc8949.html#name-core-deterministic-encoding), duplicate map key detection, etc.
+
+Design balances trade-offs between security, speed, concurrency, encoded data size, usability, etc.
+
+Highlights
+
+__🚀 Speed__
+
+Encoding and decoding is fast without using Go's `unsafe` package. Slower settings are opt-in. Default limits allow very fast and memory efficient rejection of malformed CBOR data.
+
+__🔒 Security__
+
+Decoder has configurable limits that defend against malicious inputs. Duplicate map key detection is supported. By contrast, `encoding/gob` is [not designed to be hardened against adversarial inputs](https://pkg.go.dev/encoding/gob#hdr-Security).
+
+Codec passed multiple confidential security assessments in 2022. No vulnerabilities found in subset of codec in a [nonconfidential security assessment](https://github.com/veraison/go-cose/blob/v1.0.0-rc.1/reports/NCC_Microsoft-go-cose-Report_2022-05-26_v1.0.pdf) prepared by NCC Group for Microsoft Corporation.
+
+__🗜️ Data Size__
+
+Struct tags (`toarray`, `keyasint`, `omitempty`) automatically reduce size of encoded structs. Encoding optionally shrinks float64→32→16 when values fit.
+
+__:jigsaw: Usability__
+
+API is mostly same as `encoding/json` plus interfaces that simplify concurrency for CBOR options. Encoding and decoding modes can be created at startup and reused by any goroutines.
+
+Presets include Core Deterministic Encoding, Preferred Serialization, CTAP2 Canonical CBOR, etc.
+
+__📆 Extensibility__
+
+Features include CBOR [extension points](https://www.rfc-editor.org/rfc/rfc8949.html#section-7.1) (e.g. CBOR tags) and extensive settings. API has interfaces that allow users to create custom encoding and decoding without modifying this library.
+
+
+
+
+
+### Secure Decoding with Configurable Settings
+
+`fxamacker/cbor` has configurable limits, etc. that defend against malicious CBOR data.
+
+By contrast, `encoding/gob` is [not designed to be hardened against adversarial inputs](https://pkg.go.dev/encoding/gob#hdr-Security).
+
+Example decoding with encoding/gob 💥 fatal error (out of memory)
+
+```Go
+// Example of encoding/gob having "fatal error: runtime: out of memory"
+// while decoding 181 bytes.
+package main
+import (
+ "bytes"
+ "encoding/gob"
+ "encoding/hex"
+ "fmt"
+)
+
+// Example data is from https://github.com/golang/go/issues/24446
+// (shortened to 181 bytes).
+const data = "4dffb503010102303001ff30000109010130010800010130010800010130" +
+ "01ffb80001014a01ffb60001014b01ff860001013001ff860001013001ff" +
+ "860001013001ff860001013001ffb80000001eff850401010e3030303030" +
+ "30303030303030303001ff3000010c0104000016ffb70201010830303030" +
+ "3030303001ff3000010c000030ffb6040405fcff00303030303030303030" +
+ "303030303030303030303030303030303030303030303030303030303030" +
+ "30"
+
+type X struct {
+ J *X
+ K map[string]int
+}
+
+func main() {
+ raw, _ := hex.DecodeString(data)
+ decoder := gob.NewDecoder(bytes.NewReader(raw))
+
+ var x X
+ decoder.Decode(&x) // fatal error: runtime: out of memory
+ fmt.Println("Decoding finished.")
+}
+```
+
+
+
+
+
+`fxamacker/cbor` is fast at rejecting malformed CBOR data. E.g. attempts to
+decode 10 bytes of malicious CBOR data to `[]byte` (with default settings):
+
+| Codec | Speed (ns/op) | Memory | Allocs |
+| :---- | ------------: | -----: | -----: |
+| fxamacker/cbor 2.5.0 | 44 ± 5% | 32 B/op | 2 allocs/op |
+| ugorji/go 1.2.11 | 5353261 ± 4% | 67111321 B/op | 13 allocs/op |
+
+Benchmark details
+
+Latest comparison used:
+- Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}`
+- go1.19.10, linux/amd64, i5-13600K (disabled all e-cores, DDR4 @2933)
+- go test -bench=. -benchmem -count=20
+
+#### Prior comparisons
+
+| Codec | Speed (ns/op) | Memory | Allocs |
+| :---- | ------------: | -----: | -----: |
+| fxamacker/cbor 2.5.0-beta2 | 44.33 ± 2% | 32 B/op | 2 allocs/op |
+| fxamacker/cbor 0.1.0 - 2.4.0 | ~44.68 ± 6% | 32 B/op | 2 allocs/op |
+| ugorji/go 1.2.10 | 5524792.50 ± 3% | 67110491 B/op | 12 allocs/op |
+| ugorji/go 1.1.0 - 1.2.6 | 💥 runtime: | out of memory: | cannot allocate |
+
+- Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}`
+- go1.19.6, linux/amd64, i5-13600K (DDR4)
+- go test -bench=. -benchmem -count=20
+
+
+
+
+
+### Smaller Encodings with Struct Tags
+
+Struct tags (`toarray`, `keyasint`, `omitempty`) reduce encoded size of structs.
+
+Example encoding 3-level nested Go struct to 1 byte CBOR
+
+https://go.dev/play/p/YxwvfPdFQG2
+
+```Go
+// Example encoding nested struct (with omitempty tag)
+// - encoding/json: 18 byte JSON
+// - fxamacker/cbor: 1 byte CBOR
+package main
+
+import (
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+
+ "github.com/fxamacker/cbor/v2"
+)
+
+type GrandChild struct {
+ Quux int `json:",omitempty"`
+}
+
+type Child struct {
+ Baz int `json:",omitempty"`
+ Qux GrandChild `json:",omitempty"`
+}
+
+type Parent struct {
+ Foo Child `json:",omitempty"`
+ Bar int `json:",omitempty"`
+}
+
+func cb() {
+ results, _ := cbor.Marshal(Parent{})
+ fmt.Println("hex(CBOR): " + hex.EncodeToString(results))
+
+ text, _ := cbor.Diagnose(results) // Diagnostic Notation
+ fmt.Println("DN: " + text)
+}
+
+func js() {
+ results, _ := json.Marshal(Parent{})
+ fmt.Println("hex(JSON): " + hex.EncodeToString(results))
+
+ text := string(results) // JSON
+ fmt.Println("JSON: " + text)
+}
+
+func main() {
+ cb()
+ fmt.Println("-------------")
+ js()
+}
+```
+
+Output (DN is Diagnostic Notation):
+```
+hex(CBOR): a0
+DN: {}
+-------------
+hex(JSON): 7b22466f6f223a7b22517578223a7b7d7d7d
+JSON: {"Foo":{"Qux":{}}}
+```
+
+
+
+
+
+Example using different struct tags together:
+
+![alt text](https://github.com/fxamacker/images/raw/master/cbor/v2.3.0/cbor_struct_tags_api.svg?sanitize=1 "CBOR API and Go Struct Tags")
+
+API is mostly same as `encoding/json`, plus interfaces that simplify concurrency for CBOR options.
+
+## Quick Start
+
+__Install__: `go get github.com/fxamacker/cbor/v2` and `import "github.com/fxamacker/cbor/v2"`.
+
+### Key Points
+
+This library can encode and decode CBOR (RFC 8949) and CBOR Sequences (RFC 8742).
+
+- __CBOR data item__ is a single piece of CBOR data and its structure may contain 0 or more nested data items.
+- __CBOR sequence__ is a concatenation of 0 or more encoded CBOR data items.
+
+Configurable limits and options can be used to balance trade-offs.
+
+- Encoding and decoding modes are created from options (settings).
+- Modes can be created at startup and reused.
+- Modes are safe for concurrent use.
+
+### Default Mode
+
+Package level functions only use this library's default settings.
+They provide the "default mode" of encoding and decoding.
+
+```go
+// API matches encoding/json for Marshal, Unmarshal, Encode, Decode, etc.
+b, err = cbor.Marshal(v) // encode v to []byte b
+err = cbor.Unmarshal(b, &v) // decode []byte b to v
+decoder = cbor.NewDecoder(r) // create decoder with io.Reader r
+err = decoder.Decode(&v) // decode a CBOR data item to v
+
+// v2.7.0 added MarshalToBuffer() and UserBufferEncMode interface.
+err = cbor.MarshalToBuffer(v, b) // encode v to b instead of using built-in buf pool.
+
+// v2.5.0 added new functions that return remaining bytes.
+
+// UnmarshalFirst decodes first CBOR data item and returns remaining bytes.
+rest, err = cbor.UnmarshalFirst(b, &v) // decode []byte b to v
+
+// DiagnoseFirst translates first CBOR data item to text and returns remaining bytes.
+text, rest, err = cbor.DiagnoseFirst(b) // decode []byte b to Diagnostic Notation text
+
+// NOTE: Unmarshal returns ExtraneousDataError if there are remaining bytes,
+// but new funcs UnmarshalFirst and DiagnoseFirst do not.
+```
+
+__IMPORTANT__: 👉 CBOR settings allow trade-offs between speed, security, encoding size, etc.
+
+- Different CBOR libraries may use different default settings.
+- CBOR-based formats or protocols usually require specific settings.
+
+For example, WebAuthn uses "CTAP2 Canonical CBOR" which is available as a preset.
+
+### Presets
+
+Presets can be used as-is or as a starting point for custom settings.
+
+```go
+// EncOptions is a struct of encoder settings.
+func CoreDetEncOptions() EncOptions // RFC 8949 Core Deterministic Encoding
+func PreferredUnsortedEncOptions() EncOptions // RFC 8949 Preferred Serialization
+func CanonicalEncOptions() EncOptions // RFC 7049 Canonical CBOR
+func CTAP2EncOptions() EncOptions // FIDO2 CTAP2 Canonical CBOR
+```
+
+Presets are used to create custom modes.
+
+### Custom Modes
+
+Modes are created from settings. Once created, modes have immutable settings.
+
+💡 Create the mode at startup and reuse it. It is safe for concurrent use.
+
+```Go
+// Create encoding mode.
+opts := cbor.CoreDetEncOptions() // use preset options as a starting point
+opts.Time = cbor.TimeUnix // change any settings if needed
+em, err := opts.EncMode() // create an immutable encoding mode
+
+// Reuse the encoding mode. It is safe for concurrent use.
+
+// API matches encoding/json.
+b, err := em.Marshal(v) // encode v to []byte b
+encoder := em.NewEncoder(w) // create encoder with io.Writer w
+err := encoder.Encode(v) // encode v to io.Writer w
+```
+
+Default mode and custom modes automatically apply struct tags.
+
+### User Specified Buffer for Encoding (v2.7.0)
+
+`UserBufferEncMode` interface extends `EncMode` interface to add `MarshalToBuffer()`. It accepts a user-specified buffer instead of using built-in buffer pool.
+
+```Go
+em, err := myEncOptions.UserBufferEncMode() // create UserBufferEncMode mode
+
+var buf bytes.Buffer
+err = em.MarshalToBuffer(v, &buf) // encode v to provided buf
+```
+
+### Struct Tags
+
+Struct tags (`toarray`, `keyasint`, `omitempty`) reduce encoded size of structs.
+
+Example encoding 3-level nested Go struct to 1 byte CBOR
+
+https://go.dev/play/p/YxwvfPdFQG2
+
+```Go
+// Example encoding nested struct (with omitempty tag)
+// - encoding/json: 18 byte JSON
+// - fxamacker/cbor: 1 byte CBOR
+package main
+
+import (
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+
+ "github.com/fxamacker/cbor/v2"
+)
+
+type GrandChild struct {
+ Quux int `json:",omitempty"`
+}
+
+type Child struct {
+ Baz int `json:",omitempty"`
+ Qux GrandChild `json:",omitempty"`
+}
+
+type Parent struct {
+ Foo Child `json:",omitempty"`
+ Bar int `json:",omitempty"`
+}
+
+func cb() {
+ results, _ := cbor.Marshal(Parent{})
+ fmt.Println("hex(CBOR): " + hex.EncodeToString(results))
+
+ text, _ := cbor.Diagnose(results) // Diagnostic Notation
+ fmt.Println("DN: " + text)
+}
+
+func js() {
+ results, _ := json.Marshal(Parent{})
+ fmt.Println("hex(JSON): " + hex.EncodeToString(results))
+
+ text := string(results) // JSON
+ fmt.Println("JSON: " + text)
+}
+
+func main() {
+ cb()
+ fmt.Println("-------------")
+ js()
+}
+```
+
+Output (DN is Diagnostic Notation):
+```
+hex(CBOR): a0
+DN: {}
+-------------
+hex(JSON): 7b22466f6f223a7b22517578223a7b7d7d7d
+JSON: {"Foo":{"Qux":{}}}
+```
+
+
+
+
+
+Example using several struct tags
+
+![alt text](https://github.com/fxamacker/images/raw/master/cbor/v2.3.0/cbor_struct_tags_api.svg?sanitize=1 "CBOR API and Go Struct Tags")
+
+
+
+Struct tags simplify use of CBOR-based protocols that require CBOR arrays or maps with integer keys.
+
+### CBOR Tags
+
+CBOR tags are specified in a `TagSet`.
+
+Custom modes can be created with a `TagSet` to handle CBOR tags.
+
+```go
+em, err := opts.EncMode() // no CBOR tags
+em, err := opts.EncModeWithTags(ts) // immutable CBOR tags
+em, err := opts.EncModeWithSharedTags(ts) // mutable shared CBOR tags
+```
+
+`TagSet` and modes using it are safe for concurrent use. Equivalent API is available for `DecMode`.
+
+Example using TagSet and TagOptions
+
+```go
+// Use signedCWT struct defined in "Decoding CWT" example.
+
+// Create TagSet (safe for concurrency).
+tags := cbor.NewTagSet()
+// Register tag COSE_Sign1 18 with signedCWT type.
+tags.Add(
+ cbor.TagOptions{EncTag: cbor.EncTagRequired, DecTag: cbor.DecTagRequired},
+ reflect.TypeOf(signedCWT{}),
+ 18)
+
+// Create DecMode with immutable tags.
+dm, _ := cbor.DecOptions{}.DecModeWithTags(tags)
+
+// Unmarshal to signedCWT with tag support.
+var v signedCWT
+if err := dm.Unmarshal(data, &v); err != nil {
+ return err
+}
+
+// Create EncMode with immutable tags.
+em, _ := cbor.EncOptions{}.EncModeWithTags(tags)
+
+// Marshal signedCWT with tag number.
+if data, err := cbor.Marshal(v); err != nil {
+ return err
+}
+```
+
+
+
+### Functions and Interfaces
+
+Functions and interfaces at a glance
+
+Common functions with same API as `encoding/json`:
+- `Marshal`, `Unmarshal`
+- `NewEncoder`, `(*Encoder).Encode`
+- `NewDecoder`, `(*Decoder).Decode`
+
+NOTE: `Unmarshal` will return `ExtraneousDataError` if there are remaining bytes
+because RFC 8949 treats CBOR data item with remaining bytes as malformed.
+- 💡 Use `UnmarshalFirst` to decode first CBOR data item and return any remaining bytes.
+
+Other useful functions:
+- `Diagnose`, `DiagnoseFirst` produce human-readable [Extended Diagnostic Notation](https://www.rfc-editor.org/rfc/rfc8610.html#appendix-G) from CBOR data.
+- `UnmarshalFirst` decodes first CBOR data item and return any remaining bytes.
+- `Wellformed` returns true if the the CBOR data item is well-formed.
+
+Interfaces identical or comparable to Go `encoding` packages include:
+`Marshaler`, `Unmarshaler`, `BinaryMarshaler`, and `BinaryUnmarshaler`.
+
+The `RawMessage` type can be used to delay CBOR decoding or precompute CBOR encoding.
+
+
+
+### Security Tips
+
+🔒 Use Go's `io.LimitReader` to limit size when decoding very large or indefinite size data.
+
+Default limits may need to be increased for systems handling very large data (e.g. blockchains).
+
+`DecOptions` can be used to modify default limits for `MaxArrayElements`, `MaxMapPairs`, and `MaxNestedLevels`.
+
+## Status
+
+v2.7.0 (June 23, 2024) adds features and improvements that help large projects (e.g. Kubernetes) use CBOR as an alternative to JSON and Protocol Buffers. Other improvements include speedups, improved memory use, bug fixes, new serialization options, etc. It passed fuzz tests (5+ billion executions) and is production quality.
+
+For more details, see [release notes](https://github.com/fxamacker/cbor/releases).
+
+### Prior Release
+
+[v2.6.0](https://github.com/fxamacker/cbor/releases/tag/v2.6.0) (February 2024) adds important new features, optimizations, and bug fixes. It is especially useful to systems that need to convert data between CBOR and JSON. New options and optimizations improve handling of bignum, integers, maps, and strings.
+
+v2.5.0 was released on Sunday, August 13, 2023 with new features and important bug fixes. It is fuzz tested and production quality after extended beta [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023).
+
+__IMPORTANT__: 👉 Before upgrading from v2.4 or older release, please read the notable changes highlighted in the release notes. v2.5.0 is a large release with bug fixes to error handling for extraneous data in `Unmarshal`, etc. that should be reviewed before upgrading.
+
+See [v2.5.0 release notes](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) for list of new features, improvements, and bug fixes.
+
+See ["Version and API Changes"](https://github.com/fxamacker/cbor#versions-and-api-changes) section for more info about version numbering, etc.
+
+
+
+## Who uses fxamacker/cbor
+
+`fxamacker/cbor` is used in projects by Arm Ltd., Berlin Institute of Health at Charité, Chainlink, Cisco, Confidential Computing Consortium, ConsenSys, Dapper Labs, EdgeX Foundry, F5, FIDO Alliance, Fraunhofer‑AISEC, Kubernetes, Let's Encrypt (ISRG), Linux Foundation, Matrix.org, Microsoft, Mozilla, National Cybersecurity Agency of France (govt), Netherlands (govt), Oasis Protocol, Smallstep, Tailscale, Taurus SA, Teleport, TIBCO, and others.
+
+`fxamacker/cbor` passed multiple confidential security assessments. A [nonconfidential security assessment](https://github.com/veraison/go-cose/blob/v1.0.0-rc.1/reports/NCC_Microsoft-go-cose-Report_2022-05-26_v1.0.pdf) (prepared by NCC Group for Microsoft Corporation) includes a subset of fxamacker/cbor v2.4.0 in its scope.
+
+## Standards
+
+`fxamacker/cbor` is a CBOR codec in full conformance with [IETF STD 94 (RFC 8949)](https://www.rfc-editor.org/info/std94). It also supports CBOR Sequences ([RFC 8742](https://www.rfc-editor.org/rfc/rfc8742.html)) and Extended Diagnostic Notation ([Appendix G of RFC 8610](https://www.rfc-editor.org/rfc/rfc8610.html#appendix-G)).
+
+Notable CBOR features include:
+
+| CBOR Feature | Description |
+| :--- | :--- |
+| CBOR tags | API supports built-in and user-defined tags. |
+| Preferred serialization | Integers encode to fewest bytes. Optional float64 → float32 → float16. |
+| Map key sorting | Unsorted, length-first (Canonical CBOR), and bytewise-lexicographic (CTAP2). |
+| Duplicate map keys | Always forbid for encoding and option to allow/forbid for decoding. |
+| Indefinite length data | Option to allow/forbid for encoding and decoding. |
+| Well-formedness | Always checked and enforced. |
+| Basic validity checks | Optionally check UTF-8 validity and duplicate map keys. |
+| Security considerations | Prevent integer overflow and resource exhaustion (RFC 8949 Section 10). |
+
+Known limitations are noted in the [Limitations section](#limitations).
+
+Go nil values for slices, maps, pointers, etc. are encoded as CBOR null. Empty slices, maps, etc. are encoded as empty CBOR arrays and maps.
+
+Decoder checks for all required well-formedness errors, including all "subkinds" of syntax errors and too little data.
+
+After well-formedness is verified, basic validity errors are handled as follows:
+
+* Invalid UTF-8 string: Decoder has option to check and return invalid UTF-8 string error. This check is enabled by default.
+* Duplicate keys in a map: Decoder has options to ignore or enforce rejection of duplicate map keys.
+
+When decoding well-formed CBOR arrays and maps, decoder saves the first error it encounters and continues with the next item. Options to handle this differently may be added in the future.
+
+By default, decoder treats time values of floating-point NaN and Infinity as if they are CBOR Null or CBOR Undefined.
+
+__Click to expand topic:__
+
+
+ Duplicate Map Keys
+
+This library provides options for fast detection and rejection of duplicate map keys based on applying a Go-specific data model to CBOR's extended generic data model in order to determine duplicate vs distinct map keys. Detection relies on whether the CBOR map key would be a duplicate "key" when decoded and applied to the user-provided Go map or struct.
+
+`DupMapKeyQuiet` turns off detection of duplicate map keys. It tries to use a "keep fastest" method by choosing either "keep first" or "keep last" depending on the Go data type.
+
+`DupMapKeyEnforcedAPF` enforces detection and rejection of duplidate map keys. Decoding stops immediately and returns `DupMapKeyError` when the first duplicate key is detected. The error includes the duplicate map key and the index number.
+
+APF suffix means "Allow Partial Fill" so the destination map or struct can contain some decoded values at the time of error. It is the caller's responsibility to respond to the `DupMapKeyError` by discarding the partially filled result if that's required by their protocol.
+
+
+
+
+ Tag Validity
+
+This library checks tag validity for built-in tags (currently tag numbers 0, 1, 2, 3, and 55799):
+
+* Inadmissible type for tag content
+* Inadmissible value for tag content
+
+Unknown tag data items (not tag number 0, 1, 2, 3, or 55799) are handled in two ways:
+
+* When decoding into an empty interface, unknown tag data item will be decoded into `cbor.Tag` data type, which contains tag number and tag content. The tag content will be decoded into the default Go data type for the CBOR data type.
+* When decoding into other Go types, unknown tag data item is decoded into the specified Go type. If Go type is registered with a tag number, the tag number can optionally be verified.
+
+Decoder also has an option to forbid tag data items (treat any tag data item as error) which is specified by protocols such as CTAP2 Canonical CBOR.
+
+For more information, see [decoding options](#decoding-options-1) and [tag options](#tag-options).
+
+
+
+## Limitations
+
+If any of these limitations prevent you from using this library, please open an issue along with a link to your project.
+
+* CBOR `Undefined` (0xf7) value decodes to Go's `nil` value. CBOR `Null` (0xf6) more closely matches Go's `nil`.
+* CBOR map keys with data types not supported by Go for map keys are ignored and an error is returned after continuing to decode remaining items.
+* When decoding registered CBOR tag data to interface type, decoder creates a pointer to registered Go type matching CBOR tag number. Requiring a pointer for this is a Go limitation.
+
+## Fuzzing and Code Coverage
+
+__Code coverage__ is always 95% or higher (with `go test -cover`) when tagging a release.
+
+__Coverage-guided fuzzing__ must pass billions of execs using before tagging a release. Fuzzing is done using nonpublic code which may eventually get merged into this project. Until then, reports like OpenSSF Scorecard can't detect fuzz tests being used by this project.
+
+
+
+## Versions and API Changes
+This project uses [Semantic Versioning](https://semver.org), so the API is always backwards compatible unless the major version number changes.
+
+These functions have signatures identical to encoding/json and their API will continue to match `encoding/json` even after major new releases:
+`Marshal`, `Unmarshal`, `NewEncoder`, `NewDecoder`, `(*Encoder).Encode`, and `(*Decoder).Decode`.
+
+Exclusions from SemVer:
+- Newly added API documented as "subject to change".
+- Newly added API in the master branch that has never been tagged in non-beta release.
+- If function parameters are unchanged, bug fixes that change behavior (e.g. return error for edge case was missed in prior version). We try to highlight these in the release notes and add extended beta period. E.g. [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023).
+
+This project avoids breaking changes to behavior of encoding and decoding functions unless required to improve conformance with supported RFCs (e.g. RFC 8949, RFC 8742, etc.) Visible changes that don't improve conformance to standards are typically made available as new opt-in settings or new functions.
+
+## Code of Conduct
+
+This project has adopted the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md). Contact [faye.github@gmail.com](mailto:faye.github@gmail.com) with any questions or comments.
+
+## Contributing
+
+Please open an issue before beginning work on a PR. The improvement may have already been considered, etc.
+
+For more info, see [How to Contribute](CONTRIBUTING.md).
+
+## Security Policy
+
+Security fixes are provided for the latest released version of fxamacker/cbor.
+
+For the full text of the Security Policy, see [SECURITY.md](SECURITY.md).
+
+## Acknowledgements
+
+Many thanks to all the contributors on this project!
+
+I'm especially grateful to Bastian Müller and Dieter Shirley for suggesting and collaborating on CBOR stream mode, and much more.
+
+I'm very grateful to Stefan Tatschner, Yawning Angel, Jernej Kos, x448, ZenGround0, and Jakob Borg for their contributions or support in the very early days.
+
+Big thanks to Ben Luddy for his contributions in v2.6.0 and v2.7.0.
+
+This library clearly wouldn't be possible without Carsten Bormann authoring CBOR RFCs.
+
+Special thanks to Laurence Lundblade and Jeffrey Yasskin for their help on IETF mailing list or at [7049bis](https://github.com/cbor-wg/CBORbis).
+
+Huge thanks to The Go Authors for creating a fun and practical programming language with batteries included!
+
+This library uses `x448/float16` which used to be included. As a standalone package, `x448/float16` is useful to other projects as well.
+
+## License
+
+Copyright © 2019-2024 [Faye Amacker](https://github.com/fxamacker).
+
+fxamacker/cbor is licensed under the MIT License. See [LICENSE](LICENSE) for the full license text.
+
+
diff --git a/vendor/github.com/fxamacker/cbor/v2/SECURITY.md b/vendor/github.com/fxamacker/cbor/v2/SECURITY.md
new file mode 100644
index 000000000..9c05146d1
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/SECURITY.md
@@ -0,0 +1,7 @@
+# Security Policy
+
+Security fixes are provided for the latest released version of fxamacker/cbor.
+
+If the security vulnerability is already known to the public, then you can open an issue as a bug report.
+
+To report security vulnerabilities not yet known to the public, please email faye.github@gmail.com and allow time for the problem to be resolved before reporting it to the public.
diff --git a/vendor/github.com/fxamacker/cbor/v2/bytestring.go b/vendor/github.com/fxamacker/cbor/v2/bytestring.go
new file mode 100644
index 000000000..823bff12c
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/bytestring.go
@@ -0,0 +1,63 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+package cbor
+
+import (
+ "errors"
+)
+
+// ByteString represents CBOR byte string (major type 2). ByteString can be used
+// when using a Go []byte is not possible or convenient. For example, Go doesn't
+// allow []byte as map key, so ByteString can be used to support data formats
+// having CBOR map with byte string keys. ByteString can also be used to
+// encode invalid UTF-8 string as CBOR byte string.
+// See DecOption.MapKeyByteStringMode for more details.
+type ByteString string
+
+// Bytes returns bytes representing ByteString.
+func (bs ByteString) Bytes() []byte {
+ return []byte(bs)
+}
+
+// MarshalCBOR encodes ByteString as CBOR byte string (major type 2).
+func (bs ByteString) MarshalCBOR() ([]byte, error) {
+ e := getEncodeBuffer()
+ defer putEncodeBuffer(e)
+
+ // Encode length
+ encodeHead(e, byte(cborTypeByteString), uint64(len(bs)))
+
+ // Encode data
+ buf := make([]byte, e.Len()+len(bs))
+ n := copy(buf, e.Bytes())
+ copy(buf[n:], bs)
+
+ return buf, nil
+}
+
+// UnmarshalCBOR decodes CBOR byte string (major type 2) to ByteString.
+// Decoding CBOR null and CBOR undefined sets ByteString to be empty.
+func (bs *ByteString) UnmarshalCBOR(data []byte) error {
+ if bs == nil {
+ return errors.New("cbor.ByteString: UnmarshalCBOR on nil pointer")
+ }
+
+ // Decoding CBOR null and CBOR undefined to ByteString resets data.
+ // This behavior is similar to decoding CBOR null and CBOR undefined to []byte.
+ if len(data) == 1 && (data[0] == 0xf6 || data[0] == 0xf7) {
+ *bs = ""
+ return nil
+ }
+
+ d := decoder{data: data, dm: defaultDecMode}
+
+ // Check if CBOR data type is byte string
+ if typ := d.nextCBORType(); typ != cborTypeByteString {
+ return &UnmarshalTypeError{CBORType: typ.String(), GoType: typeByteString.String()}
+ }
+
+ b, _ := d.parseByteString()
+ *bs = ByteString(b)
+ return nil
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/cache.go b/vendor/github.com/fxamacker/cbor/v2/cache.go
new file mode 100644
index 000000000..ea0f39e24
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/cache.go
@@ -0,0 +1,363 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+package cbor
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "reflect"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+)
+
+type encodeFuncs struct {
+ ef encodeFunc
+ ief isEmptyFunc
+}
+
+var (
+ decodingStructTypeCache sync.Map // map[reflect.Type]*decodingStructType
+ encodingStructTypeCache sync.Map // map[reflect.Type]*encodingStructType
+ encodeFuncCache sync.Map // map[reflect.Type]encodeFuncs
+ typeInfoCache sync.Map // map[reflect.Type]*typeInfo
+)
+
+type specialType int
+
+const (
+ specialTypeNone specialType = iota
+ specialTypeUnmarshalerIface
+ specialTypeEmptyIface
+ specialTypeIface
+ specialTypeTag
+ specialTypeTime
+)
+
+type typeInfo struct {
+ elemTypeInfo *typeInfo
+ keyTypeInfo *typeInfo
+ typ reflect.Type
+ kind reflect.Kind
+ nonPtrType reflect.Type
+ nonPtrKind reflect.Kind
+ spclType specialType
+}
+
+func newTypeInfo(t reflect.Type) *typeInfo {
+ tInfo := typeInfo{typ: t, kind: t.Kind()}
+
+ for t.Kind() == reflect.Ptr {
+ t = t.Elem()
+ }
+
+ k := t.Kind()
+
+ tInfo.nonPtrType = t
+ tInfo.nonPtrKind = k
+
+ if k == reflect.Interface {
+ if t.NumMethod() == 0 {
+ tInfo.spclType = specialTypeEmptyIface
+ } else {
+ tInfo.spclType = specialTypeIface
+ }
+ } else if t == typeTag {
+ tInfo.spclType = specialTypeTag
+ } else if t == typeTime {
+ tInfo.spclType = specialTypeTime
+ } else if reflect.PtrTo(t).Implements(typeUnmarshaler) {
+ tInfo.spclType = specialTypeUnmarshalerIface
+ }
+
+ switch k {
+ case reflect.Array, reflect.Slice:
+ tInfo.elemTypeInfo = getTypeInfo(t.Elem())
+ case reflect.Map:
+ tInfo.keyTypeInfo = getTypeInfo(t.Key())
+ tInfo.elemTypeInfo = getTypeInfo(t.Elem())
+ }
+
+ return &tInfo
+}
+
+type decodingStructType struct {
+ fields fields
+ fieldIndicesByName map[string]int
+ err error
+ toArray bool
+}
+
+// The stdlib errors.Join was introduced in Go 1.20, and we still support Go 1.17, so instead,
+// here's a very basic implementation of an aggregated error.
+type multierror []error
+
+func (m multierror) Error() string {
+ var sb strings.Builder
+ for i, err := range m {
+ sb.WriteString(err.Error())
+ if i < len(m)-1 {
+ sb.WriteString(", ")
+ }
+ }
+ return sb.String()
+}
+
+func getDecodingStructType(t reflect.Type) *decodingStructType {
+ if v, _ := decodingStructTypeCache.Load(t); v != nil {
+ return v.(*decodingStructType)
+ }
+
+ flds, structOptions := getFields(t)
+
+ toArray := hasToArrayOption(structOptions)
+
+ var errs []error
+ for i := 0; i < len(flds); i++ {
+ if flds[i].keyAsInt {
+ nameAsInt, numErr := strconv.Atoi(flds[i].name)
+ if numErr != nil {
+ errs = append(errs, errors.New("cbor: failed to parse field name \""+flds[i].name+"\" to int ("+numErr.Error()+")"))
+ break
+ }
+ flds[i].nameAsInt = int64(nameAsInt)
+ }
+
+ flds[i].typInfo = getTypeInfo(flds[i].typ)
+ }
+
+ fieldIndicesByName := make(map[string]int, len(flds))
+ for i, fld := range flds {
+ if _, ok := fieldIndicesByName[fld.name]; ok {
+ errs = append(errs, fmt.Errorf("cbor: two or more fields of %v have the same name %q", t, fld.name))
+ continue
+ }
+ fieldIndicesByName[fld.name] = i
+ }
+
+ var err error
+ {
+ var multi multierror
+ for _, each := range errs {
+ if each != nil {
+ multi = append(multi, each)
+ }
+ }
+ if len(multi) == 1 {
+ err = multi[0]
+ } else if len(multi) > 1 {
+ err = multi
+ }
+ }
+
+ structType := &decodingStructType{
+ fields: flds,
+ fieldIndicesByName: fieldIndicesByName,
+ err: err,
+ toArray: toArray,
+ }
+ decodingStructTypeCache.Store(t, structType)
+ return structType
+}
+
+type encodingStructType struct {
+ fields fields
+ bytewiseFields fields
+ lengthFirstFields fields
+ omitEmptyFieldsIdx []int
+ err error
+ toArray bool
+}
+
+func (st *encodingStructType) getFields(em *encMode) fields {
+ switch em.sort {
+ case SortNone, SortFastShuffle:
+ return st.fields
+ case SortLengthFirst:
+ return st.lengthFirstFields
+ default:
+ return st.bytewiseFields
+ }
+}
+
+type bytewiseFieldSorter struct {
+ fields fields
+}
+
+func (x *bytewiseFieldSorter) Len() int {
+ return len(x.fields)
+}
+
+func (x *bytewiseFieldSorter) Swap(i, j int) {
+ x.fields[i], x.fields[j] = x.fields[j], x.fields[i]
+}
+
+func (x *bytewiseFieldSorter) Less(i, j int) bool {
+ return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) <= 0
+}
+
+type lengthFirstFieldSorter struct {
+ fields fields
+}
+
+func (x *lengthFirstFieldSorter) Len() int {
+ return len(x.fields)
+}
+
+func (x *lengthFirstFieldSorter) Swap(i, j int) {
+ x.fields[i], x.fields[j] = x.fields[j], x.fields[i]
+}
+
+func (x *lengthFirstFieldSorter) Less(i, j int) bool {
+ if len(x.fields[i].cborName) != len(x.fields[j].cborName) {
+ return len(x.fields[i].cborName) < len(x.fields[j].cborName)
+ }
+ return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) <= 0
+}
+
+func getEncodingStructType(t reflect.Type) (*encodingStructType, error) {
+ if v, _ := encodingStructTypeCache.Load(t); v != nil {
+ structType := v.(*encodingStructType)
+ return structType, structType.err
+ }
+
+ flds, structOptions := getFields(t)
+
+ if hasToArrayOption(structOptions) {
+ return getEncodingStructToArrayType(t, flds)
+ }
+
+ var err error
+ var hasKeyAsInt bool
+ var hasKeyAsStr bool
+ var omitEmptyIdx []int
+ e := getEncodeBuffer()
+ for i := 0; i < len(flds); i++ {
+ // Get field's encodeFunc
+ flds[i].ef, flds[i].ief = getEncodeFunc(flds[i].typ)
+ if flds[i].ef == nil {
+ err = &UnsupportedTypeError{t}
+ break
+ }
+
+ // Encode field name
+ if flds[i].keyAsInt {
+ nameAsInt, numErr := strconv.Atoi(flds[i].name)
+ if numErr != nil {
+ err = errors.New("cbor: failed to parse field name \"" + flds[i].name + "\" to int (" + numErr.Error() + ")")
+ break
+ }
+ flds[i].nameAsInt = int64(nameAsInt)
+ if nameAsInt >= 0 {
+ encodeHead(e, byte(cborTypePositiveInt), uint64(nameAsInt))
+ } else {
+ n := nameAsInt*(-1) - 1
+ encodeHead(e, byte(cborTypeNegativeInt), uint64(n))
+ }
+ flds[i].cborName = make([]byte, e.Len())
+ copy(flds[i].cborName, e.Bytes())
+ e.Reset()
+
+ hasKeyAsInt = true
+ } else {
+ encodeHead(e, byte(cborTypeTextString), uint64(len(flds[i].name)))
+ flds[i].cborName = make([]byte, e.Len()+len(flds[i].name))
+ n := copy(flds[i].cborName, e.Bytes())
+ copy(flds[i].cborName[n:], flds[i].name)
+ e.Reset()
+
+ // If cborName contains a text string, then cborNameByteString contains a
+ // string that has the byte string major type but is otherwise identical to
+ // cborName.
+ flds[i].cborNameByteString = make([]byte, len(flds[i].cborName))
+ copy(flds[i].cborNameByteString, flds[i].cborName)
+ // Reset encoded CBOR type to byte string, preserving the "additional
+ // information" bits:
+ flds[i].cborNameByteString[0] = byte(cborTypeByteString) |
+ getAdditionalInformation(flds[i].cborNameByteString[0])
+
+ hasKeyAsStr = true
+ }
+
+ // Check if field can be omitted when empty
+ if flds[i].omitEmpty {
+ omitEmptyIdx = append(omitEmptyIdx, i)
+ }
+ }
+ putEncodeBuffer(e)
+
+ if err != nil {
+ structType := &encodingStructType{err: err}
+ encodingStructTypeCache.Store(t, structType)
+ return structType, structType.err
+ }
+
+ // Sort fields by canonical order
+ bytewiseFields := make(fields, len(flds))
+ copy(bytewiseFields, flds)
+ sort.Sort(&bytewiseFieldSorter{bytewiseFields})
+
+ lengthFirstFields := bytewiseFields
+ if hasKeyAsInt && hasKeyAsStr {
+ lengthFirstFields = make(fields, len(flds))
+ copy(lengthFirstFields, flds)
+ sort.Sort(&lengthFirstFieldSorter{lengthFirstFields})
+ }
+
+ structType := &encodingStructType{
+ fields: flds,
+ bytewiseFields: bytewiseFields,
+ lengthFirstFields: lengthFirstFields,
+ omitEmptyFieldsIdx: omitEmptyIdx,
+ }
+
+ encodingStructTypeCache.Store(t, structType)
+ return structType, structType.err
+}
+
+func getEncodingStructToArrayType(t reflect.Type, flds fields) (*encodingStructType, error) {
+ for i := 0; i < len(flds); i++ {
+ // Get field's encodeFunc
+ flds[i].ef, flds[i].ief = getEncodeFunc(flds[i].typ)
+ if flds[i].ef == nil {
+ structType := &encodingStructType{err: &UnsupportedTypeError{t}}
+ encodingStructTypeCache.Store(t, structType)
+ return structType, structType.err
+ }
+ }
+
+ structType := &encodingStructType{
+ fields: flds,
+ toArray: true,
+ }
+ encodingStructTypeCache.Store(t, structType)
+ return structType, structType.err
+}
+
+func getEncodeFunc(t reflect.Type) (encodeFunc, isEmptyFunc) {
+ if v, _ := encodeFuncCache.Load(t); v != nil {
+ fs := v.(encodeFuncs)
+ return fs.ef, fs.ief
+ }
+ ef, ief := getEncodeFuncInternal(t)
+ encodeFuncCache.Store(t, encodeFuncs{ef, ief})
+ return ef, ief
+}
+
+func getTypeInfo(t reflect.Type) *typeInfo {
+ if v, _ := typeInfoCache.Load(t); v != nil {
+ return v.(*typeInfo)
+ }
+ tInfo := newTypeInfo(t)
+ typeInfoCache.Store(t, tInfo)
+ return tInfo
+}
+
+func hasToArrayOption(tag string) bool {
+ s := ",toarray"
+ idx := strings.Index(tag, s)
+ return idx >= 0 && (len(tag) == idx+len(s) || tag[idx+len(s)] == ',')
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/common.go b/vendor/github.com/fxamacker/cbor/v2/common.go
new file mode 100644
index 000000000..ec038a49e
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/common.go
@@ -0,0 +1,182 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+package cbor
+
+import (
+ "fmt"
+ "strconv"
+)
+
+type cborType uint8
+
+const (
+ cborTypePositiveInt cborType = 0x00
+ cborTypeNegativeInt cborType = 0x20
+ cborTypeByteString cborType = 0x40
+ cborTypeTextString cborType = 0x60
+ cborTypeArray cborType = 0x80
+ cborTypeMap cborType = 0xa0
+ cborTypeTag cborType = 0xc0
+ cborTypePrimitives cborType = 0xe0
+)
+
+func (t cborType) String() string {
+ switch t {
+ case cborTypePositiveInt:
+ return "positive integer"
+ case cborTypeNegativeInt:
+ return "negative integer"
+ case cborTypeByteString:
+ return "byte string"
+ case cborTypeTextString:
+ return "UTF-8 text string"
+ case cborTypeArray:
+ return "array"
+ case cborTypeMap:
+ return "map"
+ case cborTypeTag:
+ return "tag"
+ case cborTypePrimitives:
+ return "primitives"
+ default:
+ return "Invalid type " + strconv.Itoa(int(t))
+ }
+}
+
+type additionalInformation uint8
+
+const (
+ maxAdditionalInformationWithoutArgument = 23
+ additionalInformationWith1ByteArgument = 24
+ additionalInformationWith2ByteArgument = 25
+ additionalInformationWith4ByteArgument = 26
+ additionalInformationWith8ByteArgument = 27
+
+ // For major type 7.
+ additionalInformationAsFalse = 20
+ additionalInformationAsTrue = 21
+ additionalInformationAsNull = 22
+ additionalInformationAsUndefined = 23
+ additionalInformationAsFloat16 = 25
+ additionalInformationAsFloat32 = 26
+ additionalInformationAsFloat64 = 27
+
+ // For major type 2, 3, 4, 5.
+ additionalInformationAsIndefiniteLengthFlag = 31
+)
+
+const (
+ maxSimpleValueInAdditionalInformation = 23
+ minSimpleValueIn1ByteArgument = 32
+)
+
+func (ai additionalInformation) isIndefiniteLength() bool {
+ return ai == additionalInformationAsIndefiniteLengthFlag
+}
+
+const (
+ // From RFC 8949 Section 3:
+ // "The initial byte of each encoded data item contains both information about the major type
+ // (the high-order 3 bits, described in Section 3.1) and additional information
+ // (the low-order 5 bits)."
+
+ // typeMask is used to extract major type in initial byte of encoded data item.
+ typeMask = 0xe0
+
+ // additionalInformationMask is used to extract additional information in initial byte of encoded data item.
+ additionalInformationMask = 0x1f
+)
+
+func getType(raw byte) cborType {
+ return cborType(raw & typeMask)
+}
+
+func getAdditionalInformation(raw byte) byte {
+ return raw & additionalInformationMask
+}
+
+func isBreakFlag(raw byte) bool {
+ return raw == cborBreakFlag
+}
+
+func parseInitialByte(b byte) (t cborType, ai byte) {
+ return getType(b), getAdditionalInformation(b)
+}
+
+const (
+ tagNumRFC3339Time = 0
+ tagNumEpochTime = 1
+ tagNumUnsignedBignum = 2
+ tagNumNegativeBignum = 3
+ tagNumExpectedLaterEncodingBase64URL = 21
+ tagNumExpectedLaterEncodingBase64 = 22
+ tagNumExpectedLaterEncodingBase16 = 23
+ tagNumSelfDescribedCBOR = 55799
+)
+
+const (
+ cborBreakFlag = byte(0xff)
+ cborByteStringWithIndefiniteLengthHead = byte(0x5f)
+ cborTextStringWithIndefiniteLengthHead = byte(0x7f)
+ cborArrayWithIndefiniteLengthHead = byte(0x9f)
+ cborMapWithIndefiniteLengthHead = byte(0xbf)
+)
+
+var (
+ cborFalse = []byte{0xf4}
+ cborTrue = []byte{0xf5}
+ cborNil = []byte{0xf6}
+ cborNaN = []byte{0xf9, 0x7e, 0x00}
+ cborPositiveInfinity = []byte{0xf9, 0x7c, 0x00}
+ cborNegativeInfinity = []byte{0xf9, 0xfc, 0x00}
+)
+
+// validBuiltinTag checks that supported built-in tag numbers are followed by expected content types.
+func validBuiltinTag(tagNum uint64, contentHead byte) error {
+ t := getType(contentHead)
+ switch tagNum {
+ case tagNumRFC3339Time:
+ // Tag content (date/time text string in RFC 3339 format) must be string type.
+ if t != cborTypeTextString {
+ return newInadmissibleTagContentTypeError(
+ tagNumRFC3339Time,
+ "text string",
+ t.String())
+ }
+ return nil
+
+ case tagNumEpochTime:
+ // Tag content (epoch date/time) must be uint, int, or float type.
+ if t != cborTypePositiveInt && t != cborTypeNegativeInt && (contentHead < 0xf9 || contentHead > 0xfb) {
+ return newInadmissibleTagContentTypeError(
+ tagNumEpochTime,
+ "integer or floating-point number",
+ t.String())
+ }
+ return nil
+
+ case tagNumUnsignedBignum, tagNumNegativeBignum:
+ // Tag content (bignum) must be byte type.
+ if t != cborTypeByteString {
+ return newInadmissibleTagContentTypeErrorf(
+ fmt.Sprintf(
+ "tag number %d or %d must be followed by byte string, got %s",
+ tagNumUnsignedBignum,
+ tagNumNegativeBignum,
+ t.String(),
+ ))
+ }
+ return nil
+
+ case tagNumExpectedLaterEncodingBase64URL, tagNumExpectedLaterEncodingBase64, tagNumExpectedLaterEncodingBase16:
+ // From RFC 8949 3.4.5.2:
+ // The data item tagged can be a byte string or any other data item. In the latter
+ // case, the tag applies to all of the byte string data items contained in the data
+ // item, except for those contained in a nested data item tagged with an expected
+ // conversion.
+ return nil
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/decode.go b/vendor/github.com/fxamacker/cbor/v2/decode.go
new file mode 100644
index 000000000..85842ac73
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/decode.go
@@ -0,0 +1,3187 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+package cbor
+
+import (
+ "encoding"
+ "encoding/base64"
+ "encoding/binary"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "math/big"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf8"
+
+ "github.com/x448/float16"
+)
+
+// Unmarshal parses the CBOR-encoded data into the value pointed to by v
+// using default decoding options. If v is nil, not a pointer, or
+// a nil pointer, Unmarshal returns an error.
+//
+// To unmarshal CBOR into a value implementing the Unmarshaler interface,
+// Unmarshal calls that value's UnmarshalCBOR method with a valid
+// CBOR value.
+//
+// To unmarshal CBOR byte string into a value implementing the
+// encoding.BinaryUnmarshaler interface, Unmarshal calls that value's
+// UnmarshalBinary method with decoded CBOR byte string.
+//
+// To unmarshal CBOR into a pointer, Unmarshal sets the pointer to nil
+// if CBOR data is null (0xf6) or undefined (0xf7). Otherwise, Unmarshal
+// unmarshals CBOR into the value pointed to by the pointer. If the
+// pointer is nil, Unmarshal creates a new value for it to point to.
+//
+// To unmarshal CBOR into an empty interface value, Unmarshal uses the
+// following rules:
+//
+// CBOR booleans decode to bool.
+// CBOR positive integers decode to uint64.
+// CBOR negative integers decode to int64 (big.Int if value overflows).
+// CBOR floating points decode to float64.
+// CBOR byte strings decode to []byte.
+// CBOR text strings decode to string.
+// CBOR arrays decode to []interface{}.
+// CBOR maps decode to map[interface{}]interface{}.
+// CBOR null and undefined values decode to nil.
+// CBOR times (tag 0 and 1) decode to time.Time.
+// CBOR bignums (tag 2 and 3) decode to big.Int.
+// CBOR tags with an unrecognized number decode to cbor.Tag
+//
+// To unmarshal a CBOR array into a slice, Unmarshal allocates a new slice
+// if the CBOR array is empty or slice capacity is less than CBOR array length.
+// Otherwise Unmarshal overwrites existing elements, and sets slice length
+// to CBOR array length.
+//
+// To unmarshal a CBOR array into a Go array, Unmarshal decodes CBOR array
+// elements into Go array elements. If the Go array is smaller than the
+// CBOR array, the extra CBOR array elements are discarded. If the CBOR
+// array is smaller than the Go array, the extra Go array elements are
+// set to zero values.
+//
+// To unmarshal a CBOR array into a struct, struct must have a special field "_"
+// with struct tag `cbor:",toarray"`. Go array elements are decoded into struct
+// fields. Any "omitempty" struct field tag option is ignored in this case.
+//
+// To unmarshal a CBOR map into a map, Unmarshal allocates a new map only if the
+// map is nil. Otherwise Unmarshal reuses the existing map and keeps existing
+// entries. Unmarshal stores key-value pairs from the CBOR map into Go map.
+// See DecOptions.DupMapKey to enable duplicate map key detection.
+//
+// To unmarshal a CBOR map into a struct, Unmarshal matches CBOR map keys to the
+// keys in the following priority:
+//
+// 1. "cbor" key in struct field tag,
+// 2. "json" key in struct field tag,
+// 3. struct field name.
+//
+// Unmarshal tries an exact match for field name, then a case-insensitive match.
+// Map key-value pairs without corresponding struct fields are ignored. See
+// DecOptions.ExtraReturnErrors to return error at unknown field.
+//
+// To unmarshal a CBOR text string into a time.Time value, Unmarshal parses text
+// string formatted in RFC3339. To unmarshal a CBOR integer/float into a
+// time.Time value, Unmarshal creates an unix time with integer/float as seconds
+// and fractional seconds since January 1, 1970 UTC. As a special case, Infinite
+// and NaN float values decode to time.Time's zero value.
+//
+// To unmarshal CBOR null (0xf6) and undefined (0xf7) values into a
+// slice/map/pointer, Unmarshal sets Go value to nil. Because null is often
+// used to mean "not present", unmarshalling CBOR null and undefined value
+// into any other Go type has no effect and returns no error.
+//
+// Unmarshal supports CBOR tag 55799 (self-describe CBOR), tag 0 and 1 (time),
+// and tag 2 and 3 (bignum).
+//
+// Unmarshal returns ExtraneousDataError error (without decoding into v)
+// if there are any remaining bytes following the first valid CBOR data item.
+// See UnmarshalFirst, if you want to unmarshal only the first
+// CBOR data item without ExtraneousDataError caused by remaining bytes.
+func Unmarshal(data []byte, v interface{}) error {
+ return defaultDecMode.Unmarshal(data, v)
+}
+
+// UnmarshalFirst parses the first CBOR data item into the value pointed to by v
+// using default decoding options. Any remaining bytes are returned in rest.
+//
+// If v is nil, not a pointer, or a nil pointer, UnmarshalFirst returns an error.
+//
+// See the documentation for Unmarshal for details.
+func UnmarshalFirst(data []byte, v interface{}) (rest []byte, err error) {
+ return defaultDecMode.UnmarshalFirst(data, v)
+}
+
+// Valid checks whether data is a well-formed encoded CBOR data item and
+// that it complies with default restrictions such as MaxNestedLevels,
+// MaxArrayElements, MaxMapPairs, etc.
+//
+// If there are any remaining bytes after the CBOR data item,
+// an ExtraneousDataError is returned.
+//
+// WARNING: Valid doesn't check if encoded CBOR data item is valid (i.e. validity)
+// and RFC 8949 distinctly defines what is "Valid" and what is "Well-formed".
+//
+// Deprecated: Valid is kept for compatibility and should not be used.
+// Use Wellformed instead because it has a more appropriate name.
+func Valid(data []byte) error {
+ return defaultDecMode.Valid(data)
+}
+
+// Wellformed checks whether data is a well-formed encoded CBOR data item and
+// that it complies with default restrictions such as MaxNestedLevels,
+// MaxArrayElements, MaxMapPairs, etc.
+//
+// If there are any remaining bytes after the CBOR data item,
+// an ExtraneousDataError is returned.
+func Wellformed(data []byte) error {
+ return defaultDecMode.Wellformed(data)
+}
+
+// Unmarshaler is the interface implemented by types that wish to unmarshal
+// CBOR data themselves. The input is a valid CBOR value. UnmarshalCBOR
+// must copy the CBOR data if it needs to use it after returning.
+type Unmarshaler interface {
+ UnmarshalCBOR([]byte) error
+}
+
+// InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
+type InvalidUnmarshalError struct {
+ s string
+}
+
+func (e *InvalidUnmarshalError) Error() string {
+ return e.s
+}
+
+// UnmarshalTypeError describes a CBOR value that can't be decoded to a Go type.
+type UnmarshalTypeError struct {
+ CBORType string // type of CBOR value
+ GoType string // type of Go value it could not be decoded into
+ StructFieldName string // name of the struct field holding the Go value (optional)
+ errorMsg string // additional error message (optional)
+}
+
+func (e *UnmarshalTypeError) Error() string {
+ var s string
+ if e.StructFieldName != "" {
+ s = "cbor: cannot unmarshal " + e.CBORType + " into Go struct field " + e.StructFieldName + " of type " + e.GoType
+ } else {
+ s = "cbor: cannot unmarshal " + e.CBORType + " into Go value of type " + e.GoType
+ }
+ if e.errorMsg != "" {
+ s += " (" + e.errorMsg + ")"
+ }
+ return s
+}
+
+// InvalidMapKeyTypeError describes invalid Go map key type when decoding CBOR map.
+// For example, Go doesn't allow slice as map key.
+type InvalidMapKeyTypeError struct {
+ GoType string
+}
+
+func (e *InvalidMapKeyTypeError) Error() string {
+ return "cbor: invalid map key type: " + e.GoType
+}
+
+// DupMapKeyError describes detected duplicate map key in CBOR map.
+type DupMapKeyError struct {
+ Key interface{}
+ Index int
+}
+
+func (e *DupMapKeyError) Error() string {
+ return fmt.Sprintf("cbor: found duplicate map key \"%v\" at map element index %d", e.Key, e.Index)
+}
+
+// UnknownFieldError describes detected unknown field in CBOR map when decoding to Go struct.
+type UnknownFieldError struct {
+ Index int
+}
+
+func (e *UnknownFieldError) Error() string {
+ return fmt.Sprintf("cbor: found unknown field at map element index %d", e.Index)
+}
+
+// UnacceptableDataItemError is returned when unmarshaling a CBOR input that contains a data item
+// that is not acceptable to a specific CBOR-based application protocol ("invalid or unexpected" as
+// described in RFC 8949 Section 5 Paragraph 3).
+type UnacceptableDataItemError struct {
+ CBORType string
+ Message string
+}
+
+func (e UnacceptableDataItemError) Error() string {
+ return fmt.Sprintf("cbor: data item of cbor type %s is not accepted by protocol: %s", e.CBORType, e.Message)
+}
+
+// ByteStringExpectedFormatError is returned when unmarshaling CBOR byte string fails when
+// using non-default ByteStringExpectedFormat decoding option that makes decoder expect
+// a specified format such as base64, hex, etc.
+type ByteStringExpectedFormatError struct {
+ expectedFormatOption ByteStringExpectedFormatMode
+ err error
+}
+
+func newByteStringExpectedFormatError(expectedFormatOption ByteStringExpectedFormatMode, err error) *ByteStringExpectedFormatError {
+ return &ByteStringExpectedFormatError{expectedFormatOption, err}
+}
+
+func (e *ByteStringExpectedFormatError) Error() string {
+ switch e.expectedFormatOption {
+ case ByteStringExpectedBase64URL:
+ return fmt.Sprintf("cbor: failed to decode base64url from byte string: %s", e.err)
+
+ case ByteStringExpectedBase64:
+ return fmt.Sprintf("cbor: failed to decode base64 from byte string: %s", e.err)
+
+ case ByteStringExpectedBase16:
+ return fmt.Sprintf("cbor: failed to decode hex from byte string: %s", e.err)
+
+ default:
+ return fmt.Sprintf("cbor: failed to decode byte string in expected format %d: %s", e.expectedFormatOption, e.err)
+ }
+}
+
+func (e *ByteStringExpectedFormatError) Unwrap() error {
+ return e.err
+}
+
+// InadmissibleTagContentTypeError is returned when unmarshaling built-in CBOR tags
+// fails because of inadmissible type for tag content. Currently, the built-in
+// CBOR tags in this codec are tags 0-3 and 21-23.
+// See "Tag validity" in RFC 8949 Section 5.3.2.
+type InadmissibleTagContentTypeError struct {
+ s string
+ tagNum int
+ expectedTagContentType string
+ gotTagContentType string
+}
+
+func newInadmissibleTagContentTypeError(
+ tagNum int,
+ expectedTagContentType string,
+ gotTagContentType string,
+) *InadmissibleTagContentTypeError {
+ return &InadmissibleTagContentTypeError{
+ tagNum: tagNum,
+ expectedTagContentType: expectedTagContentType,
+ gotTagContentType: gotTagContentType,
+ }
+}
+
+func newInadmissibleTagContentTypeErrorf(s string) *InadmissibleTagContentTypeError {
+ return &InadmissibleTagContentTypeError{s: "cbor: " + s} //nolint:goconst // ignore "cbor"
+}
+
+func (e *InadmissibleTagContentTypeError) Error() string {
+ if e.s == "" {
+ return fmt.Sprintf(
+ "cbor: tag number %d must be followed by %s, got %s",
+ e.tagNum,
+ e.expectedTagContentType,
+ e.gotTagContentType,
+ )
+ }
+ return e.s
+}
+
+// DupMapKeyMode specifies how to enforce duplicate map key. Two map keys are considered duplicates if:
+// 1. When decoding into a struct, both keys match the same struct field. The keys are also
+// considered duplicates if neither matches any field and decoding to interface{} would produce
+// equal (==) values for both keys.
+// 2. When decoding into a map, both keys are equal (==) when decoded into values of the
+// destination map's key type.
+type DupMapKeyMode int
+
+const (
+ // DupMapKeyQuiet doesn't enforce duplicate map key. Decoder quietly (no error)
+ // uses faster of "keep first" or "keep last" depending on Go data type and other factors.
+ DupMapKeyQuiet DupMapKeyMode = iota
+
+ // DupMapKeyEnforcedAPF enforces detection and rejection of duplicate map keys.
+ // APF means "Allow Partial Fill" and the destination map or struct can be partially filled.
+ // If a duplicate map key is detected, DupMapKeyError is returned without further decoding
+ // of the map. It's the caller's responsibility to respond to DupMapKeyError by
+ // discarding the partially filled result if their protocol requires it.
+ // WARNING: using DupMapKeyEnforcedAPF will decrease performance and increase memory use.
+ DupMapKeyEnforcedAPF
+
+ maxDupMapKeyMode
+)
+
+func (dmkm DupMapKeyMode) valid() bool {
+ return dmkm >= 0 && dmkm < maxDupMapKeyMode
+}
+
+// IndefLengthMode specifies whether to allow indefinite length items.
+type IndefLengthMode int
+
+const (
+ // IndefLengthAllowed allows indefinite length items.
+ IndefLengthAllowed IndefLengthMode = iota
+
+ // IndefLengthForbidden disallows indefinite length items.
+ IndefLengthForbidden
+
+ maxIndefLengthMode
+)
+
+func (m IndefLengthMode) valid() bool {
+ return m >= 0 && m < maxIndefLengthMode
+}
+
+// TagsMode specifies whether to allow CBOR tags.
+type TagsMode int
+
+const (
+ // TagsAllowed allows CBOR tags.
+ TagsAllowed TagsMode = iota
+
+ // TagsForbidden disallows CBOR tags.
+ TagsForbidden
+
+ maxTagsMode
+)
+
+func (tm TagsMode) valid() bool {
+ return tm >= 0 && tm < maxTagsMode
+}
+
+// IntDecMode specifies which Go type (int64, uint64, or big.Int) should
+// be used when decoding CBOR integers (major type 0 and 1) to Go interface{}.
+type IntDecMode int
+
+const (
+ // IntDecConvertNone affects how CBOR integers (major type 0 and 1) decode to Go interface{}.
+ // It decodes CBOR unsigned integer (major type 0) to:
+ // - uint64
+ // It decodes CBOR negative integer (major type 1) to:
+ // - int64 if value fits
+ // - big.Int or *big.Int (see BigIntDecMode) if value doesn't fit into int64
+ IntDecConvertNone IntDecMode = iota
+
+ // IntDecConvertSigned affects how CBOR integers (major type 0 and 1) decode to Go interface{}.
+ // It decodes CBOR integers (major type 0 and 1) to:
+ // - int64 if value fits
+ // - big.Int or *big.Int (see BigIntDecMode) if value < math.MinInt64
+ // - return UnmarshalTypeError if value > math.MaxInt64
+ // Deprecated: IntDecConvertSigned should not be used.
+ // Please use other options, such as IntDecConvertSignedOrError, IntDecConvertSignedOrBigInt, IntDecConvertNone.
+ IntDecConvertSigned
+
+ // IntDecConvertSignedOrFail affects how CBOR integers (major type 0 and 1) decode to Go interface{}.
+ // It decodes CBOR integers (major type 0 and 1) to:
+ // - int64 if value fits
+ // - return UnmarshalTypeError if value doesn't fit into int64
+ IntDecConvertSignedOrFail
+
+ // IntDecConvertSigned affects how CBOR integers (major type 0 and 1) decode to Go interface{}.
+ // It makes CBOR integers (major type 0 and 1) decode to:
+ // - int64 if value fits
+ // - big.Int or *big.Int (see BigIntDecMode) if value doesn't fit into int64
+ IntDecConvertSignedOrBigInt
+
+ maxIntDec
+)
+
+func (idm IntDecMode) valid() bool {
+ return idm >= 0 && idm < maxIntDec
+}
+
+// MapKeyByteStringMode specifies how to decode CBOR byte string (major type 2)
+// as Go map key when decoding CBOR map key into an empty Go interface value.
+// Specifically, this option applies when decoding CBOR map into
+// - Go empty interface, or
+// - Go map with empty interface as key type.
+// The CBOR map key types handled by this option are
+// - byte string
+// - tagged byte string
+// - nested tagged byte string
+type MapKeyByteStringMode int
+
+const (
+ // MapKeyByteStringAllowed allows CBOR byte string to be decoded as Go map key.
+ // Since Go doesn't allow []byte as map key, CBOR byte string is decoded to
+ // ByteString which has underlying string type.
+ // This is the default setting.
+ MapKeyByteStringAllowed MapKeyByteStringMode = iota
+
+ // MapKeyByteStringForbidden forbids CBOR byte string being decoded as Go map key.
+ // Attempting to decode CBOR byte string as map key into empty interface value
+ // returns a decoding error.
+ MapKeyByteStringForbidden
+
+ maxMapKeyByteStringMode
+)
+
+func (mkbsm MapKeyByteStringMode) valid() bool {
+ return mkbsm >= 0 && mkbsm < maxMapKeyByteStringMode
+}
+
+// ExtraDecErrorCond specifies extra conditions that should be treated as errors.
+type ExtraDecErrorCond uint
+
+// ExtraDecErrorNone indicates no extra error condition.
+const ExtraDecErrorNone ExtraDecErrorCond = 0
+
+const (
+ // ExtraDecErrorUnknownField indicates error condition when destination
+ // Go struct doesn't have a field matching a CBOR map key.
+ ExtraDecErrorUnknownField ExtraDecErrorCond = 1 << iota
+
+ maxExtraDecError
+)
+
+func (ec ExtraDecErrorCond) valid() bool {
+ return ec < maxExtraDecError
+}
+
+// UTF8Mode option specifies if decoder should
+// decode CBOR Text containing invalid UTF-8 string.
+type UTF8Mode int
+
+const (
+ // UTF8RejectInvalid rejects CBOR Text containing
+ // invalid UTF-8 string.
+ UTF8RejectInvalid UTF8Mode = iota
+
+ // UTF8DecodeInvalid allows decoding CBOR Text containing
+ // invalid UTF-8 string.
+ UTF8DecodeInvalid
+
+ maxUTF8Mode
+)
+
+func (um UTF8Mode) valid() bool {
+ return um >= 0 && um < maxUTF8Mode
+}
+
+// FieldNameMatchingMode specifies how string keys in CBOR maps are matched to Go struct field names.
+type FieldNameMatchingMode int
+
+const (
+ // FieldNameMatchingPreferCaseSensitive prefers to decode map items into struct fields whose names (or tag
+ // names) exactly match the item's key. If there is no such field, a map item will be decoded into a field whose
+ // name is a case-insensitive match for the item's key.
+ FieldNameMatchingPreferCaseSensitive FieldNameMatchingMode = iota
+
+ // FieldNameMatchingCaseSensitive decodes map items only into a struct field whose name (or tag name) is an
+ // exact match for the item's key.
+ FieldNameMatchingCaseSensitive
+
+ maxFieldNameMatchingMode
+)
+
+func (fnmm FieldNameMatchingMode) valid() bool {
+ return fnmm >= 0 && fnmm < maxFieldNameMatchingMode
+}
+
+// BigIntDecMode specifies how to decode CBOR bignum to Go interface{}.
+type BigIntDecMode int
+
+const (
+ // BigIntDecodeValue makes CBOR bignum decode to big.Int (instead of *big.Int)
+ // when unmarshalling into a Go interface{}.
+ BigIntDecodeValue BigIntDecMode = iota
+
+ // BigIntDecodePointer makes CBOR bignum decode to *big.Int when
+ // unmarshalling into a Go interface{}.
+ BigIntDecodePointer
+
+ maxBigIntDecMode
+)
+
+func (bidm BigIntDecMode) valid() bool {
+ return bidm >= 0 && bidm < maxBigIntDecMode
+}
+
+// ByteStringToStringMode specifies the behavior when decoding a CBOR byte string into a Go string.
+type ByteStringToStringMode int
+
+const (
+ // ByteStringToStringForbidden generates an error on an attempt to decode a CBOR byte string into a Go string.
+ ByteStringToStringForbidden ByteStringToStringMode = iota
+
+ // ByteStringToStringAllowed permits decoding a CBOR byte string into a Go string.
+ ByteStringToStringAllowed
+
+ // ByteStringToStringAllowedWithExpectedLaterEncoding permits decoding a CBOR byte string
+ // into a Go string. Also, if the byte string is enclosed (directly or indirectly) by one of
+ // the "expected later encoding" tags (numbers 21 through 23), the destination string will
+ // be populated by applying the designated text encoding to the contents of the input byte
+ // string.
+ ByteStringToStringAllowedWithExpectedLaterEncoding
+
+ maxByteStringToStringMode
+)
+
+func (bstsm ByteStringToStringMode) valid() bool {
+ return bstsm >= 0 && bstsm < maxByteStringToStringMode
+}
+
+// FieldNameByteStringMode specifies the behavior when decoding a CBOR byte string map key as a Go struct field name.
+type FieldNameByteStringMode int
+
+const (
+ // FieldNameByteStringForbidden generates an error on an attempt to decode a CBOR byte string map key as a Go struct field name.
+ FieldNameByteStringForbidden FieldNameByteStringMode = iota
+
+ // FieldNameByteStringAllowed permits CBOR byte string map keys to be recognized as Go struct field names.
+ FieldNameByteStringAllowed
+
+ maxFieldNameByteStringMode
+)
+
+func (fnbsm FieldNameByteStringMode) valid() bool {
+ return fnbsm >= 0 && fnbsm < maxFieldNameByteStringMode
+}
+
+// UnrecognizedTagToAnyMode specifies how to decode unrecognized CBOR tag into an empty interface (any).
+// Currently, recognized CBOR tag numbers are 0, 1, 2, 3, or registered by TagSet.
+type UnrecognizedTagToAnyMode int
+
+const (
+ // UnrecognizedTagNumAndContentToAny decodes CBOR tag number and tag content to cbor.Tag
+ // when decoding unrecognized CBOR tag into an empty interface.
+ UnrecognizedTagNumAndContentToAny UnrecognizedTagToAnyMode = iota
+
+ // UnrecognizedTagContentToAny decodes only CBOR tag content (into its default type)
+ // when decoding unrecognized CBOR tag into an empty interface.
+ UnrecognizedTagContentToAny
+
+ maxUnrecognizedTagToAny
+)
+
+func (uttam UnrecognizedTagToAnyMode) valid() bool {
+ return uttam >= 0 && uttam < maxUnrecognizedTagToAny
+}
+
+// TimeTagToAnyMode specifies how to decode CBOR tag 0 and 1 into an empty interface (any).
+// Based on the specified mode, Unmarshal can return a time.Time value or a time string in a specific format.
+type TimeTagToAnyMode int
+
+const (
+ // TimeTagToTime decodes CBOR tag 0 and 1 into a time.Time value
+ // when decoding tag 0 or 1 into an empty interface.
+ TimeTagToTime TimeTagToAnyMode = iota
+
+ // TimeTagToRFC3339 decodes CBOR tag 0 and 1 into a time string in RFC3339 format
+ // when decoding tag 0 or 1 into an empty interface.
+ TimeTagToRFC3339
+
+ // TimeTagToRFC3339Nano decodes CBOR tag 0 and 1 into a time string in RFC3339Nano format
+ // when decoding tag 0 or 1 into an empty interface.
+ TimeTagToRFC3339Nano
+
+ maxTimeTagToAnyMode
+)
+
+func (tttam TimeTagToAnyMode) valid() bool {
+ return tttam >= 0 && tttam < maxTimeTagToAnyMode
+}
+
+// SimpleValueRegistry is a registry of unmarshaling behaviors for each possible CBOR simple value
+// number (0...23 and 32...255).
+type SimpleValueRegistry struct {
+ rejected [256]bool
+}
+
+// WithRejectedSimpleValue registers the given simple value as rejected. If the simple value is
+// encountered in a CBOR input during unmarshaling, an UnacceptableDataItemError is returned.
+func WithRejectedSimpleValue(sv SimpleValue) func(*SimpleValueRegistry) error {
+ return func(r *SimpleValueRegistry) error {
+ if sv >= 24 && sv <= 31 {
+ return fmt.Errorf("cbor: cannot set analog for reserved simple value %d", sv)
+ }
+ r.rejected[sv] = true
+ return nil
+ }
+}
+
+// Creates a new SimpleValueRegistry. The registry state is initialized by executing the provided
+// functions in order against a registry that is pre-populated with the defaults for all well-formed
+// simple value numbers.
+func NewSimpleValueRegistryFromDefaults(fns ...func(*SimpleValueRegistry) error) (*SimpleValueRegistry, error) {
+ var r SimpleValueRegistry
+ for _, fn := range fns {
+ if err := fn(&r); err != nil {
+ return nil, err
+ }
+ }
+ return &r, nil
+}
+
+// NaNMode specifies how to decode floating-point values (major type 7, additional information 25
+// through 27) representing NaN (not-a-number).
+type NaNMode int
+
+const (
+ // NaNDecodeAllowed will decode NaN values to Go float32 or float64.
+ NaNDecodeAllowed NaNMode = iota
+
+ // NaNDecodeForbidden will return an UnacceptableDataItemError on an attempt to decode a NaN value.
+ NaNDecodeForbidden
+
+ maxNaNDecode
+)
+
+func (ndm NaNMode) valid() bool {
+ return ndm >= 0 && ndm < maxNaNDecode
+}
+
+// InfMode specifies how to decode floating-point values (major type 7, additional information 25
+// through 27) representing positive or negative infinity.
+type InfMode int
+
+const (
+ // InfDecodeAllowed will decode infinite values to Go float32 or float64.
+ InfDecodeAllowed InfMode = iota
+
+ // InfDecodeForbidden will return an UnacceptableDataItemError on an attempt to decode an
+ // infinite value.
+ InfDecodeForbidden
+
+ maxInfDecode
+)
+
+func (idm InfMode) valid() bool {
+ return idm >= 0 && idm < maxInfDecode
+}
+
+// ByteStringToTimeMode specifies the behavior when decoding a CBOR byte string into a Go time.Time.
+type ByteStringToTimeMode int
+
+const (
+ // ByteStringToTimeForbidden generates an error on an attempt to decode a CBOR byte string into a Go time.Time.
+ ByteStringToTimeForbidden ByteStringToTimeMode = iota
+
+ // ByteStringToTimeAllowed permits decoding a CBOR byte string into a Go time.Time.
+ ByteStringToTimeAllowed
+
+ maxByteStringToTimeMode
+)
+
+func (bttm ByteStringToTimeMode) valid() bool {
+ return bttm >= 0 && bttm < maxByteStringToTimeMode
+}
+
+// ByteStringExpectedFormatMode specifies how to decode CBOR byte string into Go byte slice
+// when the byte string is NOT enclosed in CBOR tag 21, 22, or 23. An error is returned if
+// the CBOR byte string does not contain the expected format (e.g. base64) specified.
+// For tags 21-23, see "Expected Later Encoding for CBOR-to-JSON Converters"
+// in RFC 8949 Section 3.4.5.2.
+type ByteStringExpectedFormatMode int
+
+const (
+ // ByteStringExpectedFormatNone copies the unmodified CBOR byte string into Go byte slice
+ // if the byte string is not tagged by CBOR tag 21-23.
+ ByteStringExpectedFormatNone ByteStringExpectedFormatMode = iota
+
+ // ByteStringExpectedBase64URL expects CBOR byte strings to contain base64url-encoded bytes
+ // if the byte string is not tagged by CBOR tag 21-23. The decoder will attempt to decode
+ // the base64url-encoded bytes into Go slice.
+ ByteStringExpectedBase64URL
+
+ // ByteStringExpectedBase64 expects CBOR byte strings to contain base64-encoded bytes
+ // if the byte string is not tagged by CBOR tag 21-23. The decoder will attempt to decode
+ // the base64-encoded bytes into Go slice.
+ ByteStringExpectedBase64
+
+ // ByteStringExpectedBase16 expects CBOR byte strings to contain base16-encoded bytes
+ // if the byte string is not tagged by CBOR tag 21-23. The decoder will attempt to decode
+ // the base16-encoded bytes into Go slice.
+ ByteStringExpectedBase16
+
+ maxByteStringExpectedFormatMode
+)
+
+func (bsefm ByteStringExpectedFormatMode) valid() bool {
+ return bsefm >= 0 && bsefm < maxByteStringExpectedFormatMode
+}
+
+// BignumTagMode specifies whether or not the "bignum" tags 2 and 3 (RFC 8949 Section 3.4.3) can be
+// decoded.
+type BignumTagMode int
+
+const (
+ // BignumTagAllowed allows bignum tags to be decoded.
+ BignumTagAllowed BignumTagMode = iota
+
+ // BignumTagForbidden produces an UnacceptableDataItemError during Unmarshal if a bignum tag
+ // is encountered in the input.
+ BignumTagForbidden
+
+ maxBignumTag
+)
+
+func (btm BignumTagMode) valid() bool {
+ return btm >= 0 && btm < maxBignumTag
+}
+
+// BinaryUnmarshalerMode specifies how to decode into types that implement
+// encoding.BinaryUnmarshaler.
+type BinaryUnmarshalerMode int
+
+const (
+ // BinaryUnmarshalerByteString will invoke UnmarshalBinary on the contents of a CBOR byte
+ // string when decoding into a value that implements BinaryUnmarshaler.
+ BinaryUnmarshalerByteString BinaryUnmarshalerMode = iota
+
+ // BinaryUnmarshalerNone does not recognize BinaryUnmarshaler implementations during decode.
+ BinaryUnmarshalerNone
+
+ maxBinaryUnmarshalerMode
+)
+
+func (bum BinaryUnmarshalerMode) valid() bool {
+ return bum >= 0 && bum < maxBinaryUnmarshalerMode
+}
+
+// DecOptions specifies decoding options.
+type DecOptions struct {
+ // DupMapKey specifies whether to enforce duplicate map key.
+ DupMapKey DupMapKeyMode
+
+ // TimeTag specifies whether or not untagged data items, or tags other
+ // than tag 0 and tag 1, can be decoded to time.Time. If tag 0 or tag 1
+ // appears in an input, the type of its content is always validated as
+ // specified in RFC 8949. That behavior is not controlled by this
+ // option. The behavior of the supported modes are:
+ //
+ // DecTagIgnored (default): Untagged text strings and text strings
+ // enclosed in tags other than 0 and 1 are decoded as though enclosed
+ // in tag 0. Untagged unsigned integers, negative integers, and
+ // floating-point numbers (or those enclosed in tags other than 0 and
+ // 1) are decoded as though enclosed in tag 1. Decoding a tag other
+ // than 0 or 1 enclosing simple values null or undefined into a
+ // time.Time does not modify the destination value.
+ //
+ // DecTagOptional: Untagged text strings are decoded as though
+ // enclosed in tag 0. Untagged unsigned integers, negative integers,
+ // and floating-point numbers are decoded as though enclosed in tag
+ // 1. Tags other than 0 and 1 will produce an error on attempts to
+ // decode them into a time.Time.
+ //
+ // DecTagRequired: Only tags 0 and 1 can be decoded to time.Time. Any
+ // other input will produce an error.
+ TimeTag DecTagMode
+
+ // MaxNestedLevels specifies the max nested levels allowed for any combination of CBOR array, maps, and tags.
+ // Default is 32 levels and it can be set to [4, 65535]. Note that higher maximum levels of nesting can
+ // require larger amounts of stack to deserialize. Don't increase this higher than you require.
+ MaxNestedLevels int
+
+ // MaxArrayElements specifies the max number of elements for CBOR arrays.
+ // Default is 128*1024=131072 and it can be set to [16, 2147483647]
+ MaxArrayElements int
+
+ // MaxMapPairs specifies the max number of key-value pairs for CBOR maps.
+ // Default is 128*1024=131072 and it can be set to [16, 2147483647]
+ MaxMapPairs int
+
+ // IndefLength specifies whether to allow indefinite length CBOR items.
+ IndefLength IndefLengthMode
+
+ // TagsMd specifies whether to allow CBOR tags (major type 6).
+ TagsMd TagsMode
+
+ // IntDec specifies which Go integer type (int64 or uint64) to use
+ // when decoding CBOR int (major type 0 and 1) to Go interface{}.
+ IntDec IntDecMode
+
+ // MapKeyByteString specifies how to decode CBOR byte string as map key
+ // when decoding CBOR map with byte string key into an empty interface value.
+ // By default, an error is returned when attempting to decode CBOR byte string
+ // as map key because Go doesn't allow []byte as map key.
+ MapKeyByteString MapKeyByteStringMode
+
+ // ExtraReturnErrors specifies extra conditions that should be treated as errors.
+ ExtraReturnErrors ExtraDecErrorCond
+
+ // DefaultMapType specifies Go map type to create and decode to
+ // when unmarshalling CBOR into an empty interface value.
+ // By default, unmarshal uses map[interface{}]interface{}.
+ DefaultMapType reflect.Type
+
+ // UTF8 specifies if decoder should decode CBOR Text containing invalid UTF-8.
+ // By default, unmarshal rejects CBOR text containing invalid UTF-8.
+ UTF8 UTF8Mode
+
+ // FieldNameMatching specifies how string keys in CBOR maps are matched to Go struct field names.
+ FieldNameMatching FieldNameMatchingMode
+
+ // BigIntDec specifies how to decode CBOR bignum to Go interface{}.
+ BigIntDec BigIntDecMode
+
+ // DefaultByteStringType is the Go type that should be produced when decoding a CBOR byte
+ // string into an empty interface value. Types to which a []byte is convertible are valid
+ // for this option, except for array and pointer-to-array types. If nil, the default is
+ // []byte.
+ DefaultByteStringType reflect.Type
+
+ // ByteStringToString specifies the behavior when decoding a CBOR byte string into a Go string.
+ ByteStringToString ByteStringToStringMode
+
+ // FieldNameByteString specifies the behavior when decoding a CBOR byte string map key as a
+ // Go struct field name.
+ FieldNameByteString FieldNameByteStringMode
+
+ // UnrecognizedTagToAny specifies how to decode unrecognized CBOR tag into an empty interface.
+ // Currently, recognized CBOR tag numbers are 0, 1, 2, 3, or registered by TagSet.
+ UnrecognizedTagToAny UnrecognizedTagToAnyMode
+
+ // TimeTagToAny specifies how to decode CBOR tag 0 and 1 into an empty interface (any).
+ // Based on the specified mode, Unmarshal can return a time.Time value or a time string in a specific format.
+ TimeTagToAny TimeTagToAnyMode
+
+ // SimpleValues is an immutable mapping from each CBOR simple value to a corresponding
+ // unmarshal behavior. If nil, the simple values false, true, null, and undefined are mapped
+ // to the Go analog values false, true, nil, and nil, respectively, and all other simple
+ // values N (except the reserved simple values 24 through 31) are mapped to
+ // cbor.SimpleValue(N). In other words, all well-formed simple values can be decoded.
+ //
+ // Users may provide a custom SimpleValueRegistry constructed via
+ // NewSimpleValueRegistryFromDefaults.
+ SimpleValues *SimpleValueRegistry
+
+ // NaN specifies how to decode floating-point values (major type 7, additional information
+ // 25 through 27) representing NaN (not-a-number).
+ NaN NaNMode
+
+ // Inf specifies how to decode floating-point values (major type 7, additional information
+ // 25 through 27) representing positive or negative infinity.
+ Inf InfMode
+
+ // ByteStringToTime specifies how to decode CBOR byte string into Go time.Time.
+ ByteStringToTime ByteStringToTimeMode
+
+ // ByteStringExpectedFormat specifies how to decode CBOR byte string into Go byte slice
+ // when the byte string is NOT enclosed in CBOR tag 21, 22, or 23. An error is returned if
+ // the CBOR byte string does not contain the expected format (e.g. base64) specified.
+ // For tags 21-23, see "Expected Later Encoding for CBOR-to-JSON Converters"
+ // in RFC 8949 Section 3.4.5.2.
+ ByteStringExpectedFormat ByteStringExpectedFormatMode
+
+ // BignumTag specifies whether or not the "bignum" tags 2 and 3 (RFC 8949 Section 3.4.3) can
+ // be decoded. Unlike BigIntDec, this option applies to all bignum tags encountered in a
+ // CBOR input, independent of the type of the destination value of a particular Unmarshal
+ // operation.
+ BignumTag BignumTagMode
+
+ // BinaryUnmarshaler specifies how to decode into types that implement
+ // encoding.BinaryUnmarshaler.
+ BinaryUnmarshaler BinaryUnmarshalerMode
+}
+
+// DecMode returns DecMode with immutable options and no tags (safe for concurrency).
+func (opts DecOptions) DecMode() (DecMode, error) { //nolint:gocritic // ignore hugeParam
+ return opts.decMode()
+}
+
+// validForTags checks that the provided tag set is compatible with these options and returns a
+// non-nil error if and only if the provided tag set is incompatible.
+func (opts DecOptions) validForTags(tags TagSet) error { //nolint:gocritic // ignore hugeParam
+ if opts.TagsMd == TagsForbidden {
+ return errors.New("cbor: cannot create DecMode with TagSet when TagsMd is TagsForbidden")
+ }
+ if tags == nil {
+ return errors.New("cbor: cannot create DecMode with nil value as TagSet")
+ }
+ if opts.ByteStringToString == ByteStringToStringAllowedWithExpectedLaterEncoding ||
+ opts.ByteStringExpectedFormat != ByteStringExpectedFormatNone {
+ for _, tagNum := range []uint64{
+ tagNumExpectedLaterEncodingBase64URL,
+ tagNumExpectedLaterEncodingBase64,
+ tagNumExpectedLaterEncodingBase16,
+ } {
+ if rt := tags.getTypeFromTagNum([]uint64{tagNum}); rt != nil {
+ return fmt.Errorf("cbor: DecMode with non-default StringExpectedEncoding or ByteSliceExpectedEncoding treats tag %d as built-in and conflicts with the provided TagSet's registration of %v", tagNum, rt)
+ }
+ }
+
+ }
+ return nil
+}
+
+// DecModeWithTags returns DecMode with options and tags that are both immutable (safe for concurrency).
+func (opts DecOptions) DecModeWithTags(tags TagSet) (DecMode, error) { //nolint:gocritic // ignore hugeParam
+ if err := opts.validForTags(tags); err != nil {
+ return nil, err
+ }
+ dm, err := opts.decMode()
+ if err != nil {
+ return nil, err
+ }
+
+ // Copy tags
+ ts := tagSet(make(map[reflect.Type]*tagItem))
+ syncTags := tags.(*syncTagSet)
+ syncTags.RLock()
+ for contentType, tag := range syncTags.t {
+ if tag.opts.DecTag != DecTagIgnored {
+ ts[contentType] = tag
+ }
+ }
+ syncTags.RUnlock()
+
+ if len(ts) > 0 {
+ dm.tags = ts
+ }
+
+ return dm, nil
+}
+
+// DecModeWithSharedTags returns DecMode with immutable options and mutable shared tags (safe for concurrency).
+func (opts DecOptions) DecModeWithSharedTags(tags TagSet) (DecMode, error) { //nolint:gocritic // ignore hugeParam
+ if err := opts.validForTags(tags); err != nil {
+ return nil, err
+ }
+ dm, err := opts.decMode()
+ if err != nil {
+ return nil, err
+ }
+ dm.tags = tags
+ return dm, nil
+}
+
+const (
+ defaultMaxArrayElements = 131072
+ minMaxArrayElements = 16
+ maxMaxArrayElements = 2147483647
+
+ defaultMaxMapPairs = 131072
+ minMaxMapPairs = 16
+ maxMaxMapPairs = 2147483647
+
+ defaultMaxNestedLevels = 32
+ minMaxNestedLevels = 4
+ maxMaxNestedLevels = 65535
+)
+
+var defaultSimpleValues = func() *SimpleValueRegistry {
+ registry, err := NewSimpleValueRegistryFromDefaults()
+ if err != nil {
+ panic(err)
+ }
+ return registry
+}()
+
+//nolint:gocyclo // Each option comes with some manageable boilerplate
+func (opts DecOptions) decMode() (*decMode, error) { //nolint:gocritic // ignore hugeParam
+ if !opts.DupMapKey.valid() {
+ return nil, errors.New("cbor: invalid DupMapKey " + strconv.Itoa(int(opts.DupMapKey)))
+ }
+
+ if !opts.TimeTag.valid() {
+ return nil, errors.New("cbor: invalid TimeTag " + strconv.Itoa(int(opts.TimeTag)))
+ }
+
+ if !opts.IndefLength.valid() {
+ return nil, errors.New("cbor: invalid IndefLength " + strconv.Itoa(int(opts.IndefLength)))
+ }
+
+ if !opts.TagsMd.valid() {
+ return nil, errors.New("cbor: invalid TagsMd " + strconv.Itoa(int(opts.TagsMd)))
+ }
+
+ if !opts.IntDec.valid() {
+ return nil, errors.New("cbor: invalid IntDec " + strconv.Itoa(int(opts.IntDec)))
+ }
+
+ if !opts.MapKeyByteString.valid() {
+ return nil, errors.New("cbor: invalid MapKeyByteString " + strconv.Itoa(int(opts.MapKeyByteString)))
+ }
+
+ if opts.MaxNestedLevels == 0 {
+ opts.MaxNestedLevels = defaultMaxNestedLevels
+ } else if opts.MaxNestedLevels < minMaxNestedLevels || opts.MaxNestedLevels > maxMaxNestedLevels {
+ return nil, errors.New("cbor: invalid MaxNestedLevels " + strconv.Itoa(opts.MaxNestedLevels) +
+ " (range is [" + strconv.Itoa(minMaxNestedLevels) + ", " + strconv.Itoa(maxMaxNestedLevels) + "])")
+ }
+
+ if opts.MaxArrayElements == 0 {
+ opts.MaxArrayElements = defaultMaxArrayElements
+ } else if opts.MaxArrayElements < minMaxArrayElements || opts.MaxArrayElements > maxMaxArrayElements {
+ return nil, errors.New("cbor: invalid MaxArrayElements " + strconv.Itoa(opts.MaxArrayElements) +
+ " (range is [" + strconv.Itoa(minMaxArrayElements) + ", " + strconv.Itoa(maxMaxArrayElements) + "])")
+ }
+
+ if opts.MaxMapPairs == 0 {
+ opts.MaxMapPairs = defaultMaxMapPairs
+ } else if opts.MaxMapPairs < minMaxMapPairs || opts.MaxMapPairs > maxMaxMapPairs {
+ return nil, errors.New("cbor: invalid MaxMapPairs " + strconv.Itoa(opts.MaxMapPairs) +
+ " (range is [" + strconv.Itoa(minMaxMapPairs) + ", " + strconv.Itoa(maxMaxMapPairs) + "])")
+ }
+
+ if !opts.ExtraReturnErrors.valid() {
+ return nil, errors.New("cbor: invalid ExtraReturnErrors " + strconv.Itoa(int(opts.ExtraReturnErrors)))
+ }
+
+ if opts.DefaultMapType != nil && opts.DefaultMapType.Kind() != reflect.Map {
+ return nil, fmt.Errorf("cbor: invalid DefaultMapType %s", opts.DefaultMapType)
+ }
+
+ if !opts.UTF8.valid() {
+ return nil, errors.New("cbor: invalid UTF8 " + strconv.Itoa(int(opts.UTF8)))
+ }
+
+ if !opts.FieldNameMatching.valid() {
+ return nil, errors.New("cbor: invalid FieldNameMatching " + strconv.Itoa(int(opts.FieldNameMatching)))
+ }
+
+ if !opts.BigIntDec.valid() {
+ return nil, errors.New("cbor: invalid BigIntDec " + strconv.Itoa(int(opts.BigIntDec)))
+ }
+
+ if opts.DefaultByteStringType != nil &&
+ opts.DefaultByteStringType.Kind() != reflect.String &&
+ (opts.DefaultByteStringType.Kind() != reflect.Slice || opts.DefaultByteStringType.Elem().Kind() != reflect.Uint8) {
+ return nil, fmt.Errorf("cbor: invalid DefaultByteStringType: %s is not of kind string or []uint8", opts.DefaultByteStringType)
+ }
+
+ if !opts.ByteStringToString.valid() {
+ return nil, errors.New("cbor: invalid ByteStringToString " + strconv.Itoa(int(opts.ByteStringToString)))
+ }
+
+ if !opts.FieldNameByteString.valid() {
+ return nil, errors.New("cbor: invalid FieldNameByteString " + strconv.Itoa(int(opts.FieldNameByteString)))
+ }
+
+ if !opts.UnrecognizedTagToAny.valid() {
+ return nil, errors.New("cbor: invalid UnrecognizedTagToAnyMode " + strconv.Itoa(int(opts.UnrecognizedTagToAny)))
+ }
+ simpleValues := opts.SimpleValues
+ if simpleValues == nil {
+ simpleValues = defaultSimpleValues
+ }
+
+ if !opts.TimeTagToAny.valid() {
+ return nil, errors.New("cbor: invalid TimeTagToAny " + strconv.Itoa(int(opts.TimeTagToAny)))
+ }
+
+ if !opts.NaN.valid() {
+ return nil, errors.New("cbor: invalid NaNDec " + strconv.Itoa(int(opts.NaN)))
+ }
+
+ if !opts.Inf.valid() {
+ return nil, errors.New("cbor: invalid InfDec " + strconv.Itoa(int(opts.Inf)))
+ }
+
+ if !opts.ByteStringToTime.valid() {
+ return nil, errors.New("cbor: invalid ByteStringToTime " + strconv.Itoa(int(opts.ByteStringToTime)))
+ }
+
+ if !opts.ByteStringExpectedFormat.valid() {
+ return nil, errors.New("cbor: invalid ByteStringExpectedFormat " + strconv.Itoa(int(opts.ByteStringExpectedFormat)))
+ }
+
+ if !opts.BignumTag.valid() {
+ return nil, errors.New("cbor: invalid BignumTag " + strconv.Itoa(int(opts.BignumTag)))
+ }
+
+ if !opts.BinaryUnmarshaler.valid() {
+ return nil, errors.New("cbor: invalid BinaryUnmarshaler " + strconv.Itoa(int(opts.BinaryUnmarshaler)))
+ }
+
+ dm := decMode{
+ dupMapKey: opts.DupMapKey,
+ timeTag: opts.TimeTag,
+ maxNestedLevels: opts.MaxNestedLevels,
+ maxArrayElements: opts.MaxArrayElements,
+ maxMapPairs: opts.MaxMapPairs,
+ indefLength: opts.IndefLength,
+ tagsMd: opts.TagsMd,
+ intDec: opts.IntDec,
+ mapKeyByteString: opts.MapKeyByteString,
+ extraReturnErrors: opts.ExtraReturnErrors,
+ defaultMapType: opts.DefaultMapType,
+ utf8: opts.UTF8,
+ fieldNameMatching: opts.FieldNameMatching,
+ bigIntDec: opts.BigIntDec,
+ defaultByteStringType: opts.DefaultByteStringType,
+ byteStringToString: opts.ByteStringToString,
+ fieldNameByteString: opts.FieldNameByteString,
+ unrecognizedTagToAny: opts.UnrecognizedTagToAny,
+ timeTagToAny: opts.TimeTagToAny,
+ simpleValues: simpleValues,
+ nanDec: opts.NaN,
+ infDec: opts.Inf,
+ byteStringToTime: opts.ByteStringToTime,
+ byteStringExpectedFormat: opts.ByteStringExpectedFormat,
+ bignumTag: opts.BignumTag,
+ binaryUnmarshaler: opts.BinaryUnmarshaler,
+ }
+
+ return &dm, nil
+}
+
+// DecMode is the main interface for CBOR decoding.
+type DecMode interface {
+ // Unmarshal parses the CBOR-encoded data into the value pointed to by v
+ // using the decoding mode. If v is nil, not a pointer, or a nil pointer,
+ // Unmarshal returns an error.
+ //
+ // See the documentation for Unmarshal for details.
+ Unmarshal(data []byte, v interface{}) error
+
+ // UnmarshalFirst parses the first CBOR data item into the value pointed to by v
+ // using the decoding mode. Any remaining bytes are returned in rest.
+ //
+ // If v is nil, not a pointer, or a nil pointer, UnmarshalFirst returns an error.
+ //
+ // See the documentation for Unmarshal for details.
+ UnmarshalFirst(data []byte, v interface{}) (rest []byte, err error)
+
+ // Valid checks whether data is a well-formed encoded CBOR data item and
+ // that it complies with configurable restrictions such as MaxNestedLevels,
+ // MaxArrayElements, MaxMapPairs, etc.
+ //
+ // If there are any remaining bytes after the CBOR data item,
+ // an ExtraneousDataError is returned.
+ //
+ // WARNING: Valid doesn't check if encoded CBOR data item is valid (i.e. validity)
+ // and RFC 8949 distinctly defines what is "Valid" and what is "Well-formed".
+ //
+ // Deprecated: Valid is kept for compatibility and should not be used.
+ // Use Wellformed instead because it has a more appropriate name.
+ Valid(data []byte) error
+
+ // Wellformed checks whether data is a well-formed encoded CBOR data item and
+ // that it complies with configurable restrictions such as MaxNestedLevels,
+ // MaxArrayElements, MaxMapPairs, etc.
+ //
+ // If there are any remaining bytes after the CBOR data item,
+ // an ExtraneousDataError is returned.
+ Wellformed(data []byte) error
+
+ // NewDecoder returns a new decoder that reads from r using dm DecMode.
+ NewDecoder(r io.Reader) *Decoder
+
+ // DecOptions returns user specified options used to create this DecMode.
+ DecOptions() DecOptions
+}
+
+type decMode struct {
+ tags tagProvider
+ dupMapKey DupMapKeyMode
+ timeTag DecTagMode
+ maxNestedLevels int
+ maxArrayElements int
+ maxMapPairs int
+ indefLength IndefLengthMode
+ tagsMd TagsMode
+ intDec IntDecMode
+ mapKeyByteString MapKeyByteStringMode
+ extraReturnErrors ExtraDecErrorCond
+ defaultMapType reflect.Type
+ utf8 UTF8Mode
+ fieldNameMatching FieldNameMatchingMode
+ bigIntDec BigIntDecMode
+ defaultByteStringType reflect.Type
+ byteStringToString ByteStringToStringMode
+ fieldNameByteString FieldNameByteStringMode
+ unrecognizedTagToAny UnrecognizedTagToAnyMode
+ timeTagToAny TimeTagToAnyMode
+ simpleValues *SimpleValueRegistry
+ nanDec NaNMode
+ infDec InfMode
+ byteStringToTime ByteStringToTimeMode
+ byteStringExpectedFormat ByteStringExpectedFormatMode
+ bignumTag BignumTagMode
+ binaryUnmarshaler BinaryUnmarshalerMode
+}
+
+var defaultDecMode, _ = DecOptions{}.decMode()
+
+// DecOptions returns user specified options used to create this DecMode.
+func (dm *decMode) DecOptions() DecOptions {
+ simpleValues := dm.simpleValues
+ if simpleValues == defaultSimpleValues {
+ // Users can't explicitly set this to defaultSimpleValues. It must have been nil in
+ // the original DecOptions.
+ simpleValues = nil
+ }
+
+ return DecOptions{
+ DupMapKey: dm.dupMapKey,
+ TimeTag: dm.timeTag,
+ MaxNestedLevels: dm.maxNestedLevels,
+ MaxArrayElements: dm.maxArrayElements,
+ MaxMapPairs: dm.maxMapPairs,
+ IndefLength: dm.indefLength,
+ TagsMd: dm.tagsMd,
+ IntDec: dm.intDec,
+ MapKeyByteString: dm.mapKeyByteString,
+ ExtraReturnErrors: dm.extraReturnErrors,
+ DefaultMapType: dm.defaultMapType,
+ UTF8: dm.utf8,
+ FieldNameMatching: dm.fieldNameMatching,
+ BigIntDec: dm.bigIntDec,
+ DefaultByteStringType: dm.defaultByteStringType,
+ ByteStringToString: dm.byteStringToString,
+ FieldNameByteString: dm.fieldNameByteString,
+ UnrecognizedTagToAny: dm.unrecognizedTagToAny,
+ TimeTagToAny: dm.timeTagToAny,
+ SimpleValues: simpleValues,
+ NaN: dm.nanDec,
+ Inf: dm.infDec,
+ ByteStringToTime: dm.byteStringToTime,
+ ByteStringExpectedFormat: dm.byteStringExpectedFormat,
+ BignumTag: dm.bignumTag,
+ BinaryUnmarshaler: dm.binaryUnmarshaler,
+ }
+}
+
+// Unmarshal parses the CBOR-encoded data into the value pointed to by v
+// using dm decoding mode. If v is nil, not a pointer, or a nil pointer,
+// Unmarshal returns an error.
+//
+// See the documentation for Unmarshal for details.
+func (dm *decMode) Unmarshal(data []byte, v interface{}) error {
+ d := decoder{data: data, dm: dm}
+
+ // Check well-formedness.
+ off := d.off // Save offset before data validation
+ err := d.wellformed(false, false) // don't allow any extra data after valid data item.
+ d.off = off // Restore offset
+ if err != nil {
+ return err
+ }
+
+ return d.value(v)
+}
+
+// UnmarshalFirst parses the first CBOR data item into the value pointed to by v
+// using dm decoding mode. Any remaining bytes are returned in rest.
+//
+// If v is nil, not a pointer, or a nil pointer, UnmarshalFirst returns an error.
+//
+// See the documentation for Unmarshal for details.
+func (dm *decMode) UnmarshalFirst(data []byte, v interface{}) (rest []byte, err error) {
+ d := decoder{data: data, dm: dm}
+
+ // check well-formedness.
+ off := d.off // Save offset before data validation
+ err = d.wellformed(true, false) // allow extra data after well-formed data item
+ d.off = off // Restore offset
+
+ // If it is well-formed, parse the value. This is structured like this to allow
+ // better test coverage
+ if err == nil {
+ err = d.value(v)
+ }
+
+ // If either wellformed or value returned an error, do not return rest bytes
+ if err != nil {
+ return nil, err
+ }
+
+ // Return the rest of the data slice (which might be len 0)
+ return d.data[d.off:], nil
+}
+
+// Valid checks whether data is a well-formed encoded CBOR data item and
+// that it complies with configurable restrictions such as MaxNestedLevels,
+// MaxArrayElements, MaxMapPairs, etc.
+//
+// If there are any remaining bytes after the CBOR data item,
+// an ExtraneousDataError is returned.
+//
+// WARNING: Valid doesn't check if encoded CBOR data item is valid (i.e. validity)
+// and RFC 8949 distinctly defines what is "Valid" and what is "Well-formed".
+//
+// Deprecated: Valid is kept for compatibility and should not be used.
+// Use Wellformed instead because it has a more appropriate name.
+func (dm *decMode) Valid(data []byte) error {
+ return dm.Wellformed(data)
+}
+
+// Wellformed checks whether data is a well-formed encoded CBOR data item and
+// that it complies with configurable restrictions such as MaxNestedLevels,
+// MaxArrayElements, MaxMapPairs, etc.
+//
+// If there are any remaining bytes after the CBOR data item,
+// an ExtraneousDataError is returned.
+func (dm *decMode) Wellformed(data []byte) error {
+ d := decoder{data: data, dm: dm}
+ return d.wellformed(false, false)
+}
+
+// NewDecoder returns a new decoder that reads from r using dm DecMode.
+func (dm *decMode) NewDecoder(r io.Reader) *Decoder {
+ return &Decoder{r: r, d: decoder{dm: dm}}
+}
+
+type decoder struct {
+ data []byte
+ off int // next read offset in data
+ dm *decMode
+
+ // expectedLaterEncodingTags stores a stack of encountered "Expected Later Encoding" tags,
+ // if any.
+ //
+ // The "Expected Later Encoding" tags (21 to 23) are valid for any data item. When decoding
+ // byte strings, the effective encoding comes from the tag nearest to the byte string being
+ // decoded. For example, the effective encoding of the byte string 21(22(h'41')) would be
+ // controlled by tag 22,and in the data item 23(h'42', 22([21(h'43')])]) the effective
+ // encoding of the byte strings h'42' and h'43' would be controlled by tag 23 and 21,
+ // respectively.
+ expectedLaterEncodingTags []uint64
+}
+
+// value decodes CBOR data item into the value pointed to by v.
+// If CBOR data item fails to be decoded into v,
+// error is returned and offset is moved to the next CBOR data item.
+// Precondition: d.data contains at least one well-formed CBOR data item.
+func (d *decoder) value(v interface{}) error {
+ // v can't be nil, non-pointer, or nil pointer value.
+ if v == nil {
+ return &InvalidUnmarshalError{"cbor: Unmarshal(nil)"}
+ }
+ rv := reflect.ValueOf(v)
+ if rv.Kind() != reflect.Ptr {
+ return &InvalidUnmarshalError{"cbor: Unmarshal(non-pointer " + rv.Type().String() + ")"}
+ } else if rv.IsNil() {
+ return &InvalidUnmarshalError{"cbor: Unmarshal(nil " + rv.Type().String() + ")"}
+ }
+ rv = rv.Elem()
+ return d.parseToValue(rv, getTypeInfo(rv.Type()))
+}
+
+// parseToValue decodes CBOR data to value. It assumes data is well-formed,
+// and does not perform bounds checking.
+func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo
+
+ // Decode CBOR nil or CBOR undefined to pointer value by setting pointer value to nil.
+ if d.nextCBORNil() && v.Kind() == reflect.Ptr {
+ d.skip()
+ v.Set(reflect.Zero(v.Type()))
+ return nil
+ }
+
+ if tInfo.spclType == specialTypeIface {
+ if !v.IsNil() {
+ // Use value type
+ v = v.Elem()
+ tInfo = getTypeInfo(v.Type())
+ } else { //nolint:gocritic
+ // Create and use registered type if CBOR data is registered tag
+ if d.dm.tags != nil && d.nextCBORType() == cborTypeTag {
+
+ off := d.off
+ var tagNums []uint64
+ for d.nextCBORType() == cborTypeTag {
+ _, _, tagNum := d.getHead()
+ tagNums = append(tagNums, tagNum)
+ }
+ d.off = off
+
+ registeredType := d.dm.tags.getTypeFromTagNum(tagNums)
+ if registeredType != nil {
+ if registeredType.Implements(tInfo.nonPtrType) ||
+ reflect.PtrTo(registeredType).Implements(tInfo.nonPtrType) {
+ v.Set(reflect.New(registeredType))
+ v = v.Elem()
+ tInfo = getTypeInfo(registeredType)
+ }
+ }
+ }
+ }
+ }
+
+ // Create new value for the pointer v to point to.
+ // At this point, CBOR value is not nil/undefined if v is a pointer.
+ for v.Kind() == reflect.Ptr {
+ if v.IsNil() {
+ if !v.CanSet() {
+ d.skip()
+ return errors.New("cbor: cannot set new value for " + v.Type().String())
+ }
+ v.Set(reflect.New(v.Type().Elem()))
+ }
+ v = v.Elem()
+ }
+
+ // Strip self-described CBOR tag number.
+ for d.nextCBORType() == cborTypeTag {
+ off := d.off
+ _, _, tagNum := d.getHead()
+ if tagNum != tagNumSelfDescribedCBOR {
+ d.off = off
+ break
+ }
+ }
+
+ // Check validity of supported built-in tags.
+ off := d.off
+ for d.nextCBORType() == cborTypeTag {
+ _, _, tagNum := d.getHead()
+ if err := validBuiltinTag(tagNum, d.data[d.off]); err != nil {
+ d.skip()
+ return err
+ }
+ }
+ d.off = off
+
+ if tInfo.spclType != specialTypeNone {
+ switch tInfo.spclType {
+ case specialTypeEmptyIface:
+ iv, err := d.parse(false) // Skipped self-described CBOR tag number already.
+ if iv != nil {
+ v.Set(reflect.ValueOf(iv))
+ }
+ return err
+
+ case specialTypeTag:
+ return d.parseToTag(v)
+
+ case specialTypeTime:
+ if d.nextCBORNil() {
+ // Decoding CBOR null and undefined to time.Time is no-op.
+ d.skip()
+ return nil
+ }
+ tm, ok, err := d.parseToTime()
+ if err != nil {
+ return err
+ }
+ if ok {
+ v.Set(reflect.ValueOf(tm))
+ }
+ return nil
+
+ case specialTypeUnmarshalerIface:
+ return d.parseToUnmarshaler(v)
+ }
+ }
+
+ // Check registered tag number
+ if tagItem := d.getRegisteredTagItem(tInfo.nonPtrType); tagItem != nil {
+ t := d.nextCBORType()
+ if t != cborTypeTag {
+ if tagItem.opts.DecTag == DecTagRequired {
+ d.skip() // Required tag number is absent, skip entire tag
+ return &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: tInfo.typ.String(),
+ errorMsg: "expect CBOR tag value"}
+ }
+ } else if err := d.validRegisteredTagNums(tagItem); err != nil {
+ d.skip() // Skip tag content
+ return err
+ }
+ }
+
+ t := d.nextCBORType()
+
+ switch t {
+ case cborTypePositiveInt:
+ _, _, val := d.getHead()
+ return fillPositiveInt(t, val, v)
+
+ case cborTypeNegativeInt:
+ _, _, val := d.getHead()
+ if val > math.MaxInt64 {
+ // CBOR negative integer overflows int64, use big.Int to store value.
+ bi := new(big.Int)
+ bi.SetUint64(val)
+ bi.Add(bi, big.NewInt(1))
+ bi.Neg(bi)
+
+ if tInfo.nonPtrType == typeBigInt {
+ v.Set(reflect.ValueOf(*bi))
+ return nil
+ }
+ return &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: tInfo.nonPtrType.String(),
+ errorMsg: bi.String() + " overflows Go's int64",
+ }
+ }
+ nValue := int64(-1) ^ int64(val)
+ return fillNegativeInt(t, nValue, v)
+
+ case cborTypeByteString:
+ b, copied := d.parseByteString()
+ b, converted, err := d.applyByteStringTextConversion(b, v.Type())
+ if err != nil {
+ return err
+ }
+ copied = copied || converted
+ return fillByteString(t, b, !copied, v, d.dm.byteStringToString, d.dm.binaryUnmarshaler)
+
+ case cborTypeTextString:
+ b, err := d.parseTextString()
+ if err != nil {
+ return err
+ }
+ return fillTextString(t, b, v)
+
+ case cborTypePrimitives:
+ _, ai, val := d.getHead()
+ switch ai {
+ case additionalInformationAsFloat16:
+ f := float64(float16.Frombits(uint16(val)).Float32())
+ return fillFloat(t, f, v)
+
+ case additionalInformationAsFloat32:
+ f := float64(math.Float32frombits(uint32(val)))
+ return fillFloat(t, f, v)
+
+ case additionalInformationAsFloat64:
+ f := math.Float64frombits(val)
+ return fillFloat(t, f, v)
+
+ default: // ai <= 24
+ if d.dm.simpleValues.rejected[SimpleValue(val)] {
+ return &UnacceptableDataItemError{
+ CBORType: t.String(),
+ Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized",
+ }
+ }
+
+ switch ai {
+ case additionalInformationAsFalse,
+ additionalInformationAsTrue:
+ return fillBool(t, ai == additionalInformationAsTrue, v)
+
+ case additionalInformationAsNull,
+ additionalInformationAsUndefined:
+ return fillNil(t, v)
+
+ default:
+ return fillPositiveInt(t, val, v)
+ }
+ }
+
+ case cborTypeTag:
+ _, _, tagNum := d.getHead()
+ switch tagNum {
+ case tagNumUnsignedBignum:
+ // Bignum (tag 2) can be decoded to uint, int, float, slice, array, or big.Int.
+ b, copied := d.parseByteString()
+ bi := new(big.Int).SetBytes(b)
+
+ if tInfo.nonPtrType == typeBigInt {
+ v.Set(reflect.ValueOf(*bi))
+ return nil
+ }
+ if tInfo.nonPtrKind == reflect.Slice || tInfo.nonPtrKind == reflect.Array {
+ return fillByteString(t, b, !copied, v, ByteStringToStringForbidden, d.dm.binaryUnmarshaler)
+ }
+ if bi.IsUint64() {
+ return fillPositiveInt(t, bi.Uint64(), v)
+ }
+ return &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: tInfo.nonPtrType.String(),
+ errorMsg: bi.String() + " overflows " + v.Type().String(),
+ }
+
+ case tagNumNegativeBignum:
+ // Bignum (tag 3) can be decoded to int, float, slice, array, or big.Int.
+ b, copied := d.parseByteString()
+ bi := new(big.Int).SetBytes(b)
+ bi.Add(bi, big.NewInt(1))
+ bi.Neg(bi)
+
+ if tInfo.nonPtrType == typeBigInt {
+ v.Set(reflect.ValueOf(*bi))
+ return nil
+ }
+ if tInfo.nonPtrKind == reflect.Slice || tInfo.nonPtrKind == reflect.Array {
+ return fillByteString(t, b, !copied, v, ByteStringToStringForbidden, d.dm.binaryUnmarshaler)
+ }
+ if bi.IsInt64() {
+ return fillNegativeInt(t, bi.Int64(), v)
+ }
+ return &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: tInfo.nonPtrType.String(),
+ errorMsg: bi.String() + " overflows " + v.Type().String(),
+ }
+
+ case tagNumExpectedLaterEncodingBase64URL, tagNumExpectedLaterEncodingBase64, tagNumExpectedLaterEncodingBase16:
+ // If conversion for interoperability with text encodings is not configured,
+ // treat tags 21-23 as unregistered tags.
+ if d.dm.byteStringToString == ByteStringToStringAllowedWithExpectedLaterEncoding || d.dm.byteStringExpectedFormat != ByteStringExpectedFormatNone {
+ d.expectedLaterEncodingTags = append(d.expectedLaterEncodingTags, tagNum)
+ defer func() {
+ d.expectedLaterEncodingTags = d.expectedLaterEncodingTags[:len(d.expectedLaterEncodingTags)-1]
+ }()
+ }
+ }
+
+ return d.parseToValue(v, tInfo)
+
+ case cborTypeArray:
+ if tInfo.nonPtrKind == reflect.Slice {
+ return d.parseArrayToSlice(v, tInfo)
+ } else if tInfo.nonPtrKind == reflect.Array {
+ return d.parseArrayToArray(v, tInfo)
+ } else if tInfo.nonPtrKind == reflect.Struct {
+ return d.parseArrayToStruct(v, tInfo)
+ }
+ d.skip()
+ return &UnmarshalTypeError{CBORType: t.String(), GoType: tInfo.nonPtrType.String()}
+
+ case cborTypeMap:
+ if tInfo.nonPtrKind == reflect.Struct {
+ return d.parseMapToStruct(v, tInfo)
+ } else if tInfo.nonPtrKind == reflect.Map {
+ return d.parseMapToMap(v, tInfo)
+ }
+ d.skip()
+ return &UnmarshalTypeError{CBORType: t.String(), GoType: tInfo.nonPtrType.String()}
+ }
+
+ return nil
+}
+
+func (d *decoder) parseToTag(v reflect.Value) error {
+ if d.nextCBORNil() {
+ // Decoding CBOR null and undefined to cbor.Tag is no-op.
+ d.skip()
+ return nil
+ }
+
+ t := d.nextCBORType()
+ if t != cborTypeTag {
+ d.skip()
+ return &UnmarshalTypeError{CBORType: t.String(), GoType: typeTag.String()}
+ }
+
+ // Unmarshal tag number
+ _, _, num := d.getHead()
+
+ // Unmarshal tag content
+ content, err := d.parse(false)
+ if err != nil {
+ return err
+ }
+
+ v.Set(reflect.ValueOf(Tag{num, content}))
+ return nil
+}
+
+// parseToTime decodes the current data item as a time.Time. The bool return value is false if and
+// only if the destination value should remain unmodified.
+func (d *decoder) parseToTime() (time.Time, bool, error) {
+ // Verify that tag number or absence of tag number is acceptable to specified timeTag.
+ if t := d.nextCBORType(); t == cborTypeTag {
+ if d.dm.timeTag == DecTagIgnored {
+ // Skip all enclosing tags
+ for t == cborTypeTag {
+ d.getHead()
+ t = d.nextCBORType()
+ }
+ if d.nextCBORNil() {
+ d.skip()
+ return time.Time{}, false, nil
+ }
+ } else {
+ // Read tag number
+ _, _, tagNum := d.getHead()
+ if tagNum != 0 && tagNum != 1 {
+ d.skip() // skip tag content
+ return time.Time{}, false, errors.New("cbor: wrong tag number for time.Time, got " + strconv.Itoa(int(tagNum)) + ", expect 0 or 1")
+ }
+ }
+ } else {
+ if d.dm.timeTag == DecTagRequired {
+ d.skip()
+ return time.Time{}, false, &UnmarshalTypeError{CBORType: t.String(), GoType: typeTime.String(), errorMsg: "expect CBOR tag value"}
+ }
+ }
+
+ switch t := d.nextCBORType(); t {
+ case cborTypeByteString:
+ if d.dm.byteStringToTime == ByteStringToTimeAllowed {
+ b, _ := d.parseByteString()
+ t, err := time.Parse(time.RFC3339, string(b))
+ if err != nil {
+ return time.Time{}, false, fmt.Errorf("cbor: cannot set %q for time.Time: %w", string(b), err)
+ }
+ return t, true, nil
+ }
+ return time.Time{}, false, &UnmarshalTypeError{CBORType: t.String(), GoType: typeTime.String()}
+
+ case cborTypeTextString:
+ s, err := d.parseTextString()
+ if err != nil {
+ return time.Time{}, false, err
+ }
+ t, err := time.Parse(time.RFC3339, string(s))
+ if err != nil {
+ return time.Time{}, false, errors.New("cbor: cannot set " + string(s) + " for time.Time: " + err.Error())
+ }
+ return t, true, nil
+
+ case cborTypePositiveInt:
+ _, _, val := d.getHead()
+ if val > math.MaxInt64 {
+ return time.Time{}, false, &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: typeTime.String(),
+ errorMsg: fmt.Sprintf("%d overflows Go's int64", val),
+ }
+ }
+ return time.Unix(int64(val), 0), true, nil
+
+ case cborTypeNegativeInt:
+ _, _, val := d.getHead()
+ if val > math.MaxInt64 {
+ if val == math.MaxUint64 {
+ // Maximum absolute value representable by negative integer is 2^64,
+ // not 2^64-1, so it overflows uint64.
+ return time.Time{}, false, &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: typeTime.String(),
+ errorMsg: "-18446744073709551616 overflows Go's int64",
+ }
+ }
+ return time.Time{}, false, &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: typeTime.String(),
+ errorMsg: fmt.Sprintf("-%d overflows Go's int64", val+1),
+ }
+ }
+ return time.Unix(int64(-1)^int64(val), 0), true, nil
+
+ case cborTypePrimitives:
+ _, ai, val := d.getHead()
+ var f float64
+ switch ai {
+ case additionalInformationAsFloat16:
+ f = float64(float16.Frombits(uint16(val)).Float32())
+
+ case additionalInformationAsFloat32:
+ f = float64(math.Float32frombits(uint32(val)))
+
+ case additionalInformationAsFloat64:
+ f = math.Float64frombits(val)
+
+ default:
+ return time.Time{}, false, &UnmarshalTypeError{CBORType: t.String(), GoType: typeTime.String()}
+ }
+
+ if math.IsNaN(f) || math.IsInf(f, 0) {
+ // https://www.rfc-editor.org/rfc/rfc8949.html#section-3.4.2-6
+ return time.Time{}, true, nil
+ }
+ seconds, fractional := math.Modf(f)
+ return time.Unix(int64(seconds), int64(fractional*1e9)), true, nil
+
+ default:
+ return time.Time{}, false, &UnmarshalTypeError{CBORType: t.String(), GoType: typeTime.String()}
+ }
+}
+
+// parseToUnmarshaler parses CBOR data to value implementing Unmarshaler interface.
+// It assumes data is well-formed, and does not perform bounds checking.
+func (d *decoder) parseToUnmarshaler(v reflect.Value) error {
+ if d.nextCBORNil() && v.Kind() == reflect.Ptr && v.IsNil() {
+ d.skip()
+ return nil
+ }
+
+ if v.Kind() != reflect.Ptr && v.CanAddr() {
+ v = v.Addr()
+ }
+ if u, ok := v.Interface().(Unmarshaler); ok {
+ start := d.off
+ d.skip()
+ return u.UnmarshalCBOR(d.data[start:d.off])
+ }
+ d.skip()
+ return errors.New("cbor: failed to assert " + v.Type().String() + " as cbor.Unmarshaler")
+}
+
+// parse parses CBOR data and returns value in default Go type.
+// It assumes data is well-formed, and does not perform bounds checking.
+func (d *decoder) parse(skipSelfDescribedTag bool) (interface{}, error) { //nolint:gocyclo
+ // Strip self-described CBOR tag number.
+ if skipSelfDescribedTag {
+ for d.nextCBORType() == cborTypeTag {
+ off := d.off
+ _, _, tagNum := d.getHead()
+ if tagNum != tagNumSelfDescribedCBOR {
+ d.off = off
+ break
+ }
+ }
+ }
+
+ // Check validity of supported built-in tags.
+ off := d.off
+ for d.nextCBORType() == cborTypeTag {
+ _, _, tagNum := d.getHead()
+ if err := validBuiltinTag(tagNum, d.data[d.off]); err != nil {
+ d.skip()
+ return nil, err
+ }
+ }
+ d.off = off
+
+ t := d.nextCBORType()
+ switch t {
+ case cborTypePositiveInt:
+ _, _, val := d.getHead()
+
+ switch d.dm.intDec {
+ case IntDecConvertNone:
+ return val, nil
+
+ case IntDecConvertSigned, IntDecConvertSignedOrFail:
+ if val > math.MaxInt64 {
+ return nil, &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: reflect.TypeOf(int64(0)).String(),
+ errorMsg: strconv.FormatUint(val, 10) + " overflows Go's int64",
+ }
+ }
+
+ return int64(val), nil
+
+ case IntDecConvertSignedOrBigInt:
+ if val > math.MaxInt64 {
+ bi := new(big.Int).SetUint64(val)
+ if d.dm.bigIntDec == BigIntDecodePointer {
+ return bi, nil
+ }
+ return *bi, nil
+ }
+
+ return int64(val), nil
+
+ default:
+ // not reachable
+ }
+
+ case cborTypeNegativeInt:
+ _, _, val := d.getHead()
+
+ if val > math.MaxInt64 {
+ // CBOR negative integer value overflows Go int64, use big.Int instead.
+ bi := new(big.Int).SetUint64(val)
+ bi.Add(bi, big.NewInt(1))
+ bi.Neg(bi)
+
+ if d.dm.intDec == IntDecConvertSignedOrFail {
+ return nil, &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: reflect.TypeOf(int64(0)).String(),
+ errorMsg: bi.String() + " overflows Go's int64",
+ }
+ }
+
+ if d.dm.bigIntDec == BigIntDecodePointer {
+ return bi, nil
+ }
+ return *bi, nil
+ }
+
+ nValue := int64(-1) ^ int64(val)
+ return nValue, nil
+
+ case cborTypeByteString:
+ b, copied := d.parseByteString()
+ var effectiveByteStringType = d.dm.defaultByteStringType
+ if effectiveByteStringType == nil {
+ effectiveByteStringType = typeByteSlice
+ }
+ b, converted, err := d.applyByteStringTextConversion(b, effectiveByteStringType)
+ if err != nil {
+ return nil, err
+ }
+ copied = copied || converted
+
+ switch effectiveByteStringType {
+ case typeByteSlice:
+ if copied {
+ return b, nil
+ }
+ clone := make([]byte, len(b))
+ copy(clone, b)
+ return clone, nil
+
+ case typeString:
+ return string(b), nil
+
+ default:
+ if copied || d.dm.defaultByteStringType.Kind() == reflect.String {
+ // Avoid an unnecessary copy since the conversion to string must
+ // copy the underlying bytes.
+ return reflect.ValueOf(b).Convert(d.dm.defaultByteStringType).Interface(), nil
+ }
+ clone := make([]byte, len(b))
+ copy(clone, b)
+ return reflect.ValueOf(clone).Convert(d.dm.defaultByteStringType).Interface(), nil
+ }
+
+ case cborTypeTextString:
+ b, err := d.parseTextString()
+ if err != nil {
+ return nil, err
+ }
+ return string(b), nil
+
+ case cborTypeTag:
+ tagOff := d.off
+ _, _, tagNum := d.getHead()
+ contentOff := d.off
+
+ switch tagNum {
+ case tagNumRFC3339Time, tagNumEpochTime:
+ d.off = tagOff
+ tm, _, err := d.parseToTime()
+ if err != nil {
+ return nil, err
+ }
+
+ switch d.dm.timeTagToAny {
+ case TimeTagToTime:
+ return tm, nil
+
+ case TimeTagToRFC3339:
+ if tagNum == 1 {
+ tm = tm.UTC()
+ }
+ // Call time.MarshalText() to format decoded time to RFC3339 format,
+ // and return error on time value that cannot be represented in
+ // RFC3339 format. E.g. year cannot exceed 9999, etc.
+ text, err := tm.Truncate(time.Second).MarshalText()
+ if err != nil {
+ return nil, fmt.Errorf("cbor: decoded time cannot be represented in RFC3339 format: %v", err)
+ }
+ return string(text), nil
+
+ case TimeTagToRFC3339Nano:
+ if tagNum == 1 {
+ tm = tm.UTC()
+ }
+ // Call time.MarshalText() to format decoded time to RFC3339 format,
+ // and return error on time value that cannot be represented in
+ // RFC3339 format with sub-second precision.
+ text, err := tm.MarshalText()
+ if err != nil {
+ return nil, fmt.Errorf("cbor: decoded time cannot be represented in RFC3339 format with sub-second precision: %v", err)
+ }
+ return string(text), nil
+
+ default:
+ // not reachable
+ }
+
+ case tagNumUnsignedBignum:
+ b, _ := d.parseByteString()
+ bi := new(big.Int).SetBytes(b)
+
+ if d.dm.bigIntDec == BigIntDecodePointer {
+ return bi, nil
+ }
+ return *bi, nil
+
+ case tagNumNegativeBignum:
+ b, _ := d.parseByteString()
+ bi := new(big.Int).SetBytes(b)
+ bi.Add(bi, big.NewInt(1))
+ bi.Neg(bi)
+
+ if d.dm.bigIntDec == BigIntDecodePointer {
+ return bi, nil
+ }
+ return *bi, nil
+
+ case tagNumExpectedLaterEncodingBase64URL, tagNumExpectedLaterEncodingBase64, tagNumExpectedLaterEncodingBase16:
+ // If conversion for interoperability with text encodings is not configured,
+ // treat tags 21-23 as unregistered tags.
+ if d.dm.byteStringToString == ByteStringToStringAllowedWithExpectedLaterEncoding ||
+ d.dm.byteStringExpectedFormat != ByteStringExpectedFormatNone {
+ d.expectedLaterEncodingTags = append(d.expectedLaterEncodingTags, tagNum)
+ defer func() {
+ d.expectedLaterEncodingTags = d.expectedLaterEncodingTags[:len(d.expectedLaterEncodingTags)-1]
+ }()
+ return d.parse(false)
+ }
+ }
+
+ if d.dm.tags != nil {
+ // Parse to specified type if tag number is registered.
+ tagNums := []uint64{tagNum}
+ for d.nextCBORType() == cborTypeTag {
+ _, _, num := d.getHead()
+ tagNums = append(tagNums, num)
+ }
+ registeredType := d.dm.tags.getTypeFromTagNum(tagNums)
+ if registeredType != nil {
+ d.off = tagOff
+ rv := reflect.New(registeredType)
+ if err := d.parseToValue(rv.Elem(), getTypeInfo(registeredType)); err != nil {
+ return nil, err
+ }
+ return rv.Elem().Interface(), nil
+ }
+ }
+
+ // Parse tag content
+ d.off = contentOff
+ content, err := d.parse(false)
+ if err != nil {
+ return nil, err
+ }
+ if d.dm.unrecognizedTagToAny == UnrecognizedTagContentToAny {
+ return content, nil
+ }
+ return Tag{tagNum, content}, nil
+
+ case cborTypePrimitives:
+ _, ai, val := d.getHead()
+ if ai <= 24 && d.dm.simpleValues.rejected[SimpleValue(val)] {
+ return nil, &UnacceptableDataItemError{
+ CBORType: t.String(),
+ Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized",
+ }
+ }
+ if ai < 20 || ai == 24 {
+ return SimpleValue(val), nil
+ }
+
+ switch ai {
+ case additionalInformationAsFalse,
+ additionalInformationAsTrue:
+ return (ai == additionalInformationAsTrue), nil
+
+ case additionalInformationAsNull,
+ additionalInformationAsUndefined:
+ return nil, nil
+
+ case additionalInformationAsFloat16:
+ f := float64(float16.Frombits(uint16(val)).Float32())
+ return f, nil
+
+ case additionalInformationAsFloat32:
+ f := float64(math.Float32frombits(uint32(val)))
+ return f, nil
+
+ case additionalInformationAsFloat64:
+ f := math.Float64frombits(val)
+ return f, nil
+ }
+
+ case cborTypeArray:
+ return d.parseArray()
+
+ case cborTypeMap:
+ if d.dm.defaultMapType != nil {
+ m := reflect.New(d.dm.defaultMapType)
+ err := d.parseToValue(m, getTypeInfo(m.Elem().Type()))
+ if err != nil {
+ return nil, err
+ }
+ return m.Elem().Interface(), nil
+ }
+ return d.parseMap()
+ }
+
+ return nil, nil
+}
+
+// parseByteString parses a CBOR encoded byte string. The returned byte slice
+// may be backed directly by the input. The second return value will be true if
+// and only if the slice is backed by a copy of the input. Callers are
+// responsible for making a copy if necessary.
+func (d *decoder) parseByteString() ([]byte, bool) {
+ _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag()
+ if !indefiniteLength {
+ b := d.data[d.off : d.off+int(val)]
+ d.off += int(val)
+ return b, false
+ }
+ // Process indefinite length string chunks.
+ b := []byte{}
+ for !d.foundBreak() {
+ _, _, val = d.getHead()
+ b = append(b, d.data[d.off:d.off+int(val)]...)
+ d.off += int(val)
+ }
+ return b, true
+}
+
+// applyByteStringTextConversion converts bytes read from a byte string to or from a configured text
+// encoding. If no transformation was performed (because it was not required), the original byte
+// slice is returned and the bool return value is false. Otherwise, a new slice containing the
+// converted bytes is returned along with the bool value true.
+func (d *decoder) applyByteStringTextConversion(
+ src []byte,
+ dstType reflect.Type,
+) (
+ dst []byte,
+ transformed bool,
+ err error,
+) {
+ switch dstType.Kind() {
+ case reflect.String:
+ if d.dm.byteStringToString != ByteStringToStringAllowedWithExpectedLaterEncoding || len(d.expectedLaterEncodingTags) == 0 {
+ return src, false, nil
+ }
+
+ switch d.expectedLaterEncodingTags[len(d.expectedLaterEncodingTags)-1] {
+ case tagNumExpectedLaterEncodingBase64URL:
+ encoded := make([]byte, base64.RawURLEncoding.EncodedLen(len(src)))
+ base64.RawURLEncoding.Encode(encoded, src)
+ return encoded, true, nil
+
+ case tagNumExpectedLaterEncodingBase64:
+ encoded := make([]byte, base64.StdEncoding.EncodedLen(len(src)))
+ base64.StdEncoding.Encode(encoded, src)
+ return encoded, true, nil
+
+ case tagNumExpectedLaterEncodingBase16:
+ encoded := make([]byte, hex.EncodedLen(len(src)))
+ hex.Encode(encoded, src)
+ return encoded, true, nil
+
+ default:
+ // If this happens, there is a bug: the decoder has pushed an invalid
+ // "expected later encoding" tag to the stack.
+ panic(fmt.Sprintf("unrecognized expected later encoding tag: %d", d.expectedLaterEncodingTags))
+ }
+
+ case reflect.Slice:
+ if dstType.Elem().Kind() != reflect.Uint8 || len(d.expectedLaterEncodingTags) > 0 {
+ // Either the destination is not a slice of bytes, or the encoder that
+ // produced the input indicated an expected text encoding tag and therefore
+ // the content of the byte string has NOT been text encoded.
+ return src, false, nil
+ }
+
+ switch d.dm.byteStringExpectedFormat {
+ case ByteStringExpectedBase64URL:
+ decoded := make([]byte, base64.RawURLEncoding.DecodedLen(len(src)))
+ n, err := base64.RawURLEncoding.Decode(decoded, src)
+ if err != nil {
+ return nil, false, newByteStringExpectedFormatError(ByteStringExpectedBase64URL, err)
+ }
+ return decoded[:n], true, nil
+
+ case ByteStringExpectedBase64:
+ decoded := make([]byte, base64.StdEncoding.DecodedLen(len(src)))
+ n, err := base64.StdEncoding.Decode(decoded, src)
+ if err != nil {
+ return nil, false, newByteStringExpectedFormatError(ByteStringExpectedBase64, err)
+ }
+ return decoded[:n], true, nil
+
+ case ByteStringExpectedBase16:
+ decoded := make([]byte, hex.DecodedLen(len(src)))
+ n, err := hex.Decode(decoded, src)
+ if err != nil {
+ return nil, false, newByteStringExpectedFormatError(ByteStringExpectedBase16, err)
+ }
+ return decoded[:n], true, nil
+ }
+ }
+
+ return src, false, nil
+}
+
+// parseTextString parses CBOR encoded text string. It returns a byte slice
+// to prevent creating an extra copy of string. Caller should wrap returned
+// byte slice as string when needed.
+func (d *decoder) parseTextString() ([]byte, error) {
+ _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag()
+ if !indefiniteLength {
+ b := d.data[d.off : d.off+int(val)]
+ d.off += int(val)
+ if d.dm.utf8 == UTF8RejectInvalid && !utf8.Valid(b) {
+ return nil, &SemanticError{"cbor: invalid UTF-8 string"}
+ }
+ return b, nil
+ }
+ // Process indefinite length string chunks.
+ b := []byte{}
+ for !d.foundBreak() {
+ _, _, val = d.getHead()
+ x := d.data[d.off : d.off+int(val)]
+ d.off += int(val)
+ if d.dm.utf8 == UTF8RejectInvalid && !utf8.Valid(x) {
+ for !d.foundBreak() {
+ d.skip() // Skip remaining chunk on error
+ }
+ return nil, &SemanticError{"cbor: invalid UTF-8 string"}
+ }
+ b = append(b, x...)
+ }
+ return b, nil
+}
+
+func (d *decoder) parseArray() ([]interface{}, error) {
+ _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag()
+ hasSize := !indefiniteLength
+ count := int(val)
+ if !hasSize {
+ count = d.numOfItemsUntilBreak() // peek ahead to get array size to preallocate slice for better performance
+ }
+ v := make([]interface{}, count)
+ var e interface{}
+ var err, lastErr error
+ for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ {
+ if e, lastErr = d.parse(true); lastErr != nil {
+ if err == nil {
+ err = lastErr
+ }
+ continue
+ }
+ v[i] = e
+ }
+ return v, err
+}
+
+func (d *decoder) parseArrayToSlice(v reflect.Value, tInfo *typeInfo) error {
+ _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag()
+ hasSize := !indefiniteLength
+ count := int(val)
+ if !hasSize {
+ count = d.numOfItemsUntilBreak() // peek ahead to get array size to preallocate slice for better performance
+ }
+ if v.IsNil() || v.Cap() < count || count == 0 {
+ v.Set(reflect.MakeSlice(tInfo.nonPtrType, count, count))
+ }
+ v.SetLen(count)
+ var err error
+ for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ {
+ if lastErr := d.parseToValue(v.Index(i), tInfo.elemTypeInfo); lastErr != nil {
+ if err == nil {
+ err = lastErr
+ }
+ }
+ }
+ return err
+}
+
+func (d *decoder) parseArrayToArray(v reflect.Value, tInfo *typeInfo) error {
+ _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag()
+ hasSize := !indefiniteLength
+ count := int(val)
+ gi := 0
+ vLen := v.Len()
+ var err error
+ for ci := 0; (hasSize && ci < count) || (!hasSize && !d.foundBreak()); ci++ {
+ if gi < vLen {
+ // Read CBOR array element and set array element
+ if lastErr := d.parseToValue(v.Index(gi), tInfo.elemTypeInfo); lastErr != nil {
+ if err == nil {
+ err = lastErr
+ }
+ }
+ gi++
+ } else {
+ d.skip() // Skip remaining CBOR array element
+ }
+ }
+ // Set remaining Go array elements to zero values.
+ if gi < vLen {
+ zeroV := reflect.Zero(tInfo.elemTypeInfo.typ)
+ for ; gi < vLen; gi++ {
+ v.Index(gi).Set(zeroV)
+ }
+ }
+ return err
+}
+
+func (d *decoder) parseMap() (interface{}, error) {
+ _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag()
+ hasSize := !indefiniteLength
+ count := int(val)
+ m := make(map[interface{}]interface{})
+ var k, e interface{}
+ var err, lastErr error
+ keyCount := 0
+ for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ {
+ // Parse CBOR map key.
+ if k, lastErr = d.parse(true); lastErr != nil {
+ if err == nil {
+ err = lastErr
+ }
+ d.skip()
+ continue
+ }
+
+ // Detect if CBOR map key can be used as Go map key.
+ rv := reflect.ValueOf(k)
+ if !isHashableValue(rv) {
+ var converted bool
+ if d.dm.mapKeyByteString == MapKeyByteStringAllowed {
+ k, converted = convertByteSliceToByteString(k)
+ }
+ if !converted {
+ if err == nil {
+ err = &InvalidMapKeyTypeError{rv.Type().String()}
+ }
+ d.skip()
+ continue
+ }
+ }
+
+ // Parse CBOR map value.
+ if e, lastErr = d.parse(true); lastErr != nil {
+ if err == nil {
+ err = lastErr
+ }
+ continue
+ }
+
+ // Add key-value pair to Go map.
+ m[k] = e
+
+ // Detect duplicate map key.
+ if d.dm.dupMapKey == DupMapKeyEnforcedAPF {
+ newKeyCount := len(m)
+ if newKeyCount == keyCount {
+ m[k] = nil
+ err = &DupMapKeyError{k, i}
+ i++
+ // skip the rest of the map
+ for ; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ {
+ d.skip() // Skip map key
+ d.skip() // Skip map value
+ }
+ return m, err
+ }
+ keyCount = newKeyCount
+ }
+ }
+ return m, err
+}
+
+func (d *decoder) parseMapToMap(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo
+ _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag()
+ hasSize := !indefiniteLength
+ count := int(val)
+ if v.IsNil() {
+ mapsize := count
+ if !hasSize {
+ mapsize = 0
+ }
+ v.Set(reflect.MakeMapWithSize(tInfo.nonPtrType, mapsize))
+ }
+ keyType, eleType := tInfo.keyTypeInfo.typ, tInfo.elemTypeInfo.typ
+ reuseKey, reuseEle := isImmutableKind(tInfo.keyTypeInfo.kind), isImmutableKind(tInfo.elemTypeInfo.kind)
+ var keyValue, eleValue, zeroKeyValue, zeroEleValue reflect.Value
+ keyIsInterfaceType := keyType == typeIntf // If key type is interface{}, need to check if key value is hashable.
+ var err, lastErr error
+ keyCount := v.Len()
+ var existingKeys map[interface{}]bool // Store existing map keys, used for detecting duplicate map key.
+ if d.dm.dupMapKey == DupMapKeyEnforcedAPF {
+ existingKeys = make(map[interface{}]bool, keyCount)
+ if keyCount > 0 {
+ vKeys := v.MapKeys()
+ for i := 0; i < len(vKeys); i++ {
+ existingKeys[vKeys[i].Interface()] = true
+ }
+ }
+ }
+ for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ {
+ // Parse CBOR map key.
+ if !keyValue.IsValid() {
+ keyValue = reflect.New(keyType).Elem()
+ } else if !reuseKey {
+ if !zeroKeyValue.IsValid() {
+ zeroKeyValue = reflect.Zero(keyType)
+ }
+ keyValue.Set(zeroKeyValue)
+ }
+ if lastErr = d.parseToValue(keyValue, tInfo.keyTypeInfo); lastErr != nil {
+ if err == nil {
+ err = lastErr
+ }
+ d.skip()
+ continue
+ }
+
+ // Detect if CBOR map key can be used as Go map key.
+ if keyIsInterfaceType && keyValue.Elem().IsValid() {
+ if !isHashableValue(keyValue.Elem()) {
+ var converted bool
+ if d.dm.mapKeyByteString == MapKeyByteStringAllowed {
+ var k interface{}
+ k, converted = convertByteSliceToByteString(keyValue.Elem().Interface())
+ if converted {
+ keyValue.Set(reflect.ValueOf(k))
+ }
+ }
+ if !converted {
+ if err == nil {
+ err = &InvalidMapKeyTypeError{keyValue.Elem().Type().String()}
+ }
+ d.skip()
+ continue
+ }
+ }
+ }
+
+ // Parse CBOR map value.
+ if !eleValue.IsValid() {
+ eleValue = reflect.New(eleType).Elem()
+ } else if !reuseEle {
+ if !zeroEleValue.IsValid() {
+ zeroEleValue = reflect.Zero(eleType)
+ }
+ eleValue.Set(zeroEleValue)
+ }
+ if lastErr := d.parseToValue(eleValue, tInfo.elemTypeInfo); lastErr != nil {
+ if err == nil {
+ err = lastErr
+ }
+ continue
+ }
+
+ // Add key-value pair to Go map.
+ v.SetMapIndex(keyValue, eleValue)
+
+ // Detect duplicate map key.
+ if d.dm.dupMapKey == DupMapKeyEnforcedAPF {
+ newKeyCount := v.Len()
+ if newKeyCount == keyCount {
+ kvi := keyValue.Interface()
+ if !existingKeys[kvi] {
+ v.SetMapIndex(keyValue, reflect.New(eleType).Elem())
+ err = &DupMapKeyError{kvi, i}
+ i++
+ // skip the rest of the map
+ for ; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ {
+ d.skip() // skip map key
+ d.skip() // skip map value
+ }
+ return err
+ }
+ delete(existingKeys, kvi)
+ }
+ keyCount = newKeyCount
+ }
+ }
+ return err
+}
+
+func (d *decoder) parseArrayToStruct(v reflect.Value, tInfo *typeInfo) error {
+ structType := getDecodingStructType(tInfo.nonPtrType)
+ if structType.err != nil {
+ return structType.err
+ }
+
+ if !structType.toArray {
+ t := d.nextCBORType()
+ d.skip()
+ return &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: tInfo.nonPtrType.String(),
+ errorMsg: "cannot decode CBOR array to struct without toarray option",
+ }
+ }
+
+ start := d.off
+ _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag()
+ hasSize := !indefiniteLength
+ count := int(val)
+ if !hasSize {
+ count = d.numOfItemsUntilBreak() // peek ahead to get array size
+ }
+ if count != len(structType.fields) {
+ d.off = start
+ d.skip()
+ return &UnmarshalTypeError{
+ CBORType: cborTypeArray.String(),
+ GoType: tInfo.typ.String(),
+ errorMsg: "cannot decode CBOR array to struct with different number of elements",
+ }
+ }
+ var err, lastErr error
+ for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ {
+ f := structType.fields[i]
+
+ // Get field value by index
+ var fv reflect.Value
+ if len(f.idx) == 1 {
+ fv = v.Field(f.idx[0])
+ } else {
+ fv, lastErr = getFieldValue(v, f.idx, func(v reflect.Value) (reflect.Value, error) {
+ // Return a new value for embedded field null pointer to point to, or return error.
+ if !v.CanSet() {
+ return reflect.Value{}, errors.New("cbor: cannot set embedded pointer to unexported struct: " + v.Type().String())
+ }
+ v.Set(reflect.New(v.Type().Elem()))
+ return v, nil
+ })
+ if lastErr != nil && err == nil {
+ err = lastErr
+ }
+ if !fv.IsValid() {
+ d.skip()
+ continue
+ }
+ }
+
+ if lastErr = d.parseToValue(fv, f.typInfo); lastErr != nil {
+ if err == nil {
+ if typeError, ok := lastErr.(*UnmarshalTypeError); ok {
+ typeError.StructFieldName = tInfo.typ.String() + "." + f.name
+ err = typeError
+ } else {
+ err = lastErr
+ }
+ }
+ }
+ }
+ return err
+}
+
+// parseMapToStruct needs to be fast so gocyclo can be ignored for now.
+func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo
+ structType := getDecodingStructType(tInfo.nonPtrType)
+ if structType.err != nil {
+ return structType.err
+ }
+
+ if structType.toArray {
+ t := d.nextCBORType()
+ d.skip()
+ return &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: tInfo.nonPtrType.String(),
+ errorMsg: "cannot decode CBOR map to struct with toarray option",
+ }
+ }
+
+ var err, lastErr error
+
+ // Get CBOR map size
+ _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag()
+ hasSize := !indefiniteLength
+ count := int(val)
+
+ // Keeps track of matched struct fields
+ var foundFldIdx []bool
+ {
+ const maxStackFields = 128
+ if nfields := len(structType.fields); nfields <= maxStackFields {
+ // For structs with typical field counts, expect that this can be
+ // stack-allocated.
+ var a [maxStackFields]bool
+ foundFldIdx = a[:nfields]
+ } else {
+ foundFldIdx = make([]bool, len(structType.fields))
+ }
+ }
+
+ // Keeps track of CBOR map keys to detect duplicate map key
+ keyCount := 0
+ var mapKeys map[interface{}]struct{}
+
+ errOnUnknownField := (d.dm.extraReturnErrors & ExtraDecErrorUnknownField) > 0
+
+MapEntryLoop:
+ for j := 0; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ {
+ var f *field
+
+ // If duplicate field detection is enabled and the key at index j did not match any
+ // field, k will hold the map key.
+ var k interface{}
+
+ t := d.nextCBORType()
+ if t == cborTypeTextString || (t == cborTypeByteString && d.dm.fieldNameByteString == FieldNameByteStringAllowed) {
+ var keyBytes []byte
+ if t == cborTypeTextString {
+ keyBytes, lastErr = d.parseTextString()
+ if lastErr != nil {
+ if err == nil {
+ err = lastErr
+ }
+ d.skip() // skip value
+ continue
+ }
+ } else { // cborTypeByteString
+ keyBytes, _ = d.parseByteString()
+ }
+
+ // Check for exact match on field name.
+ if i, ok := structType.fieldIndicesByName[string(keyBytes)]; ok {
+ fld := structType.fields[i]
+
+ if !foundFldIdx[i] {
+ f = fld
+ foundFldIdx[i] = true
+ } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF {
+ err = &DupMapKeyError{fld.name, j}
+ d.skip() // skip value
+ j++
+ // skip the rest of the map
+ for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ {
+ d.skip()
+ d.skip()
+ }
+ return err
+ } else {
+ // discard repeated match
+ d.skip()
+ continue MapEntryLoop
+ }
+ }
+
+ // Find field with case-insensitive match
+ if f == nil && d.dm.fieldNameMatching == FieldNameMatchingPreferCaseSensitive {
+ keyLen := len(keyBytes)
+ keyString := string(keyBytes)
+ for i := 0; i < len(structType.fields); i++ {
+ fld := structType.fields[i]
+ if len(fld.name) == keyLen && strings.EqualFold(fld.name, keyString) {
+ if !foundFldIdx[i] {
+ f = fld
+ foundFldIdx[i] = true
+ } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF {
+ err = &DupMapKeyError{keyString, j}
+ d.skip() // skip value
+ j++
+ // skip the rest of the map
+ for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ {
+ d.skip()
+ d.skip()
+ }
+ return err
+ } else {
+ // discard repeated match
+ d.skip()
+ continue MapEntryLoop
+ }
+ break
+ }
+ }
+ }
+
+ if d.dm.dupMapKey == DupMapKeyEnforcedAPF && f == nil {
+ k = string(keyBytes)
+ }
+ } else if t <= cborTypeNegativeInt { // uint/int
+ var nameAsInt int64
+
+ if t == cborTypePositiveInt {
+ _, _, val := d.getHead()
+ nameAsInt = int64(val)
+ } else {
+ _, _, val := d.getHead()
+ if val > math.MaxInt64 {
+ if err == nil {
+ err = &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: reflect.TypeOf(int64(0)).String(),
+ errorMsg: "-1-" + strconv.FormatUint(val, 10) + " overflows Go's int64",
+ }
+ }
+ d.skip() // skip value
+ continue
+ }
+ nameAsInt = int64(-1) ^ int64(val)
+ }
+
+ // Find field
+ for i := 0; i < len(structType.fields); i++ {
+ fld := structType.fields[i]
+ if fld.keyAsInt && fld.nameAsInt == nameAsInt {
+ if !foundFldIdx[i] {
+ f = fld
+ foundFldIdx[i] = true
+ } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF {
+ err = &DupMapKeyError{nameAsInt, j}
+ d.skip() // skip value
+ j++
+ // skip the rest of the map
+ for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ {
+ d.skip()
+ d.skip()
+ }
+ return err
+ } else {
+ // discard repeated match
+ d.skip()
+ continue MapEntryLoop
+ }
+ break
+ }
+ }
+
+ if d.dm.dupMapKey == DupMapKeyEnforcedAPF && f == nil {
+ k = nameAsInt
+ }
+ } else {
+ if err == nil {
+ err = &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: reflect.TypeOf("").String(),
+ errorMsg: "map key is of type " + t.String() + " and cannot be used to match struct field name",
+ }
+ }
+ if d.dm.dupMapKey == DupMapKeyEnforcedAPF {
+ // parse key
+ k, lastErr = d.parse(true)
+ if lastErr != nil {
+ d.skip() // skip value
+ continue
+ }
+ // Detect if CBOR map key can be used as Go map key.
+ if !isHashableValue(reflect.ValueOf(k)) {
+ d.skip() // skip value
+ continue
+ }
+ } else {
+ d.skip() // skip key
+ }
+ }
+
+ if f == nil {
+ if errOnUnknownField {
+ err = &UnknownFieldError{j}
+ d.skip() // Skip value
+ j++
+ // skip the rest of the map
+ for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ {
+ d.skip()
+ d.skip()
+ }
+ return err
+ }
+
+ // Two map keys that match the same struct field are immediately considered
+ // duplicates. This check detects duplicates between two map keys that do
+ // not match a struct field. If unknown field errors are enabled, then this
+ // check is never reached.
+ if d.dm.dupMapKey == DupMapKeyEnforcedAPF {
+ if mapKeys == nil {
+ mapKeys = make(map[interface{}]struct{}, 1)
+ }
+ mapKeys[k] = struct{}{}
+ newKeyCount := len(mapKeys)
+ if newKeyCount == keyCount {
+ err = &DupMapKeyError{k, j}
+ d.skip() // skip value
+ j++
+ // skip the rest of the map
+ for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ {
+ d.skip()
+ d.skip()
+ }
+ return err
+ }
+ keyCount = newKeyCount
+ }
+
+ d.skip() // Skip value
+ continue
+ }
+
+ // Get field value by index
+ var fv reflect.Value
+ if len(f.idx) == 1 {
+ fv = v.Field(f.idx[0])
+ } else {
+ fv, lastErr = getFieldValue(v, f.idx, func(v reflect.Value) (reflect.Value, error) {
+ // Return a new value for embedded field null pointer to point to, or return error.
+ if !v.CanSet() {
+ return reflect.Value{}, errors.New("cbor: cannot set embedded pointer to unexported struct: " + v.Type().String())
+ }
+ v.Set(reflect.New(v.Type().Elem()))
+ return v, nil
+ })
+ if lastErr != nil && err == nil {
+ err = lastErr
+ }
+ if !fv.IsValid() {
+ d.skip()
+ continue
+ }
+ }
+
+ if lastErr = d.parseToValue(fv, f.typInfo); lastErr != nil {
+ if err == nil {
+ if typeError, ok := lastErr.(*UnmarshalTypeError); ok {
+ typeError.StructFieldName = tInfo.nonPtrType.String() + "." + f.name
+ err = typeError
+ } else {
+ err = lastErr
+ }
+ }
+ }
+ }
+ return err
+}
+
+// validRegisteredTagNums verifies that tag numbers match registered tag numbers of type t.
+// validRegisteredTagNums assumes next CBOR data type is tag. It scans all tag numbers, and stops at tag content.
+func (d *decoder) validRegisteredTagNums(registeredTag *tagItem) error {
+ // Scan until next cbor data is tag content.
+ tagNums := make([]uint64, 0, 1)
+ for d.nextCBORType() == cborTypeTag {
+ _, _, val := d.getHead()
+ tagNums = append(tagNums, val)
+ }
+
+ if !registeredTag.equalTagNum(tagNums) {
+ return &WrongTagError{registeredTag.contentType, registeredTag.num, tagNums}
+ }
+ return nil
+}
+
+func (d *decoder) getRegisteredTagItem(vt reflect.Type) *tagItem {
+ if d.dm.tags != nil {
+ return d.dm.tags.getTagItemFromType(vt)
+ }
+ return nil
+}
+
+// skip moves data offset to the next item. skip assumes data is well-formed,
+// and does not perform bounds checking.
+func (d *decoder) skip() {
+ t, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag()
+
+ if indefiniteLength {
+ switch t {
+ case cborTypeByteString, cborTypeTextString, cborTypeArray, cborTypeMap:
+ for {
+ if isBreakFlag(d.data[d.off]) {
+ d.off++
+ return
+ }
+ d.skip()
+ }
+ }
+ }
+
+ switch t {
+ case cborTypeByteString, cborTypeTextString:
+ d.off += int(val)
+
+ case cborTypeArray:
+ for i := 0; i < int(val); i++ {
+ d.skip()
+ }
+
+ case cborTypeMap:
+ for i := 0; i < int(val)*2; i++ {
+ d.skip()
+ }
+
+ case cborTypeTag:
+ d.skip()
+ }
+}
+
+func (d *decoder) getHeadWithIndefiniteLengthFlag() (
+ t cborType,
+ ai byte,
+ val uint64,
+ indefiniteLength bool,
+) {
+ t, ai, val = d.getHead()
+ indefiniteLength = additionalInformation(ai).isIndefiniteLength()
+ return
+}
+
+// getHead assumes data is well-formed, and does not perform bounds checking.
+func (d *decoder) getHead() (t cborType, ai byte, val uint64) {
+ t, ai = parseInitialByte(d.data[d.off])
+ val = uint64(ai)
+ d.off++
+
+ if ai <= maxAdditionalInformationWithoutArgument {
+ return
+ }
+
+ if ai == additionalInformationWith1ByteArgument {
+ val = uint64(d.data[d.off])
+ d.off++
+ return
+ }
+
+ if ai == additionalInformationWith2ByteArgument {
+ const argumentSize = 2
+ val = uint64(binary.BigEndian.Uint16(d.data[d.off : d.off+argumentSize]))
+ d.off += argumentSize
+ return
+ }
+
+ if ai == additionalInformationWith4ByteArgument {
+ const argumentSize = 4
+ val = uint64(binary.BigEndian.Uint32(d.data[d.off : d.off+argumentSize]))
+ d.off += argumentSize
+ return
+ }
+
+ if ai == additionalInformationWith8ByteArgument {
+ const argumentSize = 8
+ val = binary.BigEndian.Uint64(d.data[d.off : d.off+argumentSize])
+ d.off += argumentSize
+ return
+ }
+ return
+}
+
+func (d *decoder) numOfItemsUntilBreak() int {
+ savedOff := d.off
+ i := 0
+ for !d.foundBreak() {
+ d.skip()
+ i++
+ }
+ d.off = savedOff
+ return i
+}
+
+// foundBreak returns true if next byte is CBOR break code and moves cursor by 1,
+// otherwise it returns false.
+// foundBreak assumes data is well-formed, and does not perform bounds checking.
+func (d *decoder) foundBreak() bool {
+ if isBreakFlag(d.data[d.off]) {
+ d.off++
+ return true
+ }
+ return false
+}
+
+func (d *decoder) reset(data []byte) {
+ d.data = data
+ d.off = 0
+ d.expectedLaterEncodingTags = d.expectedLaterEncodingTags[:0]
+}
+
+func (d *decoder) nextCBORType() cborType {
+ return getType(d.data[d.off])
+}
+
+func (d *decoder) nextCBORNil() bool {
+ return d.data[d.off] == 0xf6 || d.data[d.off] == 0xf7
+}
+
+var (
+ typeIntf = reflect.TypeOf([]interface{}(nil)).Elem()
+ typeTime = reflect.TypeOf(time.Time{})
+ typeBigInt = reflect.TypeOf(big.Int{})
+ typeUnmarshaler = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
+ typeBinaryUnmarshaler = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem()
+ typeString = reflect.TypeOf("")
+ typeByteSlice = reflect.TypeOf([]byte(nil))
+)
+
+func fillNil(_ cborType, v reflect.Value) error {
+ switch v.Kind() {
+ case reflect.Slice, reflect.Map, reflect.Interface, reflect.Ptr:
+ v.Set(reflect.Zero(v.Type()))
+ return nil
+ }
+ return nil
+}
+
+func fillPositiveInt(t cborType, val uint64, v reflect.Value) error {
+ switch v.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ if val > math.MaxInt64 {
+ return &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: v.Type().String(),
+ errorMsg: strconv.FormatUint(val, 10) + " overflows " + v.Type().String(),
+ }
+ }
+ if v.OverflowInt(int64(val)) {
+ return &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: v.Type().String(),
+ errorMsg: strconv.FormatUint(val, 10) + " overflows " + v.Type().String(),
+ }
+ }
+ v.SetInt(int64(val))
+ return nil
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ if v.OverflowUint(val) {
+ return &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: v.Type().String(),
+ errorMsg: strconv.FormatUint(val, 10) + " overflows " + v.Type().String(),
+ }
+ }
+ v.SetUint(val)
+ return nil
+
+ case reflect.Float32, reflect.Float64:
+ f := float64(val)
+ v.SetFloat(f)
+ return nil
+ }
+
+ if v.Type() == typeBigInt {
+ i := new(big.Int).SetUint64(val)
+ v.Set(reflect.ValueOf(*i))
+ return nil
+ }
+ return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()}
+}
+
+func fillNegativeInt(t cborType, val int64, v reflect.Value) error {
+ switch v.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ if v.OverflowInt(val) {
+ return &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: v.Type().String(),
+ errorMsg: strconv.FormatInt(val, 10) + " overflows " + v.Type().String(),
+ }
+ }
+ v.SetInt(val)
+ return nil
+
+ case reflect.Float32, reflect.Float64:
+ f := float64(val)
+ v.SetFloat(f)
+ return nil
+ }
+ if v.Type() == typeBigInt {
+ i := new(big.Int).SetInt64(val)
+ v.Set(reflect.ValueOf(*i))
+ return nil
+ }
+ return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()}
+}
+
+func fillBool(t cborType, val bool, v reflect.Value) error {
+ if v.Kind() == reflect.Bool {
+ v.SetBool(val)
+ return nil
+ }
+ return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()}
+}
+
+func fillFloat(t cborType, val float64, v reflect.Value) error {
+ switch v.Kind() {
+ case reflect.Float32, reflect.Float64:
+ if v.OverflowFloat(val) {
+ return &UnmarshalTypeError{
+ CBORType: t.String(),
+ GoType: v.Type().String(),
+ errorMsg: strconv.FormatFloat(val, 'E', -1, 64) + " overflows " + v.Type().String(),
+ }
+ }
+ v.SetFloat(val)
+ return nil
+ }
+ return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()}
+}
+
+func fillByteString(t cborType, val []byte, shared bool, v reflect.Value, bsts ByteStringToStringMode, bum BinaryUnmarshalerMode) error {
+ if bum == BinaryUnmarshalerByteString && reflect.PtrTo(v.Type()).Implements(typeBinaryUnmarshaler) {
+ if v.CanAddr() {
+ v = v.Addr()
+ if u, ok := v.Interface().(encoding.BinaryUnmarshaler); ok {
+ // The contract of BinaryUnmarshaler forbids
+ // retaining the input bytes, so no copying is
+ // required even if val is shared.
+ return u.UnmarshalBinary(val)
+ }
+ }
+ return errors.New("cbor: cannot set new value for " + v.Type().String())
+ }
+ if bsts != ByteStringToStringForbidden && v.Kind() == reflect.String {
+ v.SetString(string(val))
+ return nil
+ }
+ if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 {
+ src := val
+ if shared {
+ // SetBytes shares the underlying bytes of the source slice.
+ src = make([]byte, len(val))
+ copy(src, val)
+ }
+ v.SetBytes(src)
+ return nil
+ }
+ if v.Kind() == reflect.Array && v.Type().Elem().Kind() == reflect.Uint8 {
+ vLen := v.Len()
+ i := 0
+ for ; i < vLen && i < len(val); i++ {
+ v.Index(i).SetUint(uint64(val[i]))
+ }
+ // Set remaining Go array elements to zero values.
+ if i < vLen {
+ zeroV := reflect.Zero(reflect.TypeOf(byte(0)))
+ for ; i < vLen; i++ {
+ v.Index(i).Set(zeroV)
+ }
+ }
+ return nil
+ }
+ return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()}
+}
+
+func fillTextString(t cborType, val []byte, v reflect.Value) error {
+ if v.Kind() == reflect.String {
+ v.SetString(string(val))
+ return nil
+ }
+ return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()}
+}
+
+func isImmutableKind(k reflect.Kind) bool {
+ switch k {
+ case reflect.Bool,
+ reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+ reflect.Float32, reflect.Float64,
+ reflect.String:
+ return true
+
+ default:
+ return false
+ }
+}
+
+func isHashableValue(rv reflect.Value) bool {
+ switch rv.Kind() {
+ case reflect.Slice, reflect.Map, reflect.Func:
+ return false
+
+ case reflect.Struct:
+ switch rv.Type() {
+ case typeTag:
+ tag := rv.Interface().(Tag)
+ return isHashableValue(reflect.ValueOf(tag.Content))
+ case typeBigInt:
+ return false
+ }
+ }
+ return true
+}
+
+// convertByteSliceToByteString converts []byte to ByteString if
+// - v is []byte type, or
+// - v is Tag type and tag content type is []byte
+// This function also handles nested tags.
+// CBOR data is already verified to be well-formed before this function is used,
+// so the recursion won't exceed max nested levels.
+func convertByteSliceToByteString(v interface{}) (interface{}, bool) {
+ switch v := v.(type) {
+ case []byte:
+ return ByteString(v), true
+
+ case Tag:
+ content, converted := convertByteSliceToByteString(v.Content)
+ if converted {
+ return Tag{Number: v.Number, Content: content}, true
+ }
+ }
+ return v, false
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/diagnose.go b/vendor/github.com/fxamacker/cbor/v2/diagnose.go
new file mode 100644
index 000000000..44afb8660
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/diagnose.go
@@ -0,0 +1,724 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+package cbor
+
+import (
+ "bytes"
+ "encoding/base32"
+ "encoding/base64"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "math/big"
+ "strconv"
+ "unicode/utf16"
+ "unicode/utf8"
+
+ "github.com/x448/float16"
+)
+
+// DiagMode is the main interface for CBOR diagnostic notation.
+type DiagMode interface {
+ // Diagnose returns extended diagnostic notation (EDN) of CBOR data items using this DiagMode.
+ Diagnose([]byte) (string, error)
+
+ // DiagnoseFirst returns extended diagnostic notation (EDN) of the first CBOR data item using the DiagMode. Any remaining bytes are returned in rest.
+ DiagnoseFirst([]byte) (string, []byte, error)
+
+ // DiagOptions returns user specified options used to create this DiagMode.
+ DiagOptions() DiagOptions
+}
+
+// ByteStringEncoding specifies the base encoding that byte strings are notated.
+type ByteStringEncoding uint8
+
+const (
+ // ByteStringBase16Encoding encodes byte strings in base16, without padding.
+ ByteStringBase16Encoding ByteStringEncoding = iota
+
+ // ByteStringBase32Encoding encodes byte strings in base32, without padding.
+ ByteStringBase32Encoding
+
+ // ByteStringBase32HexEncoding encodes byte strings in base32hex, without padding.
+ ByteStringBase32HexEncoding
+
+ // ByteStringBase64Encoding encodes byte strings in base64url, without padding.
+ ByteStringBase64Encoding
+
+ maxByteStringEncoding
+)
+
+func (bse ByteStringEncoding) valid() error {
+ if bse >= maxByteStringEncoding {
+ return errors.New("cbor: invalid ByteStringEncoding " + strconv.Itoa(int(bse)))
+ }
+ return nil
+}
+
+// DiagOptions specifies Diag options.
+type DiagOptions struct {
+ // ByteStringEncoding specifies the base encoding that byte strings are notated.
+ // Default is ByteStringBase16Encoding.
+ ByteStringEncoding ByteStringEncoding
+
+ // ByteStringHexWhitespace specifies notating with whitespace in byte string
+ // when ByteStringEncoding is ByteStringBase16Encoding.
+ ByteStringHexWhitespace bool
+
+ // ByteStringText specifies notating with text in byte string
+ // if it is a valid UTF-8 text.
+ ByteStringText bool
+
+ // ByteStringEmbeddedCBOR specifies notating embedded CBOR in byte string
+ // if it is a valid CBOR bytes.
+ ByteStringEmbeddedCBOR bool
+
+ // CBORSequence specifies notating CBOR sequences.
+ // otherwise, it returns an error if there are more bytes after the first CBOR.
+ CBORSequence bool
+
+ // FloatPrecisionIndicator specifies appending a suffix to indicate float precision.
+ // Refer to https://www.rfc-editor.org/rfc/rfc8949.html#name-encoding-indicators.
+ FloatPrecisionIndicator bool
+
+ // MaxNestedLevels specifies the max nested levels allowed for any combination of CBOR array, maps, and tags.
+ // Default is 32 levels and it can be set to [4, 65535]. Note that higher maximum levels of nesting can
+ // require larger amounts of stack to deserialize. Don't increase this higher than you require.
+ MaxNestedLevels int
+
+ // MaxArrayElements specifies the max number of elements for CBOR arrays.
+ // Default is 128*1024=131072 and it can be set to [16, 2147483647]
+ MaxArrayElements int
+
+ // MaxMapPairs specifies the max number of key-value pairs for CBOR maps.
+ // Default is 128*1024=131072 and it can be set to [16, 2147483647]
+ MaxMapPairs int
+}
+
+// DiagMode returns a DiagMode with immutable options.
+func (opts DiagOptions) DiagMode() (DiagMode, error) {
+ return opts.diagMode()
+}
+
+func (opts DiagOptions) diagMode() (*diagMode, error) {
+ if err := opts.ByteStringEncoding.valid(); err != nil {
+ return nil, err
+ }
+
+ decMode, err := DecOptions{
+ MaxNestedLevels: opts.MaxNestedLevels,
+ MaxArrayElements: opts.MaxArrayElements,
+ MaxMapPairs: opts.MaxMapPairs,
+ }.decMode()
+ if err != nil {
+ return nil, err
+ }
+
+ return &diagMode{
+ byteStringEncoding: opts.ByteStringEncoding,
+ byteStringHexWhitespace: opts.ByteStringHexWhitespace,
+ byteStringText: opts.ByteStringText,
+ byteStringEmbeddedCBOR: opts.ByteStringEmbeddedCBOR,
+ cborSequence: opts.CBORSequence,
+ floatPrecisionIndicator: opts.FloatPrecisionIndicator,
+ decMode: decMode,
+ }, nil
+}
+
+type diagMode struct {
+ byteStringEncoding ByteStringEncoding
+ byteStringHexWhitespace bool
+ byteStringText bool
+ byteStringEmbeddedCBOR bool
+ cborSequence bool
+ floatPrecisionIndicator bool
+ decMode *decMode
+}
+
+// DiagOptions returns user specified options used to create this DiagMode.
+func (dm *diagMode) DiagOptions() DiagOptions {
+ return DiagOptions{
+ ByteStringEncoding: dm.byteStringEncoding,
+ ByteStringHexWhitespace: dm.byteStringHexWhitespace,
+ ByteStringText: dm.byteStringText,
+ ByteStringEmbeddedCBOR: dm.byteStringEmbeddedCBOR,
+ CBORSequence: dm.cborSequence,
+ FloatPrecisionIndicator: dm.floatPrecisionIndicator,
+ MaxNestedLevels: dm.decMode.maxNestedLevels,
+ MaxArrayElements: dm.decMode.maxArrayElements,
+ MaxMapPairs: dm.decMode.maxMapPairs,
+ }
+}
+
+// Diagnose returns extended diagnostic notation (EDN) of CBOR data items using the DiagMode.
+func (dm *diagMode) Diagnose(data []byte) (string, error) {
+ return newDiagnose(data, dm.decMode, dm).diag(dm.cborSequence)
+}
+
+// DiagnoseFirst returns extended diagnostic notation (EDN) of the first CBOR data item using the DiagMode. Any remaining bytes are returned in rest.
+func (dm *diagMode) DiagnoseFirst(data []byte) (diagNotation string, rest []byte, err error) {
+ return newDiagnose(data, dm.decMode, dm).diagFirst()
+}
+
+var defaultDiagMode, _ = DiagOptions{}.diagMode()
+
+// Diagnose returns extended diagnostic notation (EDN) of CBOR data items
+// using the default diagnostic mode.
+//
+// Refer to https://www.rfc-editor.org/rfc/rfc8949.html#name-diagnostic-notation.
+func Diagnose(data []byte) (string, error) {
+ return defaultDiagMode.Diagnose(data)
+}
+
+// Diagnose returns extended diagnostic notation (EDN) of the first CBOR data item using the DiagMode. Any remaining bytes are returned in rest.
+func DiagnoseFirst(data []byte) (diagNotation string, rest []byte, err error) {
+ return defaultDiagMode.DiagnoseFirst(data)
+}
+
+type diagnose struct {
+ dm *diagMode
+ d *decoder
+ w *bytes.Buffer
+}
+
+func newDiagnose(data []byte, decm *decMode, diagm *diagMode) *diagnose {
+ return &diagnose{
+ dm: diagm,
+ d: &decoder{data: data, dm: decm},
+ w: &bytes.Buffer{},
+ }
+}
+
+func (di *diagnose) diag(cborSequence bool) (string, error) {
+ // CBOR Sequence
+ firstItem := true
+ for {
+ switch err := di.wellformed(cborSequence); err {
+ case nil:
+ if !firstItem {
+ di.w.WriteString(", ")
+ }
+ firstItem = false
+ if itemErr := di.item(); itemErr != nil {
+ return di.w.String(), itemErr
+ }
+
+ case io.EOF:
+ if firstItem {
+ return di.w.String(), err
+ }
+ return di.w.String(), nil
+
+ default:
+ return di.w.String(), err
+ }
+ }
+}
+
+func (di *diagnose) diagFirst() (diagNotation string, rest []byte, err error) {
+ err = di.wellformed(true)
+ if err == nil {
+ err = di.item()
+ }
+
+ if err == nil {
+ // Return EDN and the rest of the data slice (which might be len 0)
+ return di.w.String(), di.d.data[di.d.off:], nil
+ }
+
+ return di.w.String(), nil, err
+}
+
+func (di *diagnose) wellformed(allowExtraData bool) error {
+ off := di.d.off
+ err := di.d.wellformed(allowExtraData, false)
+ di.d.off = off
+ return err
+}
+
+func (di *diagnose) item() error { //nolint:gocyclo
+ initialByte := di.d.data[di.d.off]
+ switch initialByte {
+ case cborByteStringWithIndefiniteLengthHead,
+ cborTextStringWithIndefiniteLengthHead: // indefinite-length byte/text string
+ di.d.off++
+ if isBreakFlag(di.d.data[di.d.off]) {
+ di.d.off++
+ switch initialByte {
+ case cborByteStringWithIndefiniteLengthHead:
+ // indefinite-length bytes with no chunks.
+ di.w.WriteString(`''_`)
+ return nil
+ case cborTextStringWithIndefiniteLengthHead:
+ // indefinite-length text with no chunks.
+ di.w.WriteString(`""_`)
+ return nil
+ }
+ }
+
+ di.w.WriteString("(_ ")
+
+ i := 0
+ for !di.d.foundBreak() {
+ if i > 0 {
+ di.w.WriteString(", ")
+ }
+
+ i++
+ // wellformedIndefiniteString() already checked that the next item is a byte/text string.
+ if err := di.item(); err != nil {
+ return err
+ }
+ }
+
+ di.w.WriteByte(')')
+ return nil
+
+ case cborArrayWithIndefiniteLengthHead: // indefinite-length array
+ di.d.off++
+ di.w.WriteString("[_ ")
+
+ i := 0
+ for !di.d.foundBreak() {
+ if i > 0 {
+ di.w.WriteString(", ")
+ }
+
+ i++
+ if err := di.item(); err != nil {
+ return err
+ }
+ }
+
+ di.w.WriteByte(']')
+ return nil
+
+ case cborMapWithIndefiniteLengthHead: // indefinite-length map
+ di.d.off++
+ di.w.WriteString("{_ ")
+
+ i := 0
+ for !di.d.foundBreak() {
+ if i > 0 {
+ di.w.WriteString(", ")
+ }
+
+ i++
+ // key
+ if err := di.item(); err != nil {
+ return err
+ }
+
+ di.w.WriteString(": ")
+
+ // value
+ if err := di.item(); err != nil {
+ return err
+ }
+ }
+
+ di.w.WriteByte('}')
+ return nil
+ }
+
+ t := di.d.nextCBORType()
+ switch t {
+ case cborTypePositiveInt:
+ _, _, val := di.d.getHead()
+ di.w.WriteString(strconv.FormatUint(val, 10))
+ return nil
+
+ case cborTypeNegativeInt:
+ _, _, val := di.d.getHead()
+ if val > math.MaxInt64 {
+ // CBOR negative integer overflows int64, use big.Int to store value.
+ bi := new(big.Int)
+ bi.SetUint64(val)
+ bi.Add(bi, big.NewInt(1))
+ bi.Neg(bi)
+ di.w.WriteString(bi.String())
+ return nil
+ }
+
+ nValue := int64(-1) ^ int64(val)
+ di.w.WriteString(strconv.FormatInt(nValue, 10))
+ return nil
+
+ case cborTypeByteString:
+ b, _ := di.d.parseByteString()
+ return di.encodeByteString(b)
+
+ case cborTypeTextString:
+ b, err := di.d.parseTextString()
+ if err != nil {
+ return err
+ }
+ return di.encodeTextString(string(b), '"')
+
+ case cborTypeArray:
+ _, _, val := di.d.getHead()
+ count := int(val)
+ di.w.WriteByte('[')
+
+ for i := 0; i < count; i++ {
+ if i > 0 {
+ di.w.WriteString(", ")
+ }
+ if err := di.item(); err != nil {
+ return err
+ }
+ }
+ di.w.WriteByte(']')
+ return nil
+
+ case cborTypeMap:
+ _, _, val := di.d.getHead()
+ count := int(val)
+ di.w.WriteByte('{')
+
+ for i := 0; i < count; i++ {
+ if i > 0 {
+ di.w.WriteString(", ")
+ }
+ // key
+ if err := di.item(); err != nil {
+ return err
+ }
+ di.w.WriteString(": ")
+ // value
+ if err := di.item(); err != nil {
+ return err
+ }
+ }
+ di.w.WriteByte('}')
+ return nil
+
+ case cborTypeTag:
+ _, _, tagNum := di.d.getHead()
+ switch tagNum {
+ case tagNumUnsignedBignum:
+ if nt := di.d.nextCBORType(); nt != cborTypeByteString {
+ return newInadmissibleTagContentTypeError(
+ tagNumUnsignedBignum,
+ "byte string",
+ nt.String())
+ }
+
+ b, _ := di.d.parseByteString()
+ bi := new(big.Int).SetBytes(b)
+ di.w.WriteString(bi.String())
+ return nil
+
+ case tagNumNegativeBignum:
+ if nt := di.d.nextCBORType(); nt != cborTypeByteString {
+ return newInadmissibleTagContentTypeError(
+ tagNumNegativeBignum,
+ "byte string",
+ nt.String(),
+ )
+ }
+
+ b, _ := di.d.parseByteString()
+ bi := new(big.Int).SetBytes(b)
+ bi.Add(bi, big.NewInt(1))
+ bi.Neg(bi)
+ di.w.WriteString(bi.String())
+ return nil
+
+ default:
+ di.w.WriteString(strconv.FormatUint(tagNum, 10))
+ di.w.WriteByte('(')
+ if err := di.item(); err != nil {
+ return err
+ }
+ di.w.WriteByte(')')
+ return nil
+ }
+
+ case cborTypePrimitives:
+ _, ai, val := di.d.getHead()
+ switch ai {
+ case additionalInformationAsFalse:
+ di.w.WriteString("false")
+ return nil
+
+ case additionalInformationAsTrue:
+ di.w.WriteString("true")
+ return nil
+
+ case additionalInformationAsNull:
+ di.w.WriteString("null")
+ return nil
+
+ case additionalInformationAsUndefined:
+ di.w.WriteString("undefined")
+ return nil
+
+ case additionalInformationAsFloat16,
+ additionalInformationAsFloat32,
+ additionalInformationAsFloat64:
+ return di.encodeFloat(ai, val)
+
+ default:
+ di.w.WriteString("simple(")
+ di.w.WriteString(strconv.FormatUint(val, 10))
+ di.w.WriteByte(')')
+ return nil
+ }
+ }
+
+ return nil
+}
+
+// writeU16 format a rune as "\uxxxx"
+func (di *diagnose) writeU16(val rune) {
+ di.w.WriteString("\\u")
+ var in [2]byte
+ in[0] = byte(val >> 8)
+ in[1] = byte(val)
+ sz := hex.EncodedLen(len(in))
+ di.w.Grow(sz)
+ dst := di.w.Bytes()[di.w.Len() : di.w.Len()+sz]
+ hex.Encode(dst, in[:])
+ di.w.Write(dst)
+}
+
+var rawBase32Encoding = base32.StdEncoding.WithPadding(base32.NoPadding)
+var rawBase32HexEncoding = base32.HexEncoding.WithPadding(base32.NoPadding)
+
+func (di *diagnose) encodeByteString(val []byte) error {
+ if len(val) > 0 {
+ if di.dm.byteStringText && utf8.Valid(val) {
+ return di.encodeTextString(string(val), '\'')
+ }
+
+ if di.dm.byteStringEmbeddedCBOR {
+ di2 := newDiagnose(val, di.dm.decMode, di.dm)
+ // should always notating embedded CBOR sequence.
+ if str, err := di2.diag(true); err == nil {
+ di.w.WriteString("<<")
+ di.w.WriteString(str)
+ di.w.WriteString(">>")
+ return nil
+ }
+ }
+ }
+
+ switch di.dm.byteStringEncoding {
+ case ByteStringBase16Encoding:
+ di.w.WriteString("h'")
+ if di.dm.byteStringHexWhitespace {
+ sz := hex.EncodedLen(len(val))
+ if len(val) > 0 {
+ sz += len(val) - 1
+ }
+ di.w.Grow(sz)
+
+ dst := di.w.Bytes()[di.w.Len():]
+ for i := range val {
+ if i > 0 {
+ dst = append(dst, ' ')
+ }
+ hex.Encode(dst[len(dst):len(dst)+2], val[i:i+1])
+ dst = dst[:len(dst)+2]
+ }
+ di.w.Write(dst)
+ } else {
+ sz := hex.EncodedLen(len(val))
+ di.w.Grow(sz)
+ dst := di.w.Bytes()[di.w.Len() : di.w.Len()+sz]
+ hex.Encode(dst, val)
+ di.w.Write(dst)
+ }
+ di.w.WriteByte('\'')
+ return nil
+
+ case ByteStringBase32Encoding:
+ di.w.WriteString("b32'")
+ sz := rawBase32Encoding.EncodedLen(len(val))
+ di.w.Grow(sz)
+ dst := di.w.Bytes()[di.w.Len() : di.w.Len()+sz]
+ rawBase32Encoding.Encode(dst, val)
+ di.w.Write(dst)
+ di.w.WriteByte('\'')
+ return nil
+
+ case ByteStringBase32HexEncoding:
+ di.w.WriteString("h32'")
+ sz := rawBase32HexEncoding.EncodedLen(len(val))
+ di.w.Grow(sz)
+ dst := di.w.Bytes()[di.w.Len() : di.w.Len()+sz]
+ rawBase32HexEncoding.Encode(dst, val)
+ di.w.Write(dst)
+ di.w.WriteByte('\'')
+ return nil
+
+ case ByteStringBase64Encoding:
+ di.w.WriteString("b64'")
+ sz := base64.RawURLEncoding.EncodedLen(len(val))
+ di.w.Grow(sz)
+ dst := di.w.Bytes()[di.w.Len() : di.w.Len()+sz]
+ base64.RawURLEncoding.Encode(dst, val)
+ di.w.Write(dst)
+ di.w.WriteByte('\'')
+ return nil
+
+ default:
+ // It should not be possible for users to construct a *diagMode with an invalid byte
+ // string encoding.
+ panic(fmt.Sprintf("diagmode has invalid ByteStringEncoding %v", di.dm.byteStringEncoding))
+ }
+}
+
+const utf16SurrSelf = rune(0x10000)
+
+// quote should be either `'` or `"`
+func (di *diagnose) encodeTextString(val string, quote byte) error {
+ di.w.WriteByte(quote)
+
+ for i := 0; i < len(val); {
+ if b := val[i]; b < utf8.RuneSelf {
+ switch {
+ case b == '\t', b == '\n', b == '\r', b == '\\', b == quote:
+ di.w.WriteByte('\\')
+
+ switch b {
+ case '\t':
+ b = 't'
+ case '\n':
+ b = 'n'
+ case '\r':
+ b = 'r'
+ }
+ di.w.WriteByte(b)
+
+ case b >= ' ' && b <= '~':
+ di.w.WriteByte(b)
+
+ default:
+ di.writeU16(rune(b))
+ }
+
+ i++
+ continue
+ }
+
+ c, size := utf8.DecodeRuneInString(val[i:])
+ switch {
+ case c == utf8.RuneError:
+ return &SemanticError{"cbor: invalid UTF-8 string"}
+
+ case c < utf16SurrSelf:
+ di.writeU16(c)
+
+ default:
+ c1, c2 := utf16.EncodeRune(c)
+ di.writeU16(c1)
+ di.writeU16(c2)
+ }
+
+ i += size
+ }
+
+ di.w.WriteByte(quote)
+ return nil
+}
+
+func (di *diagnose) encodeFloat(ai byte, val uint64) error {
+ f64 := float64(0)
+ switch ai {
+ case additionalInformationAsFloat16:
+ f16 := float16.Frombits(uint16(val))
+ switch {
+ case f16.IsNaN():
+ di.w.WriteString("NaN")
+ return nil
+ case f16.IsInf(1):
+ di.w.WriteString("Infinity")
+ return nil
+ case f16.IsInf(-1):
+ di.w.WriteString("-Infinity")
+ return nil
+ default:
+ f64 = float64(f16.Float32())
+ }
+
+ case additionalInformationAsFloat32:
+ f32 := math.Float32frombits(uint32(val))
+ switch {
+ case f32 != f32:
+ di.w.WriteString("NaN")
+ return nil
+ case f32 > math.MaxFloat32:
+ di.w.WriteString("Infinity")
+ return nil
+ case f32 < -math.MaxFloat32:
+ di.w.WriteString("-Infinity")
+ return nil
+ default:
+ f64 = float64(f32)
+ }
+
+ case additionalInformationAsFloat64:
+ f64 = math.Float64frombits(val)
+ switch {
+ case f64 != f64:
+ di.w.WriteString("NaN")
+ return nil
+ case f64 > math.MaxFloat64:
+ di.w.WriteString("Infinity")
+ return nil
+ case f64 < -math.MaxFloat64:
+ di.w.WriteString("-Infinity")
+ return nil
+ }
+ }
+ // Use ES6 number to string conversion which should match most JSON generators.
+ // Inspired by https://github.com/golang/go/blob/4df10fba1687a6d4f51d7238a403f8f2298f6a16/src/encoding/json/encode.go#L585
+ const bitSize = 64
+ b := make([]byte, 0, 32)
+ if abs := math.Abs(f64); abs != 0 && (abs < 1e-6 || abs >= 1e21) {
+ b = strconv.AppendFloat(b, f64, 'e', -1, bitSize)
+ // clean up e-09 to e-9
+ n := len(b)
+ if n >= 4 && string(b[n-4:n-1]) == "e-0" {
+ b = append(b[:n-2], b[n-1])
+ }
+ } else {
+ b = strconv.AppendFloat(b, f64, 'f', -1, bitSize)
+ }
+
+ // add decimal point and trailing zero if needed
+ if bytes.IndexByte(b, '.') < 0 {
+ if i := bytes.IndexByte(b, 'e'); i < 0 {
+ b = append(b, '.', '0')
+ } else {
+ b = append(b[:i+2], b[i:]...)
+ b[i] = '.'
+ b[i+1] = '0'
+ }
+ }
+
+ di.w.WriteString(string(b))
+
+ if di.dm.floatPrecisionIndicator {
+ switch ai {
+ case additionalInformationAsFloat16:
+ di.w.WriteString("_1")
+ return nil
+
+ case additionalInformationAsFloat32:
+ di.w.WriteString("_2")
+ return nil
+
+ case additionalInformationAsFloat64:
+ di.w.WriteString("_3")
+ return nil
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/doc.go b/vendor/github.com/fxamacker/cbor/v2/doc.go
new file mode 100644
index 000000000..23f68b984
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/doc.go
@@ -0,0 +1,129 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+/*
+Package cbor is a modern CBOR codec (RFC 8949 & RFC 7049) with CBOR tags,
+Go struct tags (toarray/keyasint/omitempty), Core Deterministic Encoding,
+CTAP2, Canonical CBOR, float64->32->16, and duplicate map key detection.
+
+Encoding options allow "preferred serialization" by encoding integers and floats
+to their smallest forms (e.g. float16) when values fit.
+
+Struct tags like "keyasint", "toarray" and "omitempty" make CBOR data smaller
+and easier to use with structs.
+
+For example, "toarray" tag makes struct fields encode to CBOR array elements. And
+"keyasint" makes a field encode to an element of CBOR map with specified int key.
+
+Latest docs can be viewed at https://github.com/fxamacker/cbor#cbor-library-in-go
+
+# Basics
+
+The Quick Start guide is at https://github.com/fxamacker/cbor#quick-start
+
+Function signatures identical to encoding/json include:
+
+ Marshal, Unmarshal, NewEncoder, NewDecoder, (*Encoder).Encode, (*Decoder).Decode.
+
+Standard interfaces include:
+
+ BinaryMarshaler, BinaryUnmarshaler, Marshaler, and Unmarshaler.
+
+Custom encoding and decoding is possible by implementing standard interfaces for
+user-defined Go types.
+
+Codec functions are available at package-level (using defaults options) or by
+creating modes from options at runtime.
+
+"Mode" in this API means definite way of encoding (EncMode) or decoding (DecMode).
+
+EncMode and DecMode interfaces are created from EncOptions or DecOptions structs.
+
+ em, err := cbor.EncOptions{...}.EncMode()
+ em, err := cbor.CanonicalEncOptions().EncMode()
+ em, err := cbor.CTAP2EncOptions().EncMode()
+
+Modes use immutable options to avoid side-effects and simplify concurrency. Behavior of
+modes won't accidentally change at runtime after they're created.
+
+Modes are intended to be reused and are safe for concurrent use.
+
+EncMode and DecMode Interfaces
+
+ // EncMode interface uses immutable options and is safe for concurrent use.
+ type EncMode interface {
+ Marshal(v interface{}) ([]byte, error)
+ NewEncoder(w io.Writer) *Encoder
+ EncOptions() EncOptions // returns copy of options
+ }
+
+ // DecMode interface uses immutable options and is safe for concurrent use.
+ type DecMode interface {
+ Unmarshal(data []byte, v interface{}) error
+ NewDecoder(r io.Reader) *Decoder
+ DecOptions() DecOptions // returns copy of options
+ }
+
+Using Default Encoding Mode
+
+ b, err := cbor.Marshal(v)
+
+ encoder := cbor.NewEncoder(w)
+ err = encoder.Encode(v)
+
+Using Default Decoding Mode
+
+ err := cbor.Unmarshal(b, &v)
+
+ decoder := cbor.NewDecoder(r)
+ err = decoder.Decode(&v)
+
+Creating and Using Encoding Modes
+
+ // Create EncOptions using either struct literal or a function.
+ opts := cbor.CanonicalEncOptions()
+
+ // If needed, modify encoding options
+ opts.Time = cbor.TimeUnix
+
+ // Create reusable EncMode interface with immutable options, safe for concurrent use.
+ em, err := opts.EncMode()
+
+ // Use EncMode like encoding/json, with same function signatures.
+ b, err := em.Marshal(v)
+ // or
+ encoder := em.NewEncoder(w)
+ err := encoder.Encode(v)
+
+ // NOTE: Both em.Marshal(v) and encoder.Encode(v) use encoding options
+ // specified during creation of em (encoding mode).
+
+# CBOR Options
+
+Predefined Encoding Options: https://github.com/fxamacker/cbor#predefined-encoding-options
+
+Encoding Options: https://github.com/fxamacker/cbor#encoding-options
+
+Decoding Options: https://github.com/fxamacker/cbor#decoding-options
+
+# Struct Tags
+
+Struct tags like `cbor:"name,omitempty"` and `json:"name,omitempty"` work as expected.
+If both struct tags are specified then `cbor` is used.
+
+Struct tags like "keyasint", "toarray", and "omitempty" make it easy to use
+very compact formats like COSE and CWT (CBOR Web Tokens) with structs.
+
+For example, "toarray" makes struct fields encode to array elements. And "keyasint"
+makes struct fields encode to elements of CBOR map with int keys.
+
+https://raw.githubusercontent.com/fxamacker/images/master/cbor/v2.0.0/cbor_easy_api.png
+
+Struct tags are listed at https://github.com/fxamacker/cbor#struct-tags-1
+
+# Tests and Fuzzing
+
+Over 375 tests are included in this package. Cover-guided fuzzing is handled by
+a private fuzzer that replaced fxamacker/cbor-fuzz years ago.
+*/
+package cbor
diff --git a/vendor/github.com/fxamacker/cbor/v2/encode.go b/vendor/github.com/fxamacker/cbor/v2/encode.go
new file mode 100644
index 000000000..6508e291d
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/encode.go
@@ -0,0 +1,1989 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+package cbor
+
+import (
+ "bytes"
+ "encoding"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "math/big"
+ "math/rand"
+ "reflect"
+ "sort"
+ "strconv"
+ "sync"
+ "time"
+
+ "github.com/x448/float16"
+)
+
+// Marshal returns the CBOR encoding of v using default encoding options.
+// See EncOptions for encoding options.
+//
+// Marshal uses the following encoding rules:
+//
+// If value implements the Marshaler interface, Marshal calls its
+// MarshalCBOR method.
+//
+// If value implements encoding.BinaryMarshaler, Marhsal calls its
+// MarshalBinary method and encode it as CBOR byte string.
+//
+// Boolean values encode as CBOR booleans (type 7).
+//
+// Positive integer values encode as CBOR positive integers (type 0).
+//
+// Negative integer values encode as CBOR negative integers (type 1).
+//
+// Floating point values encode as CBOR floating points (type 7).
+//
+// String values encode as CBOR text strings (type 3).
+//
+// []byte values encode as CBOR byte strings (type 2).
+//
+// Array and slice values encode as CBOR arrays (type 4).
+//
+// Map values encode as CBOR maps (type 5).
+//
+// Struct values encode as CBOR maps (type 5). Each exported struct field
+// becomes a pair with field name encoded as CBOR text string (type 3) and
+// field value encoded based on its type. See struct tag option "keyasint"
+// to encode field name as CBOR integer (type 0 and 1). Also see struct
+// tag option "toarray" for special field "_" to encode struct values as
+// CBOR array (type 4).
+//
+// Marshal supports format string stored under the "cbor" key in the struct
+// field's tag. CBOR format string can specify the name of the field,
+// "omitempty" and "keyasint" options, and special case "-" for field omission.
+// If "cbor" key is absent, Marshal uses "json" key.
+//
+// Struct field name is treated as integer if it has "keyasint" option in
+// its format string. The format string must specify an integer as its
+// field name.
+//
+// Special struct field "_" is used to specify struct level options, such as
+// "toarray". "toarray" option enables Go struct to be encoded as CBOR array.
+// "omitempty" is disabled by "toarray" to ensure that the same number
+// of elements are encoded every time.
+//
+// Anonymous struct fields are marshaled as if their exported fields
+// were fields in the outer struct. Marshal follows the same struct fields
+// visibility rules used by JSON encoding package.
+//
+// time.Time values encode as text strings specified in RFC3339 or numerical
+// representation of seconds since January 1, 1970 UTC depending on
+// EncOptions.Time setting. Also See EncOptions.TimeTag to encode
+// time.Time as CBOR tag with tag number 0 or 1.
+//
+// big.Int values encode as CBOR integers (type 0 and 1) if values fit.
+// Otherwise, big.Int values encode as CBOR bignums (tag 2 and 3). See
+// EncOptions.BigIntConvert to always encode big.Int values as CBOR
+// bignums.
+//
+// Pointer values encode as the value pointed to.
+//
+// Interface values encode as the value stored in the interface.
+//
+// Nil slice/map/pointer/interface values encode as CBOR nulls (type 7).
+//
+// Values of other types cannot be encoded in CBOR. Attempting
+// to encode such a value causes Marshal to return an UnsupportedTypeError.
+func Marshal(v interface{}) ([]byte, error) {
+ return defaultEncMode.Marshal(v)
+}
+
+// MarshalToBuffer encodes v into provided buffer (instead of using built-in buffer pool)
+// and uses default encoding options.
+//
+// NOTE: Unlike Marshal, the buffer provided to MarshalToBuffer can contain
+// partially encoded data if error is returned.
+//
+// See Marshal for more details.
+func MarshalToBuffer(v interface{}, buf *bytes.Buffer) error {
+ return defaultEncMode.MarshalToBuffer(v, buf)
+}
+
+// Marshaler is the interface implemented by types that can marshal themselves
+// into valid CBOR.
+type Marshaler interface {
+ MarshalCBOR() ([]byte, error)
+}
+
+// MarshalerError represents error from checking encoded CBOR data item
+// returned from MarshalCBOR for well-formedness and some very limited tag validation.
+type MarshalerError struct {
+ typ reflect.Type
+ err error
+}
+
+func (e *MarshalerError) Error() string {
+ return "cbor: error calling MarshalCBOR for type " +
+ e.typ.String() +
+ ": " + e.err.Error()
+}
+
+func (e *MarshalerError) Unwrap() error {
+ return e.err
+}
+
+// UnsupportedTypeError is returned by Marshal when attempting to encode value
+// of an unsupported type.
+type UnsupportedTypeError struct {
+ Type reflect.Type
+}
+
+func (e *UnsupportedTypeError) Error() string {
+ return "cbor: unsupported type: " + e.Type.String()
+}
+
+// UnsupportedValueError is returned by Marshal when attempting to encode an
+// unsupported value.
+type UnsupportedValueError struct {
+ msg string
+}
+
+func (e *UnsupportedValueError) Error() string {
+ return "cbor: unsupported value: " + e.msg
+}
+
+// SortMode identifies supported sorting order.
+type SortMode int
+
+const (
+ // SortNone encodes map pairs and struct fields in an arbitrary order.
+ SortNone SortMode = 0
+
+ // SortLengthFirst causes map keys or struct fields to be sorted such that:
+ // - If two keys have different lengths, the shorter one sorts earlier;
+ // - If two keys have the same length, the one with the lower value in
+ // (byte-wise) lexical order sorts earlier.
+ // It is used in "Canonical CBOR" encoding in RFC 7049 3.9.
+ SortLengthFirst SortMode = 1
+
+ // SortBytewiseLexical causes map keys or struct fields to be sorted in the
+ // bytewise lexicographic order of their deterministic CBOR encodings.
+ // It is used in "CTAP2 Canonical CBOR" and "Core Deterministic Encoding"
+ // in RFC 7049bis.
+ SortBytewiseLexical SortMode = 2
+
+ // SortShuffle encodes map pairs and struct fields in a shuffled
+ // order. This mode does not guarantee an unbiased permutation, but it
+ // does guarantee that the runtime of the shuffle algorithm used will be
+ // constant.
+ SortFastShuffle SortMode = 3
+
+ // SortCanonical is used in "Canonical CBOR" encoding in RFC 7049 3.9.
+ SortCanonical SortMode = SortLengthFirst
+
+ // SortCTAP2 is used in "CTAP2 Canonical CBOR".
+ SortCTAP2 SortMode = SortBytewiseLexical
+
+ // SortCoreDeterministic is used in "Core Deterministic Encoding" in RFC 7049bis.
+ SortCoreDeterministic SortMode = SortBytewiseLexical
+
+ maxSortMode SortMode = 4
+)
+
+func (sm SortMode) valid() bool {
+ return sm >= 0 && sm < maxSortMode
+}
+
+// StringMode specifies how to encode Go string values.
+type StringMode int
+
+const (
+ // StringToTextString encodes Go string to CBOR text string (major type 3).
+ StringToTextString StringMode = iota
+
+ // StringToByteString encodes Go string to CBOR byte string (major type 2).
+ StringToByteString
+)
+
+func (st StringMode) cborType() (cborType, error) {
+ switch st {
+ case StringToTextString:
+ return cborTypeTextString, nil
+
+ case StringToByteString:
+ return cborTypeByteString, nil
+ }
+ return 0, errors.New("cbor: invalid StringType " + strconv.Itoa(int(st)))
+}
+
+// ShortestFloatMode specifies which floating-point format should
+// be used as the shortest possible format for CBOR encoding.
+// It is not used for encoding Infinity and NaN values.
+type ShortestFloatMode int
+
+const (
+ // ShortestFloatNone makes float values encode without any conversion.
+ // This is the default for ShortestFloatMode in v1.
+ // E.g. a float32 in Go will encode to CBOR float32. And
+ // a float64 in Go will encode to CBOR float64.
+ ShortestFloatNone ShortestFloatMode = iota
+
+ // ShortestFloat16 specifies float16 as the shortest form that preserves value.
+ // E.g. if float64 can convert to float32 while preserving value, then
+ // encoding will also try to convert float32 to float16. So a float64 might
+ // encode as CBOR float64, float32 or float16 depending on the value.
+ ShortestFloat16
+
+ maxShortestFloat
+)
+
+func (sfm ShortestFloatMode) valid() bool {
+ return sfm >= 0 && sfm < maxShortestFloat
+}
+
+// NaNConvertMode specifies how to encode NaN and overrides ShortestFloatMode.
+// ShortestFloatMode is not used for encoding Infinity and NaN values.
+type NaNConvertMode int
+
+const (
+ // NaNConvert7e00 always encodes NaN to 0xf97e00 (CBOR float16 = 0x7e00).
+ NaNConvert7e00 NaNConvertMode = iota
+
+ // NaNConvertNone never modifies or converts NaN to other representations
+ // (float64 NaN stays float64, etc. even if it can use float16 without losing
+ // any bits).
+ NaNConvertNone
+
+ // NaNConvertPreserveSignal converts NaN to the smallest form that preserves
+ // value (quiet bit + payload) as described in RFC 7049bis Draft 12.
+ NaNConvertPreserveSignal
+
+ // NaNConvertQuiet always forces quiet bit = 1 and shortest form that preserves
+ // NaN payload.
+ NaNConvertQuiet
+
+ // NaNConvertReject returns UnsupportedValueError on attempts to encode a NaN value.
+ NaNConvertReject
+
+ maxNaNConvert
+)
+
+func (ncm NaNConvertMode) valid() bool {
+ return ncm >= 0 && ncm < maxNaNConvert
+}
+
+// InfConvertMode specifies how to encode Infinity and overrides ShortestFloatMode.
+// ShortestFloatMode is not used for encoding Infinity and NaN values.
+type InfConvertMode int
+
+const (
+ // InfConvertFloat16 always converts Inf to lossless IEEE binary16 (float16).
+ InfConvertFloat16 InfConvertMode = iota
+
+ // InfConvertNone never converts (used by CTAP2 Canonical CBOR).
+ InfConvertNone
+
+ // InfConvertReject returns UnsupportedValueError on attempts to encode an infinite value.
+ InfConvertReject
+
+ maxInfConvert
+)
+
+func (icm InfConvertMode) valid() bool {
+ return icm >= 0 && icm < maxInfConvert
+}
+
+// TimeMode specifies how to encode time.Time values.
+type TimeMode int
+
+const (
+ // TimeUnix causes time.Time to be encoded as epoch time in integer with second precision.
+ TimeUnix TimeMode = iota
+
+ // TimeUnixMicro causes time.Time to be encoded as epoch time in float-point rounded to microsecond precision.
+ TimeUnixMicro
+
+ // TimeUnixDynamic causes time.Time to be encoded as integer if time.Time doesn't have fractional seconds,
+ // otherwise float-point rounded to microsecond precision.
+ TimeUnixDynamic
+
+ // TimeRFC3339 causes time.Time to be encoded as RFC3339 formatted string with second precision.
+ TimeRFC3339
+
+ // TimeRFC3339Nano causes time.Time to be encoded as RFC3339 formatted string with nanosecond precision.
+ TimeRFC3339Nano
+
+ maxTimeMode
+)
+
+func (tm TimeMode) valid() bool {
+ return tm >= 0 && tm < maxTimeMode
+}
+
+// BigIntConvertMode specifies how to encode big.Int values.
+type BigIntConvertMode int
+
+const (
+ // BigIntConvertShortest makes big.Int encode to CBOR integer if value fits.
+ // E.g. if big.Int value can be converted to CBOR integer while preserving
+ // value, encoder will encode it to CBOR integer (major type 0 or 1).
+ BigIntConvertShortest BigIntConvertMode = iota
+
+ // BigIntConvertNone makes big.Int encode to CBOR bignum (tag 2 or 3) without
+ // converting it to another CBOR type.
+ BigIntConvertNone
+
+ // BigIntConvertReject returns an UnsupportedTypeError instead of marshaling a big.Int.
+ BigIntConvertReject
+
+ maxBigIntConvert
+)
+
+func (bim BigIntConvertMode) valid() bool {
+ return bim >= 0 && bim < maxBigIntConvert
+}
+
+// NilContainersMode specifies how to encode nil slices and maps.
+type NilContainersMode int
+
+const (
+ // NilContainerAsNull encodes nil slices and maps as CBOR null.
+ // This is the default.
+ NilContainerAsNull NilContainersMode = iota
+
+ // NilContainerAsEmpty encodes nil slices and maps as
+ // empty container (CBOR bytestring, array, or map).
+ NilContainerAsEmpty
+
+ maxNilContainersMode
+)
+
+func (m NilContainersMode) valid() bool {
+ return m >= 0 && m < maxNilContainersMode
+}
+
+// OmitEmptyMode specifies how to encode struct fields with omitempty tag.
+// The default behavior omits if field value would encode as empty CBOR value.
+type OmitEmptyMode int
+
+const (
+ // OmitEmptyCBORValue specifies that struct fields tagged with "omitempty"
+ // should be omitted from encoding if the field would be encoded as an empty
+ // CBOR value, such as CBOR false, 0, 0.0, nil, empty byte, empty string,
+ // empty array, or empty map.
+ OmitEmptyCBORValue OmitEmptyMode = iota
+
+ // OmitEmptyGoValue specifies that struct fields tagged with "omitempty"
+ // should be omitted from encoding if the field has an empty Go value,
+ // defined as false, 0, 0.0, a nil pointer, a nil interface value, and
+ // any empty array, slice, map, or string.
+ // This behavior is the same as the current (aka v1) encoding/json package
+ // included in Go.
+ OmitEmptyGoValue
+
+ maxOmitEmptyMode
+)
+
+func (om OmitEmptyMode) valid() bool {
+ return om >= 0 && om < maxOmitEmptyMode
+}
+
+// FieldNameMode specifies the CBOR type to use when encoding struct field names.
+type FieldNameMode int
+
+const (
+ // FieldNameToTextString encodes struct fields to CBOR text string (major type 3).
+ FieldNameToTextString FieldNameMode = iota
+
+ // FieldNameToTextString encodes struct fields to CBOR byte string (major type 2).
+ FieldNameToByteString
+
+ maxFieldNameMode
+)
+
+func (fnm FieldNameMode) valid() bool {
+ return fnm >= 0 && fnm < maxFieldNameMode
+}
+
+// ByteSliceLaterFormatMode specifies which later format conversion hint (CBOR tag 21-23)
+// to include (if any) when encoding Go byte slice to CBOR byte string. The encoder will
+// always encode unmodified bytes from the byte slice and just wrap it within
+// CBOR tag 21, 22, or 23 if specified.
+// See "Expected Later Encoding for CBOR-to-JSON Converters" in RFC 8949 Section 3.4.5.2.
+type ByteSliceLaterFormatMode int
+
+const (
+ // ByteSliceLaterFormatNone encodes unmodified bytes from Go byte slice to CBOR byte string (major type 2)
+ // without adding CBOR tag 21, 22, or 23.
+ ByteSliceLaterFormatNone ByteSliceLaterFormatMode = iota
+
+ // ByteSliceLaterFormatBase64URL encodes unmodified bytes from Go byte slice to CBOR byte string (major type 2)
+ // inside CBOR tag 21 (expected later conversion to base64url encoding, see RFC 8949 Section 3.4.5.2).
+ ByteSliceLaterFormatBase64URL
+
+ // ByteSliceLaterFormatBase64 encodes unmodified bytes from Go byte slice to CBOR byte string (major type 2)
+ // inside CBOR tag 22 (expected later conversion to base64 encoding, see RFC 8949 Section 3.4.5.2).
+ ByteSliceLaterFormatBase64
+
+ // ByteSliceLaterFormatBase16 encodes unmodified bytes from Go byte slice to CBOR byte string (major type 2)
+ // inside CBOR tag 23 (expected later conversion to base16 encoding, see RFC 8949 Section 3.4.5.2).
+ ByteSliceLaterFormatBase16
+)
+
+func (bsefm ByteSliceLaterFormatMode) encodingTag() (uint64, error) {
+ switch bsefm {
+ case ByteSliceLaterFormatNone:
+ return 0, nil
+
+ case ByteSliceLaterFormatBase64URL:
+ return tagNumExpectedLaterEncodingBase64URL, nil
+
+ case ByteSliceLaterFormatBase64:
+ return tagNumExpectedLaterEncodingBase64, nil
+
+ case ByteSliceLaterFormatBase16:
+ return tagNumExpectedLaterEncodingBase16, nil
+ }
+ return 0, errors.New("cbor: invalid ByteSliceLaterFormat " + strconv.Itoa(int(bsefm)))
+}
+
+// ByteArrayMode specifies how to encode byte arrays.
+type ByteArrayMode int
+
+const (
+ // ByteArrayToByteSlice encodes byte arrays the same way that a byte slice with identical
+ // length and contents is encoded.
+ ByteArrayToByteSlice ByteArrayMode = iota
+
+ // ByteArrayToArray encodes byte arrays to the CBOR array type with one unsigned integer
+ // item for each byte in the array.
+ ByteArrayToArray
+
+ maxByteArrayMode
+)
+
+func (bam ByteArrayMode) valid() bool {
+ return bam >= 0 && bam < maxByteArrayMode
+}
+
+// BinaryMarshalerMode specifies how to encode types that implement encoding.BinaryMarshaler.
+type BinaryMarshalerMode int
+
+const (
+ // BinaryMarshalerByteString encodes the output of MarshalBinary to a CBOR byte string.
+ BinaryMarshalerByteString BinaryMarshalerMode = iota
+
+ // BinaryMarshalerNone does not recognize BinaryMarshaler implementations during encode.
+ BinaryMarshalerNone
+
+ maxBinaryMarshalerMode
+)
+
+func (bmm BinaryMarshalerMode) valid() bool {
+ return bmm >= 0 && bmm < maxBinaryMarshalerMode
+}
+
+// EncOptions specifies encoding options.
+type EncOptions struct {
+ // Sort specifies sorting order.
+ Sort SortMode
+
+ // ShortestFloat specifies the shortest floating-point encoding that preserves
+ // the value being encoded.
+ ShortestFloat ShortestFloatMode
+
+ // NaNConvert specifies how to encode NaN and it overrides ShortestFloatMode.
+ NaNConvert NaNConvertMode
+
+ // InfConvert specifies how to encode Inf and it overrides ShortestFloatMode.
+ InfConvert InfConvertMode
+
+ // BigIntConvert specifies how to encode big.Int values.
+ BigIntConvert BigIntConvertMode
+
+ // Time specifies how to encode time.Time.
+ Time TimeMode
+
+ // TimeTag allows time.Time to be encoded with a tag number.
+ // RFC3339 format gets tag number 0, and numeric epoch time tag number 1.
+ TimeTag EncTagMode
+
+ // IndefLength specifies whether to allow indefinite length CBOR items.
+ IndefLength IndefLengthMode
+
+ // NilContainers specifies how to encode nil slices and maps.
+ NilContainers NilContainersMode
+
+ // TagsMd specifies whether to allow CBOR tags (major type 6).
+ TagsMd TagsMode
+
+ // OmitEmptyMode specifies how to encode struct fields with omitempty tag.
+ OmitEmpty OmitEmptyMode
+
+ // String specifies which CBOR type to use when encoding Go strings.
+ // - CBOR text string (major type 3) is default
+ // - CBOR byte string (major type 2)
+ String StringMode
+
+ // FieldName specifies the CBOR type to use when encoding struct field names.
+ FieldName FieldNameMode
+
+ // ByteSliceLaterFormat specifies which later format conversion hint (CBOR tag 21-23)
+ // to include (if any) when encoding Go byte slice to CBOR byte string. The encoder will
+ // always encode unmodified bytes from the byte slice and just wrap it within
+ // CBOR tag 21, 22, or 23 if specified.
+ // See "Expected Later Encoding for CBOR-to-JSON Converters" in RFC 8949 Section 3.4.5.2.
+ ByteSliceLaterFormat ByteSliceLaterFormatMode
+
+ // ByteArray specifies how to encode byte arrays.
+ ByteArray ByteArrayMode
+
+ // BinaryMarshaler specifies how to encode types that implement encoding.BinaryMarshaler.
+ BinaryMarshaler BinaryMarshalerMode
+}
+
+// CanonicalEncOptions returns EncOptions for "Canonical CBOR" encoding,
+// defined in RFC 7049 Section 3.9 with the following rules:
+//
+// 1. "Integers must be as small as possible."
+// 2. "The expression of lengths in major types 2 through 5 must be as short as possible."
+// 3. The keys in every map must be sorted in length-first sorting order.
+// See SortLengthFirst for details.
+// 4. "Indefinite-length items must be made into definite-length items."
+// 5. "If a protocol allows for IEEE floats, then additional canonicalization rules might
+// need to be added. One example rule might be to have all floats start as a 64-bit
+// float, then do a test conversion to a 32-bit float; if the result is the same numeric
+// value, use the shorter value and repeat the process with a test conversion to a
+// 16-bit float. (This rule selects 16-bit float for positive and negative Infinity
+// as well.) Also, there are many representations for NaN. If NaN is an allowed value,
+// it must always be represented as 0xf97e00."
+func CanonicalEncOptions() EncOptions {
+ return EncOptions{
+ Sort: SortCanonical,
+ ShortestFloat: ShortestFloat16,
+ NaNConvert: NaNConvert7e00,
+ InfConvert: InfConvertFloat16,
+ IndefLength: IndefLengthForbidden,
+ }
+}
+
+// CTAP2EncOptions returns EncOptions for "CTAP2 Canonical CBOR" encoding,
+// defined in CTAP specification, with the following rules:
+//
+// 1. "Integers must be encoded as small as possible."
+// 2. "The representations of any floating-point values are not changed."
+// 3. "The expression of lengths in major types 2 through 5 must be as short as possible."
+// 4. "Indefinite-length items must be made into definite-length items.""
+// 5. The keys in every map must be sorted in bytewise lexicographic order.
+// See SortBytewiseLexical for details.
+// 6. "Tags as defined in Section 2.4 in [RFC7049] MUST NOT be present."
+func CTAP2EncOptions() EncOptions {
+ return EncOptions{
+ Sort: SortCTAP2,
+ ShortestFloat: ShortestFloatNone,
+ NaNConvert: NaNConvertNone,
+ InfConvert: InfConvertNone,
+ IndefLength: IndefLengthForbidden,
+ TagsMd: TagsForbidden,
+ }
+}
+
+// CoreDetEncOptions returns EncOptions for "Core Deterministic" encoding,
+// defined in RFC 7049bis with the following rules:
+//
+// 1. "Preferred serialization MUST be used. In particular, this means that arguments
+// (see Section 3) for integers, lengths in major types 2 through 5, and tags MUST
+// be as short as possible"
+// "Floating point values also MUST use the shortest form that preserves the value"
+// 2. "Indefinite-length items MUST NOT appear."
+// 3. "The keys in every map MUST be sorted in the bytewise lexicographic order of
+// their deterministic encodings."
+func CoreDetEncOptions() EncOptions {
+ return EncOptions{
+ Sort: SortCoreDeterministic,
+ ShortestFloat: ShortestFloat16,
+ NaNConvert: NaNConvert7e00,
+ InfConvert: InfConvertFloat16,
+ IndefLength: IndefLengthForbidden,
+ }
+}
+
+// PreferredUnsortedEncOptions returns EncOptions for "Preferred Serialization" encoding,
+// defined in RFC 7049bis with the following rules:
+//
+// 1. "The preferred serialization always uses the shortest form of representing the argument
+// (Section 3);"
+// 2. "it also uses the shortest floating-point encoding that preserves the value being
+// encoded (see Section 5.5)."
+// "The preferred encoding for a floating-point value is the shortest floating-point encoding
+// that preserves its value, e.g., 0xf94580 for the number 5.5, and 0xfa45ad9c00 for the
+// number 5555.5, unless the CBOR-based protocol specifically excludes the use of the shorter
+// floating-point encodings. For NaN values, a shorter encoding is preferred if zero-padding
+// the shorter significand towards the right reconstitutes the original NaN value (for many
+// applications, the single NaN encoding 0xf97e00 will suffice)."
+// 3. "Definite length encoding is preferred whenever the length is known at the time the
+// serialization of the item starts."
+func PreferredUnsortedEncOptions() EncOptions {
+ return EncOptions{
+ Sort: SortNone,
+ ShortestFloat: ShortestFloat16,
+ NaNConvert: NaNConvert7e00,
+ InfConvert: InfConvertFloat16,
+ }
+}
+
+// EncMode returns EncMode with immutable options and no tags (safe for concurrency).
+func (opts EncOptions) EncMode() (EncMode, error) { //nolint:gocritic // ignore hugeParam
+ return opts.encMode()
+}
+
+// UserBufferEncMode returns UserBufferEncMode with immutable options and no tags (safe for concurrency).
+func (opts EncOptions) UserBufferEncMode() (UserBufferEncMode, error) { //nolint:gocritic // ignore hugeParam
+ return opts.encMode()
+}
+
+// EncModeWithTags returns EncMode with options and tags that are both immutable (safe for concurrency).
+func (opts EncOptions) EncModeWithTags(tags TagSet) (EncMode, error) { //nolint:gocritic // ignore hugeParam
+ return opts.UserBufferEncModeWithTags(tags)
+}
+
+// UserBufferEncModeWithTags returns UserBufferEncMode with options and tags that are both immutable (safe for concurrency).
+func (opts EncOptions) UserBufferEncModeWithTags(tags TagSet) (UserBufferEncMode, error) { //nolint:gocritic // ignore hugeParam
+ if opts.TagsMd == TagsForbidden {
+ return nil, errors.New("cbor: cannot create EncMode with TagSet when TagsMd is TagsForbidden")
+ }
+ if tags == nil {
+ return nil, errors.New("cbor: cannot create EncMode with nil value as TagSet")
+ }
+ em, err := opts.encMode()
+ if err != nil {
+ return nil, err
+ }
+ // Copy tags
+ ts := tagSet(make(map[reflect.Type]*tagItem))
+ syncTags := tags.(*syncTagSet)
+ syncTags.RLock()
+ for contentType, tag := range syncTags.t {
+ if tag.opts.EncTag != EncTagNone {
+ ts[contentType] = tag
+ }
+ }
+ syncTags.RUnlock()
+ if len(ts) > 0 {
+ em.tags = ts
+ }
+ return em, nil
+}
+
+// EncModeWithSharedTags returns EncMode with immutable options and mutable shared tags (safe for concurrency).
+func (opts EncOptions) EncModeWithSharedTags(tags TagSet) (EncMode, error) { //nolint:gocritic // ignore hugeParam
+ return opts.UserBufferEncModeWithSharedTags(tags)
+}
+
+// UserBufferEncModeWithSharedTags returns UserBufferEncMode with immutable options and mutable shared tags (safe for concurrency).
+func (opts EncOptions) UserBufferEncModeWithSharedTags(tags TagSet) (UserBufferEncMode, error) { //nolint:gocritic // ignore hugeParam
+ if opts.TagsMd == TagsForbidden {
+ return nil, errors.New("cbor: cannot create EncMode with TagSet when TagsMd is TagsForbidden")
+ }
+ if tags == nil {
+ return nil, errors.New("cbor: cannot create EncMode with nil value as TagSet")
+ }
+ em, err := opts.encMode()
+ if err != nil {
+ return nil, err
+ }
+ em.tags = tags
+ return em, nil
+}
+
+func (opts EncOptions) encMode() (*encMode, error) { //nolint:gocritic // ignore hugeParam
+ if !opts.Sort.valid() {
+ return nil, errors.New("cbor: invalid SortMode " + strconv.Itoa(int(opts.Sort)))
+ }
+ if !opts.ShortestFloat.valid() {
+ return nil, errors.New("cbor: invalid ShortestFloatMode " + strconv.Itoa(int(opts.ShortestFloat)))
+ }
+ if !opts.NaNConvert.valid() {
+ return nil, errors.New("cbor: invalid NaNConvertMode " + strconv.Itoa(int(opts.NaNConvert)))
+ }
+ if !opts.InfConvert.valid() {
+ return nil, errors.New("cbor: invalid InfConvertMode " + strconv.Itoa(int(opts.InfConvert)))
+ }
+ if !opts.BigIntConvert.valid() {
+ return nil, errors.New("cbor: invalid BigIntConvertMode " + strconv.Itoa(int(opts.BigIntConvert)))
+ }
+ if !opts.Time.valid() {
+ return nil, errors.New("cbor: invalid TimeMode " + strconv.Itoa(int(opts.Time)))
+ }
+ if !opts.TimeTag.valid() {
+ return nil, errors.New("cbor: invalid TimeTag " + strconv.Itoa(int(opts.TimeTag)))
+ }
+ if !opts.IndefLength.valid() {
+ return nil, errors.New("cbor: invalid IndefLength " + strconv.Itoa(int(opts.IndefLength)))
+ }
+ if !opts.NilContainers.valid() {
+ return nil, errors.New("cbor: invalid NilContainers " + strconv.Itoa(int(opts.NilContainers)))
+ }
+ if !opts.TagsMd.valid() {
+ return nil, errors.New("cbor: invalid TagsMd " + strconv.Itoa(int(opts.TagsMd)))
+ }
+ if opts.TagsMd == TagsForbidden && opts.TimeTag == EncTagRequired {
+ return nil, errors.New("cbor: cannot set TagsMd to TagsForbidden when TimeTag is EncTagRequired")
+ }
+ if !opts.OmitEmpty.valid() {
+ return nil, errors.New("cbor: invalid OmitEmpty " + strconv.Itoa(int(opts.OmitEmpty)))
+ }
+ stringMajorType, err := opts.String.cborType()
+ if err != nil {
+ return nil, err
+ }
+ if !opts.FieldName.valid() {
+ return nil, errors.New("cbor: invalid FieldName " + strconv.Itoa(int(opts.FieldName)))
+ }
+ byteSliceLaterEncodingTag, err := opts.ByteSliceLaterFormat.encodingTag()
+ if err != nil {
+ return nil, err
+ }
+ if !opts.ByteArray.valid() {
+ return nil, errors.New("cbor: invalid ByteArray " + strconv.Itoa(int(opts.ByteArray)))
+ }
+ if !opts.BinaryMarshaler.valid() {
+ return nil, errors.New("cbor: invalid BinaryMarshaler " + strconv.Itoa(int(opts.BinaryMarshaler)))
+ }
+ em := encMode{
+ sort: opts.Sort,
+ shortestFloat: opts.ShortestFloat,
+ nanConvert: opts.NaNConvert,
+ infConvert: opts.InfConvert,
+ bigIntConvert: opts.BigIntConvert,
+ time: opts.Time,
+ timeTag: opts.TimeTag,
+ indefLength: opts.IndefLength,
+ nilContainers: opts.NilContainers,
+ tagsMd: opts.TagsMd,
+ omitEmpty: opts.OmitEmpty,
+ stringType: opts.String,
+ stringMajorType: stringMajorType,
+ fieldName: opts.FieldName,
+ byteSliceLaterFormat: opts.ByteSliceLaterFormat,
+ byteSliceLaterEncodingTag: byteSliceLaterEncodingTag,
+ byteArray: opts.ByteArray,
+ binaryMarshaler: opts.BinaryMarshaler,
+ }
+ return &em, nil
+}
+
+// EncMode is the main interface for CBOR encoding.
+type EncMode interface {
+ Marshal(v interface{}) ([]byte, error)
+ NewEncoder(w io.Writer) *Encoder
+ EncOptions() EncOptions
+}
+
+// UserBufferEncMode is an interface for CBOR encoding, which extends EncMode by
+// adding MarshalToBuffer to support user specified buffer rather than encoding
+// into the built-in buffer pool.
+type UserBufferEncMode interface {
+ EncMode
+ MarshalToBuffer(v interface{}, buf *bytes.Buffer) error
+
+ // This private method is to prevent users implementing
+ // this interface and so future additions to it will
+ // not be breaking changes.
+ // See https://go.dev/blog/module-compatibility
+ unexport()
+}
+
+type encMode struct {
+ tags tagProvider
+ sort SortMode
+ shortestFloat ShortestFloatMode
+ nanConvert NaNConvertMode
+ infConvert InfConvertMode
+ bigIntConvert BigIntConvertMode
+ time TimeMode
+ timeTag EncTagMode
+ indefLength IndefLengthMode
+ nilContainers NilContainersMode
+ tagsMd TagsMode
+ omitEmpty OmitEmptyMode
+ stringType StringMode
+ stringMajorType cborType
+ fieldName FieldNameMode
+ byteSliceLaterFormat ByteSliceLaterFormatMode
+ byteSliceLaterEncodingTag uint64
+ byteArray ByteArrayMode
+ binaryMarshaler BinaryMarshalerMode
+}
+
+var defaultEncMode, _ = EncOptions{}.encMode()
+
+// These four decoding modes are used by getMarshalerDecMode.
+// maxNestedLevels, maxArrayElements, and maxMapPairs are
+// set to max allowed limits to avoid rejecting Marshaler
+// output that would have been the allowable output of a
+// non-Marshaler object that exceeds default limits.
+var (
+ marshalerForbidIndefLengthForbidTagsDecMode = decMode{
+ maxNestedLevels: maxMaxNestedLevels,
+ maxArrayElements: maxMaxArrayElements,
+ maxMapPairs: maxMaxMapPairs,
+ indefLength: IndefLengthForbidden,
+ tagsMd: TagsForbidden,
+ }
+
+ marshalerAllowIndefLengthForbidTagsDecMode = decMode{
+ maxNestedLevels: maxMaxNestedLevels,
+ maxArrayElements: maxMaxArrayElements,
+ maxMapPairs: maxMaxMapPairs,
+ indefLength: IndefLengthAllowed,
+ tagsMd: TagsForbidden,
+ }
+
+ marshalerForbidIndefLengthAllowTagsDecMode = decMode{
+ maxNestedLevels: maxMaxNestedLevels,
+ maxArrayElements: maxMaxArrayElements,
+ maxMapPairs: maxMaxMapPairs,
+ indefLength: IndefLengthForbidden,
+ tagsMd: TagsAllowed,
+ }
+
+ marshalerAllowIndefLengthAllowTagsDecMode = decMode{
+ maxNestedLevels: maxMaxNestedLevels,
+ maxArrayElements: maxMaxArrayElements,
+ maxMapPairs: maxMaxMapPairs,
+ indefLength: IndefLengthAllowed,
+ tagsMd: TagsAllowed,
+ }
+)
+
+// getMarshalerDecMode returns one of four existing decoding modes
+// which can be reused (safe for parallel use) for the purpose of
+// checking if data returned by Marshaler is well-formed.
+func getMarshalerDecMode(indefLength IndefLengthMode, tagsMd TagsMode) *decMode {
+ switch {
+ case indefLength == IndefLengthAllowed && tagsMd == TagsAllowed:
+ return &marshalerAllowIndefLengthAllowTagsDecMode
+
+ case indefLength == IndefLengthAllowed && tagsMd == TagsForbidden:
+ return &marshalerAllowIndefLengthForbidTagsDecMode
+
+ case indefLength == IndefLengthForbidden && tagsMd == TagsAllowed:
+ return &marshalerForbidIndefLengthAllowTagsDecMode
+
+ case indefLength == IndefLengthForbidden && tagsMd == TagsForbidden:
+ return &marshalerForbidIndefLengthForbidTagsDecMode
+
+ default:
+ // This should never happen, unless we add new options to
+ // IndefLengthMode or TagsMode without updating this function.
+ return &decMode{
+ maxNestedLevels: maxMaxNestedLevels,
+ maxArrayElements: maxMaxArrayElements,
+ maxMapPairs: maxMaxMapPairs,
+ indefLength: indefLength,
+ tagsMd: tagsMd,
+ }
+ }
+}
+
+// EncOptions returns user specified options used to create this EncMode.
+func (em *encMode) EncOptions() EncOptions {
+ return EncOptions{
+ Sort: em.sort,
+ ShortestFloat: em.shortestFloat,
+ NaNConvert: em.nanConvert,
+ InfConvert: em.infConvert,
+ BigIntConvert: em.bigIntConvert,
+ Time: em.time,
+ TimeTag: em.timeTag,
+ IndefLength: em.indefLength,
+ NilContainers: em.nilContainers,
+ TagsMd: em.tagsMd,
+ OmitEmpty: em.omitEmpty,
+ String: em.stringType,
+ FieldName: em.fieldName,
+ ByteSliceLaterFormat: em.byteSliceLaterFormat,
+ ByteArray: em.byteArray,
+ BinaryMarshaler: em.binaryMarshaler,
+ }
+}
+
+func (em *encMode) unexport() {}
+
+func (em *encMode) encTagBytes(t reflect.Type) []byte {
+ if em.tags != nil {
+ if tagItem := em.tags.getTagItemFromType(t); tagItem != nil {
+ return tagItem.cborTagNum
+ }
+ }
+ return nil
+}
+
+// Marshal returns the CBOR encoding of v using em encoding mode.
+//
+// See the documentation for Marshal for details.
+func (em *encMode) Marshal(v interface{}) ([]byte, error) {
+ e := getEncodeBuffer()
+
+ if err := encode(e, em, reflect.ValueOf(v)); err != nil {
+ putEncodeBuffer(e)
+ return nil, err
+ }
+
+ buf := make([]byte, e.Len())
+ copy(buf, e.Bytes())
+
+ putEncodeBuffer(e)
+ return buf, nil
+}
+
+// MarshalToBuffer encodes v into provided buffer (instead of using built-in buffer pool)
+// and uses em encoding mode.
+//
+// NOTE: Unlike Marshal, the buffer provided to MarshalToBuffer can contain
+// partially encoded data if error is returned.
+//
+// See Marshal for more details.
+func (em *encMode) MarshalToBuffer(v interface{}, buf *bytes.Buffer) error {
+ if buf == nil {
+ return fmt.Errorf("cbor: encoding buffer provided by user is nil")
+ }
+ return encode(buf, em, reflect.ValueOf(v))
+}
+
+// NewEncoder returns a new encoder that writes to w using em EncMode.
+func (em *encMode) NewEncoder(w io.Writer) *Encoder {
+ return &Encoder{w: w, em: em}
+}
+
+// encodeBufferPool caches unused bytes.Buffer objects for later reuse.
+var encodeBufferPool = sync.Pool{
+ New: func() interface{} {
+ e := new(bytes.Buffer)
+ e.Grow(32) // TODO: make this configurable
+ return e
+ },
+}
+
+func getEncodeBuffer() *bytes.Buffer {
+ return encodeBufferPool.Get().(*bytes.Buffer)
+}
+
+func putEncodeBuffer(e *bytes.Buffer) {
+ e.Reset()
+ encodeBufferPool.Put(e)
+}
+
+type encodeFunc func(e *bytes.Buffer, em *encMode, v reflect.Value) error
+type isEmptyFunc func(em *encMode, v reflect.Value) (empty bool, err error)
+
+func encode(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if !v.IsValid() {
+ // v is zero value
+ e.Write(cborNil)
+ return nil
+ }
+ vt := v.Type()
+ f, _ := getEncodeFunc(vt)
+ if f == nil {
+ return &UnsupportedTypeError{vt}
+ }
+
+ return f(e, em, v)
+}
+
+func encodeBool(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if b := em.encTagBytes(v.Type()); b != nil {
+ e.Write(b)
+ }
+ b := cborFalse
+ if v.Bool() {
+ b = cborTrue
+ }
+ e.Write(b)
+ return nil
+}
+
+func encodeInt(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if b := em.encTagBytes(v.Type()); b != nil {
+ e.Write(b)
+ }
+ i := v.Int()
+ if i >= 0 {
+ encodeHead(e, byte(cborTypePositiveInt), uint64(i))
+ return nil
+ }
+ i = i*(-1) - 1
+ encodeHead(e, byte(cborTypeNegativeInt), uint64(i))
+ return nil
+}
+
+func encodeUint(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if b := em.encTagBytes(v.Type()); b != nil {
+ e.Write(b)
+ }
+ encodeHead(e, byte(cborTypePositiveInt), v.Uint())
+ return nil
+}
+
+func encodeFloat(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if b := em.encTagBytes(v.Type()); b != nil {
+ e.Write(b)
+ }
+ f64 := v.Float()
+ if math.IsNaN(f64) {
+ return encodeNaN(e, em, v)
+ }
+ if math.IsInf(f64, 0) {
+ return encodeInf(e, em, v)
+ }
+ fopt := em.shortestFloat
+ if v.Kind() == reflect.Float64 && (fopt == ShortestFloatNone || cannotFitFloat32(f64)) {
+ // Encode float64
+ // Don't use encodeFloat64() because it cannot be inlined.
+ const argumentSize = 8
+ const headSize = 1 + argumentSize
+ var scratch [headSize]byte
+ scratch[0] = byte(cborTypePrimitives) | byte(additionalInformationAsFloat64)
+ binary.BigEndian.PutUint64(scratch[1:], math.Float64bits(f64))
+ e.Write(scratch[:])
+ return nil
+ }
+
+ f32 := float32(f64)
+ if fopt == ShortestFloat16 {
+ var f16 float16.Float16
+ p := float16.PrecisionFromfloat32(f32)
+ if p == float16.PrecisionExact {
+ // Roundtrip float32->float16->float32 test isn't needed.
+ f16 = float16.Fromfloat32(f32)
+ } else if p == float16.PrecisionUnknown {
+ // Try roundtrip float32->float16->float32 to determine if float32 can fit into float16.
+ f16 = float16.Fromfloat32(f32)
+ if f16.Float32() == f32 {
+ p = float16.PrecisionExact
+ }
+ }
+ if p == float16.PrecisionExact {
+ // Encode float16
+ // Don't use encodeFloat16() because it cannot be inlined.
+ const argumentSize = 2
+ const headSize = 1 + argumentSize
+ var scratch [headSize]byte
+ scratch[0] = byte(cborTypePrimitives) | additionalInformationAsFloat16
+ binary.BigEndian.PutUint16(scratch[1:], uint16(f16))
+ e.Write(scratch[:])
+ return nil
+ }
+ }
+
+ // Encode float32
+ // Don't use encodeFloat32() because it cannot be inlined.
+ const argumentSize = 4
+ const headSize = 1 + argumentSize
+ var scratch [headSize]byte
+ scratch[0] = byte(cborTypePrimitives) | additionalInformationAsFloat32
+ binary.BigEndian.PutUint32(scratch[1:], math.Float32bits(f32))
+ e.Write(scratch[:])
+ return nil
+}
+
+func encodeInf(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ f64 := v.Float()
+ switch em.infConvert {
+ case InfConvertReject:
+ return &UnsupportedValueError{msg: "floating-point infinity"}
+
+ case InfConvertFloat16:
+ if f64 > 0 {
+ e.Write(cborPositiveInfinity)
+ } else {
+ e.Write(cborNegativeInfinity)
+ }
+ return nil
+ }
+ if v.Kind() == reflect.Float64 {
+ return encodeFloat64(e, f64)
+ }
+ return encodeFloat32(e, float32(f64))
+}
+
+func encodeNaN(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ switch em.nanConvert {
+ case NaNConvert7e00:
+ e.Write(cborNaN)
+ return nil
+
+ case NaNConvertNone:
+ if v.Kind() == reflect.Float64 {
+ return encodeFloat64(e, v.Float())
+ }
+ f32 := float32NaNFromReflectValue(v)
+ return encodeFloat32(e, f32)
+
+ case NaNConvertReject:
+ return &UnsupportedValueError{msg: "floating-point NaN"}
+
+ default: // NaNConvertPreserveSignal, NaNConvertQuiet
+ if v.Kind() == reflect.Float64 {
+ f64 := v.Float()
+ f64bits := math.Float64bits(f64)
+ if em.nanConvert == NaNConvertQuiet && f64bits&(1<<51) == 0 {
+ f64bits |= 1 << 51 // Set quiet bit = 1
+ f64 = math.Float64frombits(f64bits)
+ }
+ // The lower 29 bits are dropped when converting from float64 to float32.
+ if f64bits&0x1fffffff != 0 {
+ // Encode NaN as float64 because dropped coef bits from float64 to float32 are not all 0s.
+ return encodeFloat64(e, f64)
+ }
+ // Create float32 from float64 manually because float32(f64) always turns on NaN's quiet bits.
+ sign := uint32(f64bits>>32) & (1 << 31)
+ exp := uint32(0x7f800000)
+ coef := uint32((f64bits & 0xfffffffffffff) >> 29)
+ f32bits := sign | exp | coef
+ f32 := math.Float32frombits(f32bits)
+ // The lower 13 bits are dropped when converting from float32 to float16.
+ if f32bits&0x1fff != 0 {
+ // Encode NaN as float32 because dropped coef bits from float32 to float16 are not all 0s.
+ return encodeFloat32(e, f32)
+ }
+ // Encode NaN as float16
+ f16, _ := float16.FromNaN32ps(f32) // Ignore err because it only returns error when f32 is not a NaN.
+ return encodeFloat16(e, f16)
+ }
+
+ f32 := float32NaNFromReflectValue(v)
+ f32bits := math.Float32bits(f32)
+ if em.nanConvert == NaNConvertQuiet && f32bits&(1<<22) == 0 {
+ f32bits |= 1 << 22 // Set quiet bit = 1
+ f32 = math.Float32frombits(f32bits)
+ }
+ // The lower 13 bits are dropped coef bits when converting from float32 to float16.
+ if f32bits&0x1fff != 0 {
+ // Encode NaN as float32 because dropped coef bits from float32 to float16 are not all 0s.
+ return encodeFloat32(e, f32)
+ }
+ f16, _ := float16.FromNaN32ps(f32) // Ignore err because it only returns error when f32 is not a NaN.
+ return encodeFloat16(e, f16)
+ }
+}
+
+func encodeFloat16(e *bytes.Buffer, f16 float16.Float16) error {
+ const argumentSize = 2
+ const headSize = 1 + argumentSize
+ var scratch [headSize]byte
+ scratch[0] = byte(cborTypePrimitives) | additionalInformationAsFloat16
+ binary.BigEndian.PutUint16(scratch[1:], uint16(f16))
+ e.Write(scratch[:])
+ return nil
+}
+
+func encodeFloat32(e *bytes.Buffer, f32 float32) error {
+ const argumentSize = 4
+ const headSize = 1 + argumentSize
+ var scratch [headSize]byte
+ scratch[0] = byte(cborTypePrimitives) | additionalInformationAsFloat32
+ binary.BigEndian.PutUint32(scratch[1:], math.Float32bits(f32))
+ e.Write(scratch[:])
+ return nil
+}
+
+func encodeFloat64(e *bytes.Buffer, f64 float64) error {
+ const argumentSize = 8
+ const headSize = 1 + argumentSize
+ var scratch [headSize]byte
+ scratch[0] = byte(cborTypePrimitives) | additionalInformationAsFloat64
+ binary.BigEndian.PutUint64(scratch[1:], math.Float64bits(f64))
+ e.Write(scratch[:])
+ return nil
+}
+
+func encodeByteString(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ vk := v.Kind()
+ if vk == reflect.Slice && v.IsNil() && em.nilContainers == NilContainerAsNull {
+ e.Write(cborNil)
+ return nil
+ }
+ if vk == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 && em.byteSliceLaterEncodingTag != 0 {
+ encodeHead(e, byte(cborTypeTag), em.byteSliceLaterEncodingTag)
+ }
+ if b := em.encTagBytes(v.Type()); b != nil {
+ e.Write(b)
+ }
+ slen := v.Len()
+ if slen == 0 {
+ return e.WriteByte(byte(cborTypeByteString))
+ }
+ encodeHead(e, byte(cborTypeByteString), uint64(slen))
+ if vk == reflect.Array {
+ for i := 0; i < slen; i++ {
+ e.WriteByte(byte(v.Index(i).Uint()))
+ }
+ return nil
+ }
+ e.Write(v.Bytes())
+ return nil
+}
+
+func encodeString(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if b := em.encTagBytes(v.Type()); b != nil {
+ e.Write(b)
+ }
+ s := v.String()
+ encodeHead(e, byte(em.stringMajorType), uint64(len(s)))
+ e.WriteString(s)
+ return nil
+}
+
+type arrayEncodeFunc struct {
+ f encodeFunc
+}
+
+func (ae arrayEncodeFunc) encode(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if em.byteArray == ByteArrayToByteSlice && v.Type().Elem().Kind() == reflect.Uint8 {
+ return encodeByteString(e, em, v)
+ }
+ if v.Kind() == reflect.Slice && v.IsNil() && em.nilContainers == NilContainerAsNull {
+ e.Write(cborNil)
+ return nil
+ }
+ if b := em.encTagBytes(v.Type()); b != nil {
+ e.Write(b)
+ }
+ alen := v.Len()
+ if alen == 0 {
+ return e.WriteByte(byte(cborTypeArray))
+ }
+ encodeHead(e, byte(cborTypeArray), uint64(alen))
+ for i := 0; i < alen; i++ {
+ if err := ae.f(e, em, v.Index(i)); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// encodeKeyValueFunc encodes key/value pairs in map (v).
+// If kvs is provided (having the same length as v), length of encoded key and value are stored in kvs.
+// kvs is used for canonical encoding of map.
+type encodeKeyValueFunc func(e *bytes.Buffer, em *encMode, v reflect.Value, kvs []keyValue) error
+
+type mapEncodeFunc struct {
+ e encodeKeyValueFunc
+}
+
+func (me mapEncodeFunc) encode(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if v.IsNil() && em.nilContainers == NilContainerAsNull {
+ e.Write(cborNil)
+ return nil
+ }
+ if b := em.encTagBytes(v.Type()); b != nil {
+ e.Write(b)
+ }
+ mlen := v.Len()
+ if mlen == 0 {
+ return e.WriteByte(byte(cborTypeMap))
+ }
+
+ encodeHead(e, byte(cborTypeMap), uint64(mlen))
+ if em.sort == SortNone || em.sort == SortFastShuffle || mlen <= 1 {
+ return me.e(e, em, v, nil)
+ }
+
+ kvsp := getKeyValues(v.Len()) // for sorting keys
+ defer putKeyValues(kvsp)
+ kvs := *kvsp
+
+ kvBeginOffset := e.Len()
+ if err := me.e(e, em, v, kvs); err != nil {
+ return err
+ }
+ kvTotalLen := e.Len() - kvBeginOffset
+
+ // Use the capacity at the tail of the encode buffer as a staging area to rearrange the
+ // encoded pairs into sorted order.
+ e.Grow(kvTotalLen)
+ tmp := e.Bytes()[e.Len() : e.Len()+kvTotalLen] // Can use e.AvailableBuffer() in Go 1.21+.
+ dst := e.Bytes()[kvBeginOffset:]
+
+ if em.sort == SortBytewiseLexical {
+ sort.Sort(&bytewiseKeyValueSorter{kvs: kvs, data: dst})
+ } else {
+ sort.Sort(&lengthFirstKeyValueSorter{kvs: kvs, data: dst})
+ }
+
+ // This is where the encoded bytes are actually rearranged in the output buffer to reflect
+ // the desired order.
+ sortedOffset := 0
+ for _, kv := range kvs {
+ copy(tmp[sortedOffset:], dst[kv.offset:kv.nextOffset])
+ sortedOffset += kv.nextOffset - kv.offset
+ }
+ copy(dst, tmp[:kvTotalLen])
+
+ return nil
+
+}
+
+// keyValue is the position of an encoded pair in a buffer. All offsets are zero-based and relative
+// to the first byte of the first encoded pair.
+type keyValue struct {
+ offset int
+ valueOffset int
+ nextOffset int
+}
+
+type bytewiseKeyValueSorter struct {
+ kvs []keyValue
+ data []byte
+}
+
+func (x *bytewiseKeyValueSorter) Len() int {
+ return len(x.kvs)
+}
+
+func (x *bytewiseKeyValueSorter) Swap(i, j int) {
+ x.kvs[i], x.kvs[j] = x.kvs[j], x.kvs[i]
+}
+
+func (x *bytewiseKeyValueSorter) Less(i, j int) bool {
+ kvi, kvj := x.kvs[i], x.kvs[j]
+ return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) <= 0
+}
+
+type lengthFirstKeyValueSorter struct {
+ kvs []keyValue
+ data []byte
+}
+
+func (x *lengthFirstKeyValueSorter) Len() int {
+ return len(x.kvs)
+}
+
+func (x *lengthFirstKeyValueSorter) Swap(i, j int) {
+ x.kvs[i], x.kvs[j] = x.kvs[j], x.kvs[i]
+}
+
+func (x *lengthFirstKeyValueSorter) Less(i, j int) bool {
+ kvi, kvj := x.kvs[i], x.kvs[j]
+ if keyLengthDifference := (kvi.valueOffset - kvi.offset) - (kvj.valueOffset - kvj.offset); keyLengthDifference != 0 {
+ return keyLengthDifference < 0
+ }
+ return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) <= 0
+}
+
+var keyValuePool = sync.Pool{}
+
+func getKeyValues(length int) *[]keyValue {
+ v := keyValuePool.Get()
+ if v == nil {
+ y := make([]keyValue, length)
+ return &y
+ }
+ x := v.(*[]keyValue)
+ if cap(*x) >= length {
+ *x = (*x)[:length]
+ return x
+ }
+ // []keyValue from the pool does not have enough capacity.
+ // Return it back to the pool and create a new one.
+ keyValuePool.Put(x)
+ y := make([]keyValue, length)
+ return &y
+}
+
+func putKeyValues(x *[]keyValue) {
+ *x = (*x)[:0]
+ keyValuePool.Put(x)
+}
+
+func encodeStructToArray(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) {
+ structType, err := getEncodingStructType(v.Type())
+ if err != nil {
+ return err
+ }
+
+ if b := em.encTagBytes(v.Type()); b != nil {
+ e.Write(b)
+ }
+
+ flds := structType.fields
+
+ encodeHead(e, byte(cborTypeArray), uint64(len(flds)))
+ for i := 0; i < len(flds); i++ {
+ f := flds[i]
+
+ var fv reflect.Value
+ if len(f.idx) == 1 {
+ fv = v.Field(f.idx[0])
+ } else {
+ // Get embedded field value. No error is expected.
+ fv, _ = getFieldValue(v, f.idx, func(reflect.Value) (reflect.Value, error) {
+ // Write CBOR nil for null pointer to embedded struct
+ e.Write(cborNil)
+ return reflect.Value{}, nil
+ })
+ if !fv.IsValid() {
+ continue
+ }
+ }
+
+ if err := f.ef(e, em, fv); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) {
+ structType, err := getEncodingStructType(v.Type())
+ if err != nil {
+ return err
+ }
+
+ flds := structType.getFields(em)
+
+ start := 0
+ if em.sort == SortFastShuffle && len(flds) > 0 {
+ start = rand.Intn(len(flds)) //nolint:gosec // Don't need a CSPRNG for deck cutting.
+ }
+
+ if b := em.encTagBytes(v.Type()); b != nil {
+ e.Write(b)
+ }
+
+ // Encode head with struct field count.
+ // Head is rewritten later if actual encoded field count is different from struct field count.
+ encodedHeadLen := encodeHead(e, byte(cborTypeMap), uint64(len(flds)))
+
+ kvbegin := e.Len()
+ kvcount := 0
+ for offset := 0; offset < len(flds); offset++ {
+ f := flds[(start+offset)%len(flds)]
+
+ var fv reflect.Value
+ if len(f.idx) == 1 {
+ fv = v.Field(f.idx[0])
+ } else {
+ // Get embedded field value. No error is expected.
+ fv, _ = getFieldValue(v, f.idx, func(reflect.Value) (reflect.Value, error) {
+ // Skip null pointer to embedded struct
+ return reflect.Value{}, nil
+ })
+ if !fv.IsValid() {
+ continue
+ }
+ }
+ if f.omitEmpty {
+ empty, err := f.ief(em, fv)
+ if err != nil {
+ return err
+ }
+ if empty {
+ continue
+ }
+ }
+
+ if !f.keyAsInt && em.fieldName == FieldNameToByteString {
+ e.Write(f.cborNameByteString)
+ } else { // int or text string
+ e.Write(f.cborName)
+ }
+
+ if err := f.ef(e, em, fv); err != nil {
+ return err
+ }
+
+ kvcount++
+ }
+
+ if len(flds) == kvcount {
+ // Encoded element count in head is the same as actual element count.
+ return nil
+ }
+
+ // Overwrite the bytes that were reserved for the head before encoding the map entries.
+ var actualHeadLen int
+ {
+ headbuf := *bytes.NewBuffer(e.Bytes()[kvbegin-encodedHeadLen : kvbegin-encodedHeadLen : kvbegin])
+ actualHeadLen = encodeHead(&headbuf, byte(cborTypeMap), uint64(kvcount))
+ }
+
+ if actualHeadLen == encodedHeadLen {
+ // The bytes reserved for the encoded head were exactly the right size, so the
+ // encoded entries are already in their final positions.
+ return nil
+ }
+
+ // We reserved more bytes than needed for the encoded head, based on the number of fields
+ // encoded. The encoded entries are offset to the right by the number of excess reserved
+ // bytes. Shift the entries left to remove the gap.
+ excessReservedBytes := encodedHeadLen - actualHeadLen
+ dst := e.Bytes()[kvbegin-excessReservedBytes : e.Len()-excessReservedBytes]
+ src := e.Bytes()[kvbegin:e.Len()]
+ copy(dst, src)
+
+ // After shifting, the excess bytes are at the end of the output buffer and they are
+ // garbage.
+ e.Truncate(e.Len() - excessReservedBytes)
+ return nil
+}
+
+func encodeIntf(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if v.IsNil() {
+ e.Write(cborNil)
+ return nil
+ }
+ return encode(e, em, v.Elem())
+}
+
+func encodeTime(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ t := v.Interface().(time.Time)
+ if t.IsZero() {
+ e.Write(cborNil) // Even if tag is required, encode as CBOR null.
+ return nil
+ }
+ if em.timeTag == EncTagRequired {
+ tagNumber := 1
+ if em.time == TimeRFC3339 || em.time == TimeRFC3339Nano {
+ tagNumber = 0
+ }
+ encodeHead(e, byte(cborTypeTag), uint64(tagNumber))
+ }
+ switch em.time {
+ case TimeUnix:
+ secs := t.Unix()
+ return encodeInt(e, em, reflect.ValueOf(secs))
+
+ case TimeUnixMicro:
+ t = t.UTC().Round(time.Microsecond)
+ f := float64(t.UnixNano()) / 1e9
+ return encodeFloat(e, em, reflect.ValueOf(f))
+
+ case TimeUnixDynamic:
+ t = t.UTC().Round(time.Microsecond)
+ secs, nsecs := t.Unix(), uint64(t.Nanosecond())
+ if nsecs == 0 {
+ return encodeInt(e, em, reflect.ValueOf(secs))
+ }
+ f := float64(secs) + float64(nsecs)/1e9
+ return encodeFloat(e, em, reflect.ValueOf(f))
+
+ case TimeRFC3339:
+ s := t.Format(time.RFC3339)
+ return encodeString(e, em, reflect.ValueOf(s))
+
+ default: // TimeRFC3339Nano
+ s := t.Format(time.RFC3339Nano)
+ return encodeString(e, em, reflect.ValueOf(s))
+ }
+}
+
+func encodeBigInt(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if em.bigIntConvert == BigIntConvertReject {
+ return &UnsupportedTypeError{Type: typeBigInt}
+ }
+
+ vbi := v.Interface().(big.Int)
+ sign := vbi.Sign()
+ bi := new(big.Int).SetBytes(vbi.Bytes()) // bi is absolute value of v
+ if sign < 0 {
+ // For negative number, convert to CBOR encoded number (-v-1).
+ bi.Sub(bi, big.NewInt(1))
+ }
+
+ if em.bigIntConvert == BigIntConvertShortest {
+ if bi.IsUint64() {
+ if sign >= 0 {
+ // Encode as CBOR pos int (major type 0)
+ encodeHead(e, byte(cborTypePositiveInt), bi.Uint64())
+ return nil
+ }
+ // Encode as CBOR neg int (major type 1)
+ encodeHead(e, byte(cborTypeNegativeInt), bi.Uint64())
+ return nil
+ }
+ }
+
+ tagNum := 2
+ if sign < 0 {
+ tagNum = 3
+ }
+ // Write tag number
+ encodeHead(e, byte(cborTypeTag), uint64(tagNum))
+ // Write bignum byte string
+ b := bi.Bytes()
+ encodeHead(e, byte(cborTypeByteString), uint64(len(b)))
+ e.Write(b)
+ return nil
+}
+
+type binaryMarshalerEncoder struct {
+ alternateEncode encodeFunc
+ alternateIsEmpty isEmptyFunc
+}
+
+func (bme binaryMarshalerEncoder) encode(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if em.binaryMarshaler != BinaryMarshalerByteString {
+ return bme.alternateEncode(e, em, v)
+ }
+
+ vt := v.Type()
+ m, ok := v.Interface().(encoding.BinaryMarshaler)
+ if !ok {
+ pv := reflect.New(vt)
+ pv.Elem().Set(v)
+ m = pv.Interface().(encoding.BinaryMarshaler)
+ }
+ data, err := m.MarshalBinary()
+ if err != nil {
+ return err
+ }
+ if b := em.encTagBytes(vt); b != nil {
+ e.Write(b)
+ }
+ encodeHead(e, byte(cborTypeByteString), uint64(len(data)))
+ e.Write(data)
+ return nil
+}
+
+func (bme binaryMarshalerEncoder) isEmpty(em *encMode, v reflect.Value) (bool, error) {
+ if em.binaryMarshaler != BinaryMarshalerByteString {
+ return bme.alternateIsEmpty(em, v)
+ }
+
+ m, ok := v.Interface().(encoding.BinaryMarshaler)
+ if !ok {
+ pv := reflect.New(v.Type())
+ pv.Elem().Set(v)
+ m = pv.Interface().(encoding.BinaryMarshaler)
+ }
+ data, err := m.MarshalBinary()
+ if err != nil {
+ return false, err
+ }
+ return len(data) == 0, nil
+}
+
+func encodeMarshalerType(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if em.tagsMd == TagsForbidden && v.Type() == typeRawTag {
+ return errors.New("cbor: cannot encode cbor.RawTag when TagsMd is TagsForbidden")
+ }
+ m, ok := v.Interface().(Marshaler)
+ if !ok {
+ pv := reflect.New(v.Type())
+ pv.Elem().Set(v)
+ m = pv.Interface().(Marshaler)
+ }
+ data, err := m.MarshalCBOR()
+ if err != nil {
+ return err
+ }
+
+ // Verify returned CBOR data item from MarshalCBOR() is well-formed and passes tag validity for builtin tags 0-3.
+ d := decoder{data: data, dm: getMarshalerDecMode(em.indefLength, em.tagsMd)}
+ err = d.wellformed(false, true)
+ if err != nil {
+ return &MarshalerError{typ: v.Type(), err: err}
+ }
+
+ e.Write(data)
+ return nil
+}
+
+func encodeTag(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ if em.tagsMd == TagsForbidden {
+ return errors.New("cbor: cannot encode cbor.Tag when TagsMd is TagsForbidden")
+ }
+
+ t := v.Interface().(Tag)
+
+ if t.Number == 0 && t.Content == nil {
+ // Marshal uninitialized cbor.Tag
+ e.Write(cborNil)
+ return nil
+ }
+
+ // Marshal tag number
+ encodeHead(e, byte(cborTypeTag), t.Number)
+
+ vem := *em // shallow copy
+
+ // For built-in tags, disable settings that may introduce tag validity errors when
+ // marshaling certain Content values.
+ switch t.Number {
+ case tagNumRFC3339Time:
+ vem.stringType = StringToTextString
+ vem.stringMajorType = cborTypeTextString
+ case tagNumUnsignedBignum, tagNumNegativeBignum:
+ vem.byteSliceLaterFormat = ByteSliceLaterFormatNone
+ vem.byteSliceLaterEncodingTag = 0
+ }
+
+ // Marshal tag content
+ return encode(e, &vem, reflect.ValueOf(t.Content))
+}
+
+// encodeHead writes CBOR head of specified type t and returns number of bytes written.
+func encodeHead(e *bytes.Buffer, t byte, n uint64) int {
+ if n <= maxAdditionalInformationWithoutArgument {
+ const headSize = 1
+ e.WriteByte(t | byte(n))
+ return headSize
+ }
+
+ if n <= math.MaxUint8 {
+ const headSize = 2
+ scratch := [headSize]byte{
+ t | byte(additionalInformationWith1ByteArgument),
+ byte(n),
+ }
+ e.Write(scratch[:])
+ return headSize
+ }
+
+ if n <= math.MaxUint16 {
+ const headSize = 3
+ var scratch [headSize]byte
+ scratch[0] = t | byte(additionalInformationWith2ByteArgument)
+ binary.BigEndian.PutUint16(scratch[1:], uint16(n))
+ e.Write(scratch[:])
+ return headSize
+ }
+
+ if n <= math.MaxUint32 {
+ const headSize = 5
+ var scratch [headSize]byte
+ scratch[0] = t | byte(additionalInformationWith4ByteArgument)
+ binary.BigEndian.PutUint32(scratch[1:], uint32(n))
+ e.Write(scratch[:])
+ return headSize
+ }
+
+ const headSize = 9
+ var scratch [headSize]byte
+ scratch[0] = t | byte(additionalInformationWith8ByteArgument)
+ binary.BigEndian.PutUint64(scratch[1:], n)
+ e.Write(scratch[:])
+ return headSize
+}
+
+var (
+ typeMarshaler = reflect.TypeOf((*Marshaler)(nil)).Elem()
+ typeBinaryMarshaler = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem()
+ typeRawMessage = reflect.TypeOf(RawMessage(nil))
+ typeByteString = reflect.TypeOf(ByteString(""))
+)
+
+func getEncodeFuncInternal(t reflect.Type) (ef encodeFunc, ief isEmptyFunc) {
+ k := t.Kind()
+ if k == reflect.Ptr {
+ return getEncodeIndirectValueFunc(t), isEmptyPtr
+ }
+ switch t {
+ case typeSimpleValue:
+ return encodeMarshalerType, isEmptyUint
+
+ case typeTag:
+ return encodeTag, alwaysNotEmpty
+
+ case typeTime:
+ return encodeTime, alwaysNotEmpty
+
+ case typeBigInt:
+ return encodeBigInt, alwaysNotEmpty
+
+ case typeRawMessage:
+ return encodeMarshalerType, isEmptySlice
+
+ case typeByteString:
+ return encodeMarshalerType, isEmptyString
+ }
+ if reflect.PtrTo(t).Implements(typeMarshaler) {
+ return encodeMarshalerType, alwaysNotEmpty
+ }
+ if reflect.PtrTo(t).Implements(typeBinaryMarshaler) {
+ defer func() {
+ // capture encoding method used for modes that disable BinaryMarshaler
+ bme := binaryMarshalerEncoder{
+ alternateEncode: ef,
+ alternateIsEmpty: ief,
+ }
+ ef = bme.encode
+ ief = bme.isEmpty
+ }()
+ }
+ switch k {
+ case reflect.Bool:
+ return encodeBool, isEmptyBool
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return encodeInt, isEmptyInt
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return encodeUint, isEmptyUint
+
+ case reflect.Float32, reflect.Float64:
+ return encodeFloat, isEmptyFloat
+
+ case reflect.String:
+ return encodeString, isEmptyString
+
+ case reflect.Slice:
+ if t.Elem().Kind() == reflect.Uint8 {
+ return encodeByteString, isEmptySlice
+ }
+ fallthrough
+
+ case reflect.Array:
+ f, _ := getEncodeFunc(t.Elem())
+ if f == nil {
+ return nil, nil
+ }
+ return arrayEncodeFunc{f: f}.encode, isEmptySlice
+
+ case reflect.Map:
+ f := getEncodeMapFunc(t)
+ if f == nil {
+ return nil, nil
+ }
+ return f, isEmptyMap
+
+ case reflect.Struct:
+ // Get struct's special field "_" tag options
+ if f, ok := t.FieldByName("_"); ok {
+ tag := f.Tag.Get("cbor")
+ if tag != "-" {
+ if hasToArrayOption(tag) {
+ return encodeStructToArray, isEmptyStruct
+ }
+ }
+ }
+ return encodeStruct, isEmptyStruct
+
+ case reflect.Interface:
+ return encodeIntf, isEmptyIntf
+ }
+ return nil, nil
+}
+
+func getEncodeIndirectValueFunc(t reflect.Type) encodeFunc {
+ for t.Kind() == reflect.Ptr {
+ t = t.Elem()
+ }
+ f, _ := getEncodeFunc(t)
+ if f == nil {
+ return nil
+ }
+ return func(e *bytes.Buffer, em *encMode, v reflect.Value) error {
+ for v.Kind() == reflect.Ptr && !v.IsNil() {
+ v = v.Elem()
+ }
+ if v.Kind() == reflect.Ptr && v.IsNil() {
+ e.Write(cborNil)
+ return nil
+ }
+ return f(e, em, v)
+ }
+}
+
+func alwaysNotEmpty(_ *encMode, _ reflect.Value) (empty bool, err error) {
+ return false, nil
+}
+
+func isEmptyBool(_ *encMode, v reflect.Value) (bool, error) {
+ return !v.Bool(), nil
+}
+
+func isEmptyInt(_ *encMode, v reflect.Value) (bool, error) {
+ return v.Int() == 0, nil
+}
+
+func isEmptyUint(_ *encMode, v reflect.Value) (bool, error) {
+ return v.Uint() == 0, nil
+}
+
+func isEmptyFloat(_ *encMode, v reflect.Value) (bool, error) {
+ return v.Float() == 0.0, nil
+}
+
+func isEmptyString(_ *encMode, v reflect.Value) (bool, error) {
+ return v.Len() == 0, nil
+}
+
+func isEmptySlice(_ *encMode, v reflect.Value) (bool, error) {
+ return v.Len() == 0, nil
+}
+
+func isEmptyMap(_ *encMode, v reflect.Value) (bool, error) {
+ return v.Len() == 0, nil
+}
+
+func isEmptyPtr(_ *encMode, v reflect.Value) (bool, error) {
+ return v.IsNil(), nil
+}
+
+func isEmptyIntf(_ *encMode, v reflect.Value) (bool, error) {
+ return v.IsNil(), nil
+}
+
+func isEmptyStruct(em *encMode, v reflect.Value) (bool, error) {
+ structType, err := getEncodingStructType(v.Type())
+ if err != nil {
+ return false, err
+ }
+
+ if em.omitEmpty == OmitEmptyGoValue {
+ return false, nil
+ }
+
+ if structType.toArray {
+ return len(structType.fields) == 0, nil
+ }
+
+ if len(structType.fields) > len(structType.omitEmptyFieldsIdx) {
+ return false, nil
+ }
+
+ for _, i := range structType.omitEmptyFieldsIdx {
+ f := structType.fields[i]
+
+ // Get field value
+ var fv reflect.Value
+ if len(f.idx) == 1 {
+ fv = v.Field(f.idx[0])
+ } else {
+ // Get embedded field value. No error is expected.
+ fv, _ = getFieldValue(v, f.idx, func(reflect.Value) (reflect.Value, error) {
+ // Skip null pointer to embedded struct
+ return reflect.Value{}, nil
+ })
+ if !fv.IsValid() {
+ continue
+ }
+ }
+
+ empty, err := f.ief(em, fv)
+ if err != nil {
+ return false, err
+ }
+ if !empty {
+ return false, nil
+ }
+ }
+ return true, nil
+}
+
+func cannotFitFloat32(f64 float64) bool {
+ f32 := float32(f64)
+ return float64(f32) != f64
+}
+
+// float32NaNFromReflectValue extracts float32 NaN from reflect.Value while preserving NaN's quiet bit.
+func float32NaNFromReflectValue(v reflect.Value) float32 {
+ // Keith Randall's workaround for issue https://github.com/golang/go/issues/36400
+ p := reflect.New(v.Type())
+ p.Elem().Set(v)
+ f32 := p.Convert(reflect.TypeOf((*float32)(nil))).Elem().Interface().(float32)
+ return f32
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/encode_map.go b/vendor/github.com/fxamacker/cbor/v2/encode_map.go
new file mode 100644
index 000000000..8b4b4bbc5
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/encode_map.go
@@ -0,0 +1,94 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+//go:build go1.20
+
+package cbor
+
+import (
+ "bytes"
+ "reflect"
+ "sync"
+)
+
+type mapKeyValueEncodeFunc struct {
+ kf, ef encodeFunc
+ kpool, vpool sync.Pool
+}
+
+func (me *mapKeyValueEncodeFunc) encodeKeyValues(e *bytes.Buffer, em *encMode, v reflect.Value, kvs []keyValue) error {
+ iterk := me.kpool.Get().(*reflect.Value)
+ defer func() {
+ iterk.SetZero()
+ me.kpool.Put(iterk)
+ }()
+ iterv := me.vpool.Get().(*reflect.Value)
+ defer func() {
+ iterv.SetZero()
+ me.vpool.Put(iterv)
+ }()
+
+ if kvs == nil {
+ for i, iter := 0, v.MapRange(); iter.Next(); i++ {
+ iterk.SetIterKey(iter)
+ iterv.SetIterValue(iter)
+
+ if err := me.kf(e, em, *iterk); err != nil {
+ return err
+ }
+ if err := me.ef(e, em, *iterv); err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+ initial := e.Len()
+ for i, iter := 0, v.MapRange(); iter.Next(); i++ {
+ iterk.SetIterKey(iter)
+ iterv.SetIterValue(iter)
+
+ offset := e.Len()
+ if err := me.kf(e, em, *iterk); err != nil {
+ return err
+ }
+ valueOffset := e.Len()
+ if err := me.ef(e, em, *iterv); err != nil {
+ return err
+ }
+ kvs[i] = keyValue{
+ offset: offset - initial,
+ valueOffset: valueOffset - initial,
+ nextOffset: e.Len() - initial,
+ }
+ }
+
+ return nil
+}
+
+func getEncodeMapFunc(t reflect.Type) encodeFunc {
+ kf, _ := getEncodeFunc(t.Key())
+ ef, _ := getEncodeFunc(t.Elem())
+ if kf == nil || ef == nil {
+ return nil
+ }
+ mkv := &mapKeyValueEncodeFunc{
+ kf: kf,
+ ef: ef,
+ kpool: sync.Pool{
+ New: func() interface{} {
+ rk := reflect.New(t.Key()).Elem()
+ return &rk
+ },
+ },
+ vpool: sync.Pool{
+ New: func() interface{} {
+ rv := reflect.New(t.Elem()).Elem()
+ return &rv
+ },
+ },
+ }
+ return mapEncodeFunc{
+ e: mkv.encodeKeyValues,
+ }.encode
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/encode_map_go117.go b/vendor/github.com/fxamacker/cbor/v2/encode_map_go117.go
new file mode 100644
index 000000000..31c39336d
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/encode_map_go117.go
@@ -0,0 +1,60 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+//go:build !go1.20
+
+package cbor
+
+import (
+ "bytes"
+ "reflect"
+)
+
+type mapKeyValueEncodeFunc struct {
+ kf, ef encodeFunc
+}
+
+func (me *mapKeyValueEncodeFunc) encodeKeyValues(e *bytes.Buffer, em *encMode, v reflect.Value, kvs []keyValue) error {
+ if kvs == nil {
+ for i, iter := 0, v.MapRange(); iter.Next(); i++ {
+ if err := me.kf(e, em, iter.Key()); err != nil {
+ return err
+ }
+ if err := me.ef(e, em, iter.Value()); err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+ initial := e.Len()
+ for i, iter := 0, v.MapRange(); iter.Next(); i++ {
+ offset := e.Len()
+ if err := me.kf(e, em, iter.Key()); err != nil {
+ return err
+ }
+ valueOffset := e.Len()
+ if err := me.ef(e, em, iter.Value()); err != nil {
+ return err
+ }
+ kvs[i] = keyValue{
+ offset: offset - initial,
+ valueOffset: valueOffset - initial,
+ nextOffset: e.Len() - initial,
+ }
+ }
+
+ return nil
+}
+
+func getEncodeMapFunc(t reflect.Type) encodeFunc {
+ kf, _ := getEncodeFunc(t.Key())
+ ef, _ := getEncodeFunc(t.Elem())
+ if kf == nil || ef == nil {
+ return nil
+ }
+ mkv := &mapKeyValueEncodeFunc{kf: kf, ef: ef}
+ return mapEncodeFunc{
+ e: mkv.encodeKeyValues,
+ }.encode
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/simplevalue.go b/vendor/github.com/fxamacker/cbor/v2/simplevalue.go
new file mode 100644
index 000000000..de175cee4
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/simplevalue.go
@@ -0,0 +1,69 @@
+package cbor
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+)
+
+// SimpleValue represents CBOR simple value.
+// CBOR simple value is:
+// - an extension point like CBOR tag.
+// - a subset of CBOR major type 7 that isn't floating-point.
+// - "identified by a number between 0 and 255, but distinct from that number itself".
+// For example, "a simple value 2 is not equivalent to an integer 2" as a CBOR map key.
+//
+// CBOR simple values identified by 20..23 are: "false", "true" , "null", and "undefined".
+// Other CBOR simple values are currently unassigned/reserved by IANA.
+type SimpleValue uint8
+
+var (
+ typeSimpleValue = reflect.TypeOf(SimpleValue(0))
+)
+
+// MarshalCBOR encodes SimpleValue as CBOR simple value (major type 7).
+func (sv SimpleValue) MarshalCBOR() ([]byte, error) {
+ // RFC 8949 3.3. Floating-Point Numbers and Values with No Content says:
+ // "An encoder MUST NOT issue two-byte sequences that start with 0xf8
+ // (major type 7, additional information 24) and continue with a byte
+ // less than 0x20 (32 decimal). Such sequences are not well-formed.
+ // (This implies that an encoder cannot encode false, true, null, or
+ // undefined in two-byte sequences and that only the one-byte variants
+ // of these are well-formed; more generally speaking, each simple value
+ // only has a single representation variant)."
+
+ switch {
+ case sv <= maxSimpleValueInAdditionalInformation:
+ return []byte{byte(cborTypePrimitives) | byte(sv)}, nil
+
+ case sv >= minSimpleValueIn1ByteArgument:
+ return []byte{byte(cborTypePrimitives) | additionalInformationWith1ByteArgument, byte(sv)}, nil
+
+ default:
+ return nil, &UnsupportedValueError{msg: fmt.Sprintf("SimpleValue(%d)", sv)}
+ }
+}
+
+// UnmarshalCBOR decodes CBOR simple value (major type 7) to SimpleValue.
+func (sv *SimpleValue) UnmarshalCBOR(data []byte) error {
+ if sv == nil {
+ return errors.New("cbor.SimpleValue: UnmarshalCBOR on nil pointer")
+ }
+
+ d := decoder{data: data, dm: defaultDecMode}
+
+ typ, ai, val := d.getHead()
+
+ if typ != cborTypePrimitives {
+ return &UnmarshalTypeError{CBORType: typ.String(), GoType: "SimpleValue"}
+ }
+ if ai > additionalInformationWith1ByteArgument {
+ return &UnmarshalTypeError{CBORType: typ.String(), GoType: "SimpleValue", errorMsg: "not simple values"}
+ }
+
+ // It is safe to cast val to uint8 here because
+ // - data is already verified to be well-formed CBOR simple value and
+ // - val is <= math.MaxUint8.
+ *sv = SimpleValue(val)
+ return nil
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/stream.go b/vendor/github.com/fxamacker/cbor/v2/stream.go
new file mode 100644
index 000000000..507ab6c18
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/stream.go
@@ -0,0 +1,277 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+package cbor
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "reflect"
+)
+
+// Decoder reads and decodes CBOR values from io.Reader.
+type Decoder struct {
+ r io.Reader
+ d decoder
+ buf []byte
+ off int // next read offset in buf
+ bytesRead int
+}
+
+// NewDecoder returns a new decoder that reads and decodes from r using
+// the default decoding options.
+func NewDecoder(r io.Reader) *Decoder {
+ return defaultDecMode.NewDecoder(r)
+}
+
+// Decode reads CBOR value and decodes it into the value pointed to by v.
+func (dec *Decoder) Decode(v interface{}) error {
+ _, err := dec.readNext()
+ if err != nil {
+ // Return validation error or read error.
+ return err
+ }
+
+ dec.d.reset(dec.buf[dec.off:])
+ err = dec.d.value(v)
+
+ // Increment dec.off even if decoding err is not nil because
+ // dec.d.off points to the next CBOR data item if current
+ // CBOR data item is valid but failed to be decoded into v.
+ // This allows next CBOR data item to be decoded in next
+ // call to this function.
+ dec.off += dec.d.off
+ dec.bytesRead += dec.d.off
+
+ return err
+}
+
+// Skip skips to the next CBOR data item (if there is any),
+// otherwise it returns error such as io.EOF, io.UnexpectedEOF, etc.
+func (dec *Decoder) Skip() error {
+ n, err := dec.readNext()
+ if err != nil {
+ // Return validation error or read error.
+ return err
+ }
+
+ dec.off += n
+ dec.bytesRead += n
+ return nil
+}
+
+// NumBytesRead returns the number of bytes read.
+func (dec *Decoder) NumBytesRead() int {
+ return dec.bytesRead
+}
+
+// Buffered returns a reader for data remaining in Decoder's buffer.
+// Returned reader is valid until the next call to Decode or Skip.
+func (dec *Decoder) Buffered() io.Reader {
+ return bytes.NewReader(dec.buf[dec.off:])
+}
+
+// readNext() reads next CBOR data item from Reader to buffer.
+// It returns the size of next CBOR data item.
+// It also returns validation error or read error if any.
+func (dec *Decoder) readNext() (int, error) {
+ var readErr error
+ var validErr error
+
+ for {
+ // Process any unread data in dec.buf.
+ if dec.off < len(dec.buf) {
+ dec.d.reset(dec.buf[dec.off:])
+ off := dec.off // Save offset before data validation
+ validErr = dec.d.wellformed(true, false)
+ dec.off = off // Restore offset
+
+ if validErr == nil {
+ return dec.d.off, nil
+ }
+
+ if validErr != io.ErrUnexpectedEOF {
+ return 0, validErr
+ }
+
+ // Process last read error on io.ErrUnexpectedEOF.
+ if readErr != nil {
+ if readErr == io.EOF {
+ // current CBOR data item is incomplete.
+ return 0, io.ErrUnexpectedEOF
+ }
+ return 0, readErr
+ }
+ }
+
+ // More data is needed and there was no read error.
+ var n int
+ for n == 0 {
+ n, readErr = dec.read()
+ if n == 0 && readErr != nil {
+ // No more data can be read and read error is encountered.
+ // At this point, validErr is either nil or io.ErrUnexpectedEOF.
+ if readErr == io.EOF {
+ if validErr == io.ErrUnexpectedEOF {
+ // current CBOR data item is incomplete.
+ return 0, io.ErrUnexpectedEOF
+ }
+ }
+ return 0, readErr
+ }
+ }
+
+ // At this point, dec.buf contains new data from last read (n > 0).
+ }
+}
+
+// read() reads data from Reader to buffer.
+// It returns number of bytes read and any read error encountered.
+// Postconditions:
+// - dec.buf contains previously unread data and new data.
+// - dec.off is 0.
+func (dec *Decoder) read() (int, error) {
+ // Grow buf if needed.
+ const minRead = 512
+ if cap(dec.buf)-len(dec.buf)+dec.off < minRead {
+ oldUnreadBuf := dec.buf[dec.off:]
+ dec.buf = make([]byte, len(dec.buf)-dec.off, 2*cap(dec.buf)+minRead)
+ dec.overwriteBuf(oldUnreadBuf)
+ }
+
+ // Copy unread data over read data and reset off to 0.
+ if dec.off > 0 {
+ dec.overwriteBuf(dec.buf[dec.off:])
+ }
+
+ // Read from reader and reslice buf.
+ n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
+ dec.buf = dec.buf[0 : len(dec.buf)+n]
+ return n, err
+}
+
+func (dec *Decoder) overwriteBuf(newBuf []byte) {
+ n := copy(dec.buf, newBuf)
+ dec.buf = dec.buf[:n]
+ dec.off = 0
+}
+
+// Encoder writes CBOR values to io.Writer.
+type Encoder struct {
+ w io.Writer
+ em *encMode
+ indefTypes []cborType
+}
+
+// NewEncoder returns a new encoder that writes to w using the default encoding options.
+func NewEncoder(w io.Writer) *Encoder {
+ return defaultEncMode.NewEncoder(w)
+}
+
+// Encode writes the CBOR encoding of v.
+func (enc *Encoder) Encode(v interface{}) error {
+ if len(enc.indefTypes) > 0 && v != nil {
+ indefType := enc.indefTypes[len(enc.indefTypes)-1]
+ if indefType == cborTypeTextString {
+ k := reflect.TypeOf(v).Kind()
+ if k != reflect.String {
+ return errors.New("cbor: cannot encode item type " + k.String() + " for indefinite-length text string")
+ }
+ } else if indefType == cborTypeByteString {
+ t := reflect.TypeOf(v)
+ k := t.Kind()
+ if (k != reflect.Array && k != reflect.Slice) || t.Elem().Kind() != reflect.Uint8 {
+ return errors.New("cbor: cannot encode item type " + k.String() + " for indefinite-length byte string")
+ }
+ }
+ }
+
+ buf := getEncodeBuffer()
+
+ err := encode(buf, enc.em, reflect.ValueOf(v))
+ if err == nil {
+ _, err = enc.w.Write(buf.Bytes())
+ }
+
+ putEncodeBuffer(buf)
+ return err
+}
+
+// StartIndefiniteByteString starts byte string encoding of indefinite length.
+// Subsequent calls of (*Encoder).Encode() encodes definite length byte strings
+// ("chunks") as one contiguous string until EndIndefinite is called.
+func (enc *Encoder) StartIndefiniteByteString() error {
+ return enc.startIndefinite(cborTypeByteString)
+}
+
+// StartIndefiniteTextString starts text string encoding of indefinite length.
+// Subsequent calls of (*Encoder).Encode() encodes definite length text strings
+// ("chunks") as one contiguous string until EndIndefinite is called.
+func (enc *Encoder) StartIndefiniteTextString() error {
+ return enc.startIndefinite(cborTypeTextString)
+}
+
+// StartIndefiniteArray starts array encoding of indefinite length.
+// Subsequent calls of (*Encoder).Encode() encodes elements of the array
+// until EndIndefinite is called.
+func (enc *Encoder) StartIndefiniteArray() error {
+ return enc.startIndefinite(cborTypeArray)
+}
+
+// StartIndefiniteMap starts array encoding of indefinite length.
+// Subsequent calls of (*Encoder).Encode() encodes elements of the map
+// until EndIndefinite is called.
+func (enc *Encoder) StartIndefiniteMap() error {
+ return enc.startIndefinite(cborTypeMap)
+}
+
+// EndIndefinite closes last opened indefinite length value.
+func (enc *Encoder) EndIndefinite() error {
+ if len(enc.indefTypes) == 0 {
+ return errors.New("cbor: cannot encode \"break\" code outside indefinite length values")
+ }
+ _, err := enc.w.Write([]byte{cborBreakFlag})
+ if err == nil {
+ enc.indefTypes = enc.indefTypes[:len(enc.indefTypes)-1]
+ }
+ return err
+}
+
+var cborIndefHeader = map[cborType][]byte{
+ cborTypeByteString: {cborByteStringWithIndefiniteLengthHead},
+ cborTypeTextString: {cborTextStringWithIndefiniteLengthHead},
+ cborTypeArray: {cborArrayWithIndefiniteLengthHead},
+ cborTypeMap: {cborMapWithIndefiniteLengthHead},
+}
+
+func (enc *Encoder) startIndefinite(typ cborType) error {
+ if enc.em.indefLength == IndefLengthForbidden {
+ return &IndefiniteLengthError{typ}
+ }
+ _, err := enc.w.Write(cborIndefHeader[typ])
+ if err == nil {
+ enc.indefTypes = append(enc.indefTypes, typ)
+ }
+ return err
+}
+
+// RawMessage is a raw encoded CBOR value.
+type RawMessage []byte
+
+// MarshalCBOR returns m or CBOR nil if m is nil.
+func (m RawMessage) MarshalCBOR() ([]byte, error) {
+ if len(m) == 0 {
+ return cborNil, nil
+ }
+ return m, nil
+}
+
+// UnmarshalCBOR creates a copy of data and saves to *m.
+func (m *RawMessage) UnmarshalCBOR(data []byte) error {
+ if m == nil {
+ return errors.New("cbor.RawMessage: UnmarshalCBOR on nil pointer")
+ }
+ *m = append((*m)[0:0], data...)
+ return nil
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/structfields.go b/vendor/github.com/fxamacker/cbor/v2/structfields.go
new file mode 100644
index 000000000..81228acf0
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/structfields.go
@@ -0,0 +1,260 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+package cbor
+
+import (
+ "reflect"
+ "sort"
+ "strings"
+)
+
+type field struct {
+ name string
+ nameAsInt int64 // used to decoder to match field name with CBOR int
+ cborName []byte
+ cborNameByteString []byte // major type 2 name encoding iff cborName has major type 3
+ idx []int
+ typ reflect.Type
+ ef encodeFunc
+ ief isEmptyFunc
+ typInfo *typeInfo // used to decoder to reuse type info
+ tagged bool // used to choose dominant field (at the same level tagged fields dominate untagged fields)
+ omitEmpty bool // used to skip empty field
+ keyAsInt bool // used to encode/decode field name as int
+}
+
+type fields []*field
+
+// indexFieldSorter sorts fields by field idx at each level, breaking ties with idx depth.
+type indexFieldSorter struct {
+ fields fields
+}
+
+func (x *indexFieldSorter) Len() int {
+ return len(x.fields)
+}
+
+func (x *indexFieldSorter) Swap(i, j int) {
+ x.fields[i], x.fields[j] = x.fields[j], x.fields[i]
+}
+
+func (x *indexFieldSorter) Less(i, j int) bool {
+ iIdx, jIdx := x.fields[i].idx, x.fields[j].idx
+ for k := 0; k < len(iIdx) && k < len(jIdx); k++ {
+ if iIdx[k] != jIdx[k] {
+ return iIdx[k] < jIdx[k]
+ }
+ }
+ return len(iIdx) <= len(jIdx)
+}
+
+// nameLevelAndTagFieldSorter sorts fields by field name, idx depth, and presence of tag.
+type nameLevelAndTagFieldSorter struct {
+ fields fields
+}
+
+func (x *nameLevelAndTagFieldSorter) Len() int {
+ return len(x.fields)
+}
+
+func (x *nameLevelAndTagFieldSorter) Swap(i, j int) {
+ x.fields[i], x.fields[j] = x.fields[j], x.fields[i]
+}
+
+func (x *nameLevelAndTagFieldSorter) Less(i, j int) bool {
+ fi, fj := x.fields[i], x.fields[j]
+ if fi.name != fj.name {
+ return fi.name < fj.name
+ }
+ if len(fi.idx) != len(fj.idx) {
+ return len(fi.idx) < len(fj.idx)
+ }
+ if fi.tagged != fj.tagged {
+ return fi.tagged
+ }
+ return i < j // Field i and j have the same name, depth, and tagged status. Nothing else matters.
+}
+
+// getFields returns visible fields of struct type t following visibility rules for JSON encoding.
+func getFields(t reflect.Type) (flds fields, structOptions string) {
+ // Get special field "_" tag options
+ if f, ok := t.FieldByName("_"); ok {
+ tag := f.Tag.Get("cbor")
+ if tag != "-" {
+ structOptions = tag
+ }
+ }
+
+ // nTypes contains next level anonymous fields' types and indexes
+ // (there can be multiple fields of the same type at the same level)
+ flds, nTypes := appendFields(t, nil, nil, nil)
+
+ if len(nTypes) > 0 {
+
+ var cTypes map[reflect.Type][][]int // current level anonymous fields' types and indexes
+ vTypes := map[reflect.Type]bool{t: true} // visited field types at less nested levels
+
+ for len(nTypes) > 0 {
+ cTypes, nTypes = nTypes, nil
+
+ for t, idx := range cTypes {
+ // If there are multiple anonymous fields of the same struct type at the same level, all are ignored.
+ if len(idx) > 1 {
+ continue
+ }
+
+ // Anonymous field of the same type at deeper nested level is ignored.
+ if vTypes[t] {
+ continue
+ }
+ vTypes[t] = true
+
+ flds, nTypes = appendFields(t, idx[0], flds, nTypes)
+ }
+ }
+ }
+
+ sort.Sort(&nameLevelAndTagFieldSorter{flds})
+
+ // Keep visible fields.
+ j := 0 // index of next unique field
+ for i := 0; i < len(flds); {
+ name := flds[i].name
+ if i == len(flds)-1 || // last field
+ name != flds[i+1].name || // field i has unique field name
+ len(flds[i].idx) < len(flds[i+1].idx) || // field i is at a less nested level than field i+1
+ (flds[i].tagged && !flds[i+1].tagged) { // field i is tagged while field i+1 is not
+ flds[j] = flds[i]
+ j++
+ }
+
+ // Skip fields with the same field name.
+ for i++; i < len(flds) && name == flds[i].name; i++ { //nolint:revive
+ }
+ }
+ if j != len(flds) {
+ flds = flds[:j]
+ }
+
+ // Sort fields by field index
+ sort.Sort(&indexFieldSorter{flds})
+
+ return flds, structOptions
+}
+
+// appendFields appends type t's exportable fields to flds and anonymous struct fields to nTypes .
+func appendFields(
+ t reflect.Type,
+ idx []int,
+ flds fields,
+ nTypes map[reflect.Type][][]int,
+) (
+ _flds fields,
+ _nTypes map[reflect.Type][][]int,
+) {
+ for i := 0; i < t.NumField(); i++ {
+ f := t.Field(i)
+
+ ft := f.Type
+ for ft.Kind() == reflect.Ptr {
+ ft = ft.Elem()
+ }
+
+ if !isFieldExportable(f, ft.Kind()) {
+ continue
+ }
+
+ tag := f.Tag.Get("cbor")
+ if tag == "" {
+ tag = f.Tag.Get("json")
+ }
+ if tag == "-" {
+ continue
+ }
+
+ tagged := tag != ""
+
+ // Parse field tag options
+ var tagFieldName string
+ var omitempty, keyasint bool
+ for j := 0; tag != ""; j++ {
+ var token string
+ idx := strings.IndexByte(tag, ',')
+ if idx == -1 {
+ token, tag = tag, ""
+ } else {
+ token, tag = tag[:idx], tag[idx+1:]
+ }
+ if j == 0 {
+ tagFieldName = token
+ } else {
+ switch token {
+ case "omitempty":
+ omitempty = true
+ case "keyasint":
+ keyasint = true
+ }
+ }
+ }
+
+ fieldName := tagFieldName
+ if tagFieldName == "" {
+ fieldName = f.Name
+ }
+
+ fIdx := make([]int, len(idx)+1)
+ copy(fIdx, idx)
+ fIdx[len(fIdx)-1] = i
+
+ if !f.Anonymous || ft.Kind() != reflect.Struct || tagFieldName != "" {
+ flds = append(flds, &field{
+ name: fieldName,
+ idx: fIdx,
+ typ: f.Type,
+ omitEmpty: omitempty,
+ keyAsInt: keyasint,
+ tagged: tagged})
+ } else {
+ if nTypes == nil {
+ nTypes = make(map[reflect.Type][][]int)
+ }
+ nTypes[ft] = append(nTypes[ft], fIdx)
+ }
+ }
+
+ return flds, nTypes
+}
+
+// isFieldExportable returns true if f is an exportable (regular or anonymous) field or
+// a nonexportable anonymous field of struct type.
+// Nonexportable anonymous field of struct type can contain exportable fields.
+func isFieldExportable(f reflect.StructField, fk reflect.Kind) bool { //nolint:gocritic // ignore hugeParam
+ exportable := f.PkgPath == ""
+ return exportable || (f.Anonymous && fk == reflect.Struct)
+}
+
+type embeddedFieldNullPtrFunc func(reflect.Value) (reflect.Value, error)
+
+// getFieldValue returns field value of struct v by index. When encountering null pointer
+// to anonymous (embedded) struct field, f is called with the last traversed field value.
+func getFieldValue(v reflect.Value, idx []int, f embeddedFieldNullPtrFunc) (fv reflect.Value, err error) {
+ fv = v
+ for i, n := range idx {
+ fv = fv.Field(n)
+
+ if i < len(idx)-1 {
+ if fv.Kind() == reflect.Ptr && fv.Type().Elem().Kind() == reflect.Struct {
+ if fv.IsNil() {
+ // Null pointer to embedded struct field
+ fv, err = f(fv)
+ if err != nil || !fv.IsValid() {
+ return fv, err
+ }
+ }
+ fv = fv.Elem()
+ }
+ }
+ }
+ return fv, nil
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/tag.go b/vendor/github.com/fxamacker/cbor/v2/tag.go
new file mode 100644
index 000000000..5c4d2b7a4
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/tag.go
@@ -0,0 +1,299 @@
+package cbor
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+ "sync"
+)
+
+// Tag represents CBOR tag data, including tag number and unmarshaled tag content. Marshaling and
+// unmarshaling of tag content is subject to any encode and decode options that would apply to
+// enclosed data item if it were to appear outside of a tag.
+type Tag struct {
+ Number uint64
+ Content interface{}
+}
+
+// RawTag represents CBOR tag data, including tag number and raw tag content.
+// RawTag implements Unmarshaler and Marshaler interfaces.
+type RawTag struct {
+ Number uint64
+ Content RawMessage
+}
+
+// UnmarshalCBOR sets *t with tag number and raw tag content copied from data.
+func (t *RawTag) UnmarshalCBOR(data []byte) error {
+ if t == nil {
+ return errors.New("cbor.RawTag: UnmarshalCBOR on nil pointer")
+ }
+
+ // Decoding CBOR null and undefined to cbor.RawTag is no-op.
+ if len(data) == 1 && (data[0] == 0xf6 || data[0] == 0xf7) {
+ return nil
+ }
+
+ d := decoder{data: data, dm: defaultDecMode}
+
+ // Unmarshal tag number.
+ typ, _, num := d.getHead()
+ if typ != cborTypeTag {
+ return &UnmarshalTypeError{CBORType: typ.String(), GoType: typeRawTag.String()}
+ }
+ t.Number = num
+
+ // Unmarshal tag content.
+ c := d.data[d.off:]
+ t.Content = make([]byte, len(c))
+ copy(t.Content, c)
+ return nil
+}
+
+// MarshalCBOR returns CBOR encoding of t.
+func (t RawTag) MarshalCBOR() ([]byte, error) {
+ if t.Number == 0 && len(t.Content) == 0 {
+ // Marshal uninitialized cbor.RawTag
+ b := make([]byte, len(cborNil))
+ copy(b, cborNil)
+ return b, nil
+ }
+
+ e := getEncodeBuffer()
+
+ encodeHead(e, byte(cborTypeTag), t.Number)
+
+ content := t.Content
+ if len(content) == 0 {
+ content = cborNil
+ }
+
+ buf := make([]byte, len(e.Bytes())+len(content))
+ n := copy(buf, e.Bytes())
+ copy(buf[n:], content)
+
+ putEncodeBuffer(e)
+ return buf, nil
+}
+
+// DecTagMode specifies how decoder handles tag number.
+type DecTagMode int
+
+const (
+ // DecTagIgnored makes decoder ignore tag number (skips if present).
+ DecTagIgnored DecTagMode = iota
+
+ // DecTagOptional makes decoder verify tag number if it's present.
+ DecTagOptional
+
+ // DecTagRequired makes decoder verify tag number and tag number must be present.
+ DecTagRequired
+
+ maxDecTagMode
+)
+
+func (dtm DecTagMode) valid() bool {
+ return dtm >= 0 && dtm < maxDecTagMode
+}
+
+// EncTagMode specifies how encoder handles tag number.
+type EncTagMode int
+
+const (
+ // EncTagNone makes encoder not encode tag number.
+ EncTagNone EncTagMode = iota
+
+ // EncTagRequired makes encoder encode tag number.
+ EncTagRequired
+
+ maxEncTagMode
+)
+
+func (etm EncTagMode) valid() bool {
+ return etm >= 0 && etm < maxEncTagMode
+}
+
+// TagOptions specifies how encoder and decoder handle tag number.
+type TagOptions struct {
+ DecTag DecTagMode
+ EncTag EncTagMode
+}
+
+// TagSet is an interface to add and remove tag info. It is used by EncMode and DecMode
+// to provide CBOR tag support.
+type TagSet interface {
+ // Add adds given tag number(s), content type, and tag options to TagSet.
+ Add(opts TagOptions, contentType reflect.Type, num uint64, nestedNum ...uint64) error
+
+ // Remove removes given tag content type from TagSet.
+ Remove(contentType reflect.Type)
+
+ tagProvider
+}
+
+type tagProvider interface {
+ getTagItemFromType(t reflect.Type) *tagItem
+ getTypeFromTagNum(num []uint64) reflect.Type
+}
+
+type tagItem struct {
+ num []uint64
+ cborTagNum []byte
+ contentType reflect.Type
+ opts TagOptions
+}
+
+func (t *tagItem) equalTagNum(num []uint64) bool {
+ // Fast path to compare 1 tag number
+ if len(t.num) == 1 && len(num) == 1 && t.num[0] == num[0] {
+ return true
+ }
+
+ if len(t.num) != len(num) {
+ return false
+ }
+
+ for i := 0; i < len(t.num); i++ {
+ if t.num[i] != num[i] {
+ return false
+ }
+ }
+
+ return true
+}
+
+type (
+ tagSet map[reflect.Type]*tagItem
+
+ syncTagSet struct {
+ sync.RWMutex
+ t tagSet
+ }
+)
+
+func (t tagSet) getTagItemFromType(typ reflect.Type) *tagItem {
+ return t[typ]
+}
+
+func (t tagSet) getTypeFromTagNum(num []uint64) reflect.Type {
+ for typ, tag := range t {
+ if tag.equalTagNum(num) {
+ return typ
+ }
+ }
+ return nil
+}
+
+// NewTagSet returns TagSet (safe for concurrency).
+func NewTagSet() TagSet {
+ return &syncTagSet{t: make(map[reflect.Type]*tagItem)}
+}
+
+// Add adds given tag number(s), content type, and tag options to TagSet.
+func (t *syncTagSet) Add(opts TagOptions, contentType reflect.Type, num uint64, nestedNum ...uint64) error {
+ if contentType == nil {
+ return errors.New("cbor: cannot add nil content type to TagSet")
+ }
+ for contentType.Kind() == reflect.Ptr {
+ contentType = contentType.Elem()
+ }
+ tag, err := newTagItem(opts, contentType, num, nestedNum...)
+ if err != nil {
+ return err
+ }
+ t.Lock()
+ defer t.Unlock()
+ for typ, ti := range t.t {
+ if typ == contentType {
+ return errors.New("cbor: content type " + contentType.String() + " already exists in TagSet")
+ }
+ if ti.equalTagNum(tag.num) {
+ return fmt.Errorf("cbor: tag number %v already exists in TagSet", tag.num)
+ }
+ }
+ t.t[contentType] = tag
+ return nil
+}
+
+// Remove removes given tag content type from TagSet.
+func (t *syncTagSet) Remove(contentType reflect.Type) {
+ for contentType.Kind() == reflect.Ptr {
+ contentType = contentType.Elem()
+ }
+ t.Lock()
+ delete(t.t, contentType)
+ t.Unlock()
+}
+
+func (t *syncTagSet) getTagItemFromType(typ reflect.Type) *tagItem {
+ t.RLock()
+ ti := t.t[typ]
+ t.RUnlock()
+ return ti
+}
+
+func (t *syncTagSet) getTypeFromTagNum(num []uint64) reflect.Type {
+ t.RLock()
+ rt := t.t.getTypeFromTagNum(num)
+ t.RUnlock()
+ return rt
+}
+
+func newTagItem(opts TagOptions, contentType reflect.Type, num uint64, nestedNum ...uint64) (*tagItem, error) {
+ if opts.DecTag == DecTagIgnored && opts.EncTag == EncTagNone {
+ return nil, errors.New("cbor: cannot add tag with DecTagIgnored and EncTagNone options to TagSet")
+ }
+ if contentType.PkgPath() == "" || contentType.Kind() == reflect.Interface {
+ return nil, errors.New("cbor: can only add named types to TagSet, got " + contentType.String())
+ }
+ if contentType == typeTime {
+ return nil, errors.New("cbor: cannot add time.Time to TagSet, use EncOptions.TimeTag and DecOptions.TimeTag instead")
+ }
+ if contentType == typeBigInt {
+ return nil, errors.New("cbor: cannot add big.Int to TagSet, it's built-in and supported automatically")
+ }
+ if contentType == typeTag {
+ return nil, errors.New("cbor: cannot add cbor.Tag to TagSet")
+ }
+ if contentType == typeRawTag {
+ return nil, errors.New("cbor: cannot add cbor.RawTag to TagSet")
+ }
+ if num == 0 || num == 1 {
+ return nil, errors.New("cbor: cannot add tag number 0 or 1 to TagSet, use EncOptions.TimeTag and DecOptions.TimeTag instead")
+ }
+ if num == 2 || num == 3 {
+ return nil, errors.New("cbor: cannot add tag number 2 or 3 to TagSet, it's built-in and supported automatically")
+ }
+ if num == tagNumSelfDescribedCBOR {
+ return nil, errors.New("cbor: cannot add tag number 55799 to TagSet, it's built-in and ignored automatically")
+ }
+
+ te := tagItem{num: []uint64{num}, opts: opts, contentType: contentType}
+ te.num = append(te.num, nestedNum...)
+
+ // Cache encoded tag numbers
+ e := getEncodeBuffer()
+ for _, n := range te.num {
+ encodeHead(e, byte(cborTypeTag), n)
+ }
+ te.cborTagNum = make([]byte, e.Len())
+ copy(te.cborTagNum, e.Bytes())
+ putEncodeBuffer(e)
+
+ return &te, nil
+}
+
+var (
+ typeTag = reflect.TypeOf(Tag{})
+ typeRawTag = reflect.TypeOf(RawTag{})
+)
+
+// WrongTagError describes mismatch between CBOR tag and registered tag.
+type WrongTagError struct {
+ RegisteredType reflect.Type
+ RegisteredTagNum []uint64
+ TagNum []uint64
+}
+
+func (e *WrongTagError) Error() string {
+ return fmt.Sprintf("cbor: wrong tag number for %s, got %v, expected %v", e.RegisteredType.String(), e.TagNum, e.RegisteredTagNum)
+}
diff --git a/vendor/github.com/fxamacker/cbor/v2/valid.go b/vendor/github.com/fxamacker/cbor/v2/valid.go
new file mode 100644
index 000000000..b40793b95
--- /dev/null
+++ b/vendor/github.com/fxamacker/cbor/v2/valid.go
@@ -0,0 +1,394 @@
+// Copyright (c) Faye Amacker. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+package cbor
+
+import (
+ "encoding/binary"
+ "errors"
+ "io"
+ "math"
+ "strconv"
+
+ "github.com/x448/float16"
+)
+
+// SyntaxError is a description of a CBOR syntax error.
+type SyntaxError struct {
+ msg string
+}
+
+func (e *SyntaxError) Error() string { return e.msg }
+
+// SemanticError is a description of a CBOR semantic error.
+type SemanticError struct {
+ msg string
+}
+
+func (e *SemanticError) Error() string { return e.msg }
+
+// MaxNestedLevelError indicates exceeded max nested level of any combination of CBOR arrays/maps/tags.
+type MaxNestedLevelError struct {
+ maxNestedLevels int
+}
+
+func (e *MaxNestedLevelError) Error() string {
+ return "cbor: exceeded max nested level " + strconv.Itoa(e.maxNestedLevels)
+}
+
+// MaxArrayElementsError indicates exceeded max number of elements for CBOR arrays.
+type MaxArrayElementsError struct {
+ maxArrayElements int
+}
+
+func (e *MaxArrayElementsError) Error() string {
+ return "cbor: exceeded max number of elements " + strconv.Itoa(e.maxArrayElements) + " for CBOR array"
+}
+
+// MaxMapPairsError indicates exceeded max number of key-value pairs for CBOR maps.
+type MaxMapPairsError struct {
+ maxMapPairs int
+}
+
+func (e *MaxMapPairsError) Error() string {
+ return "cbor: exceeded max number of key-value pairs " + strconv.Itoa(e.maxMapPairs) + " for CBOR map"
+}
+
+// IndefiniteLengthError indicates found disallowed indefinite length items.
+type IndefiniteLengthError struct {
+ t cborType
+}
+
+func (e *IndefiniteLengthError) Error() string {
+ return "cbor: indefinite-length " + e.t.String() + " isn't allowed"
+}
+
+// TagsMdError indicates found disallowed CBOR tags.
+type TagsMdError struct {
+}
+
+func (e *TagsMdError) Error() string {
+ return "cbor: CBOR tag isn't allowed"
+}
+
+// ExtraneousDataError indicates found extraneous data following well-formed CBOR data item.
+type ExtraneousDataError struct {
+ numOfBytes int // number of bytes of extraneous data
+ index int // location of extraneous data
+}
+
+func (e *ExtraneousDataError) Error() string {
+ return "cbor: " + strconv.Itoa(e.numOfBytes) + " bytes of extraneous data starting at index " + strconv.Itoa(e.index)
+}
+
+// wellformed checks whether the CBOR data item is well-formed.
+// allowExtraData indicates if extraneous data is allowed after the CBOR data item.
+// - use allowExtraData = true when using Decoder.Decode()
+// - use allowExtraData = false when using Unmarshal()
+func (d *decoder) wellformed(allowExtraData bool, checkBuiltinTags bool) error {
+ if len(d.data) == d.off {
+ return io.EOF
+ }
+ _, err := d.wellformedInternal(0, checkBuiltinTags)
+ if err == nil {
+ if !allowExtraData && d.off != len(d.data) {
+ err = &ExtraneousDataError{len(d.data) - d.off, d.off}
+ }
+ }
+ return err
+}
+
+// wellformedInternal checks data's well-formedness and returns max depth and error.
+func (d *decoder) wellformedInternal(depth int, checkBuiltinTags bool) (int, error) { //nolint:gocyclo
+ t, _, val, indefiniteLength, err := d.wellformedHeadWithIndefiniteLengthFlag()
+ if err != nil {
+ return 0, err
+ }
+
+ switch t {
+ case cborTypeByteString, cborTypeTextString:
+ if indefiniteLength {
+ if d.dm.indefLength == IndefLengthForbidden {
+ return 0, &IndefiniteLengthError{t}
+ }
+ return d.wellformedIndefiniteString(t, depth, checkBuiltinTags)
+ }
+ valInt := int(val)
+ if valInt < 0 {
+ // Detect integer overflow
+ return 0, errors.New("cbor: " + t.String() + " length " + strconv.FormatUint(val, 10) + " is too large, causing integer overflow")
+ }
+ if len(d.data)-d.off < valInt { // valInt+off may overflow integer
+ return 0, io.ErrUnexpectedEOF
+ }
+ d.off += valInt
+
+ case cborTypeArray, cborTypeMap:
+ depth++
+ if depth > d.dm.maxNestedLevels {
+ return 0, &MaxNestedLevelError{d.dm.maxNestedLevels}
+ }
+
+ if indefiniteLength {
+ if d.dm.indefLength == IndefLengthForbidden {
+ return 0, &IndefiniteLengthError{t}
+ }
+ return d.wellformedIndefiniteArrayOrMap(t, depth, checkBuiltinTags)
+ }
+
+ valInt := int(val)
+ if valInt < 0 {
+ // Detect integer overflow
+ return 0, errors.New("cbor: " + t.String() + " length " + strconv.FormatUint(val, 10) + " is too large, it would cause integer overflow")
+ }
+
+ if t == cborTypeArray {
+ if valInt > d.dm.maxArrayElements {
+ return 0, &MaxArrayElementsError{d.dm.maxArrayElements}
+ }
+ } else {
+ if valInt > d.dm.maxMapPairs {
+ return 0, &MaxMapPairsError{d.dm.maxMapPairs}
+ }
+ }
+
+ count := 1
+ if t == cborTypeMap {
+ count = 2
+ }
+ maxDepth := depth
+ for j := 0; j < count; j++ {
+ for i := 0; i < valInt; i++ {
+ var dpt int
+ if dpt, err = d.wellformedInternal(depth, checkBuiltinTags); err != nil {
+ return 0, err
+ }
+ if dpt > maxDepth {
+ maxDepth = dpt // Save max depth
+ }
+ }
+ }
+ depth = maxDepth
+
+ case cborTypeTag:
+ if d.dm.tagsMd == TagsForbidden {
+ return 0, &TagsMdError{}
+ }
+
+ tagNum := val
+
+ // Scan nested tag numbers to avoid recursion.
+ for {
+ if len(d.data) == d.off { // Tag number must be followed by tag content.
+ return 0, io.ErrUnexpectedEOF
+ }
+ if checkBuiltinTags {
+ err = validBuiltinTag(tagNum, d.data[d.off])
+ if err != nil {
+ return 0, err
+ }
+ }
+ if d.dm.bignumTag == BignumTagForbidden && (tagNum == 2 || tagNum == 3) {
+ return 0, &UnacceptableDataItemError{
+ CBORType: cborTypeTag.String(),
+ Message: "bignum",
+ }
+ }
+ if getType(d.data[d.off]) != cborTypeTag {
+ break
+ }
+ if _, _, tagNum, err = d.wellformedHead(); err != nil {
+ return 0, err
+ }
+ depth++
+ if depth > d.dm.maxNestedLevels {
+ return 0, &MaxNestedLevelError{d.dm.maxNestedLevels}
+ }
+ }
+ // Check tag content.
+ return d.wellformedInternal(depth, checkBuiltinTags)
+ }
+
+ return depth, nil
+}
+
+// wellformedIndefiniteString checks indefinite length byte/text string's well-formedness and returns max depth and error.
+func (d *decoder) wellformedIndefiniteString(t cborType, depth int, checkBuiltinTags bool) (int, error) {
+ var err error
+ for {
+ if len(d.data) == d.off {
+ return 0, io.ErrUnexpectedEOF
+ }
+ if isBreakFlag(d.data[d.off]) {
+ d.off++
+ break
+ }
+ // Peek ahead to get next type and indefinite length status.
+ nt, ai := parseInitialByte(d.data[d.off])
+ if t != nt {
+ return 0, &SyntaxError{"cbor: wrong element type " + nt.String() + " for indefinite-length " + t.String()}
+ }
+ if additionalInformation(ai).isIndefiniteLength() {
+ return 0, &SyntaxError{"cbor: indefinite-length " + t.String() + " chunk is not definite-length"}
+ }
+ if depth, err = d.wellformedInternal(depth, checkBuiltinTags); err != nil {
+ return 0, err
+ }
+ }
+ return depth, nil
+}
+
+// wellformedIndefiniteArrayOrMap checks indefinite length array/map's well-formedness and returns max depth and error.
+func (d *decoder) wellformedIndefiniteArrayOrMap(t cborType, depth int, checkBuiltinTags bool) (int, error) {
+ var err error
+ maxDepth := depth
+ i := 0
+ for {
+ if len(d.data) == d.off {
+ return 0, io.ErrUnexpectedEOF
+ }
+ if isBreakFlag(d.data[d.off]) {
+ d.off++
+ break
+ }
+ var dpt int
+ if dpt, err = d.wellformedInternal(depth, checkBuiltinTags); err != nil {
+ return 0, err
+ }
+ if dpt > maxDepth {
+ maxDepth = dpt
+ }
+ i++
+ if t == cborTypeArray {
+ if i > d.dm.maxArrayElements {
+ return 0, &MaxArrayElementsError{d.dm.maxArrayElements}
+ }
+ } else {
+ if i%2 == 0 && i/2 > d.dm.maxMapPairs {
+ return 0, &MaxMapPairsError{d.dm.maxMapPairs}
+ }
+ }
+ }
+ if t == cborTypeMap && i%2 == 1 {
+ return 0, &SyntaxError{"cbor: unexpected \"break\" code"}
+ }
+ return maxDepth, nil
+}
+
+func (d *decoder) wellformedHeadWithIndefiniteLengthFlag() (
+ t cborType,
+ ai byte,
+ val uint64,
+ indefiniteLength bool,
+ err error,
+) {
+ t, ai, val, err = d.wellformedHead()
+ if err != nil {
+ return
+ }
+ indefiniteLength = additionalInformation(ai).isIndefiniteLength()
+ return
+}
+
+func (d *decoder) wellformedHead() (t cborType, ai byte, val uint64, err error) {
+ dataLen := len(d.data) - d.off
+ if dataLen == 0 {
+ return 0, 0, 0, io.ErrUnexpectedEOF
+ }
+
+ t, ai = parseInitialByte(d.data[d.off])
+ val = uint64(ai)
+ d.off++
+ dataLen--
+
+ if ai <= maxAdditionalInformationWithoutArgument {
+ return t, ai, val, nil
+ }
+
+ if ai == additionalInformationWith1ByteArgument {
+ const argumentSize = 1
+ if dataLen < argumentSize {
+ return 0, 0, 0, io.ErrUnexpectedEOF
+ }
+ val = uint64(d.data[d.off])
+ d.off++
+ if t == cborTypePrimitives && val < 32 {
+ return 0, 0, 0, &SyntaxError{"cbor: invalid simple value " + strconv.Itoa(int(val)) + " for type " + t.String()}
+ }
+ return t, ai, val, nil
+ }
+
+ if ai == additionalInformationWith2ByteArgument {
+ const argumentSize = 2
+ if dataLen < argumentSize {
+ return 0, 0, 0, io.ErrUnexpectedEOF
+ }
+ val = uint64(binary.BigEndian.Uint16(d.data[d.off : d.off+argumentSize]))
+ d.off += argumentSize
+ if t == cborTypePrimitives {
+ if err := d.acceptableFloat(float64(float16.Frombits(uint16(val)).Float32())); err != nil {
+ return 0, 0, 0, err
+ }
+ }
+ return t, ai, val, nil
+ }
+
+ if ai == additionalInformationWith4ByteArgument {
+ const argumentSize = 4
+ if dataLen < argumentSize {
+ return 0, 0, 0, io.ErrUnexpectedEOF
+ }
+ val = uint64(binary.BigEndian.Uint32(d.data[d.off : d.off+argumentSize]))
+ d.off += argumentSize
+ if t == cborTypePrimitives {
+ if err := d.acceptableFloat(float64(math.Float32frombits(uint32(val)))); err != nil {
+ return 0, 0, 0, err
+ }
+ }
+ return t, ai, val, nil
+ }
+
+ if ai == additionalInformationWith8ByteArgument {
+ const argumentSize = 8
+ if dataLen < argumentSize {
+ return 0, 0, 0, io.ErrUnexpectedEOF
+ }
+ val = binary.BigEndian.Uint64(d.data[d.off : d.off+argumentSize])
+ d.off += argumentSize
+ if t == cborTypePrimitives {
+ if err := d.acceptableFloat(math.Float64frombits(val)); err != nil {
+ return 0, 0, 0, err
+ }
+ }
+ return t, ai, val, nil
+ }
+
+ if additionalInformation(ai).isIndefiniteLength() {
+ switch t {
+ case cborTypePositiveInt, cborTypeNegativeInt, cborTypeTag:
+ return 0, 0, 0, &SyntaxError{"cbor: invalid additional information " + strconv.Itoa(int(ai)) + " for type " + t.String()}
+ case cborTypePrimitives: // 0xff (break code) should not be outside wellformedIndefinite().
+ return 0, 0, 0, &SyntaxError{"cbor: unexpected \"break\" code"}
+ }
+ return t, ai, val, nil
+ }
+
+ // ai == 28, 29, 30
+ return 0, 0, 0, &SyntaxError{"cbor: invalid additional information " + strconv.Itoa(int(ai)) + " for type " + t.String()}
+}
+
+func (d *decoder) acceptableFloat(f float64) error {
+ switch {
+ case d.dm.nanDec == NaNDecodeForbidden && math.IsNaN(f):
+ return &UnacceptableDataItemError{
+ CBORType: cborTypePrimitives.String(),
+ Message: "floating-point NaN",
+ }
+ case d.dm.infDec == InfDecodeForbidden && math.IsInf(f, 0):
+ return &UnacceptableDataItemError{
+ CBORType: cborTypePrimitives.String(),
+ Message: "floating-point infinity",
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/go-logr/logr/slogr/slogr.go b/vendor/github.com/go-logr/logr/slogr/slogr.go
deleted file mode 100644
index 36432c56f..000000000
--- a/vendor/github.com/go-logr/logr/slogr/slogr.go
+++ /dev/null
@@ -1,61 +0,0 @@
-//go:build go1.21
-// +build go1.21
-
-/*
-Copyright 2023 The logr 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 slogr enables usage of a slog.Handler with logr.Logger as front-end
-// API and of a logr.LogSink through the slog.Handler and thus slog.Logger
-// APIs.
-//
-// See the README in the top-level [./logr] package for a discussion of
-// interoperability.
-//
-// Deprecated: use the main logr package instead.
-package slogr
-
-import (
- "log/slog"
-
- "github.com/go-logr/logr"
-)
-
-// NewLogr returns a logr.Logger which writes to the slog.Handler.
-//
-// Deprecated: use [logr.FromSlogHandler] instead.
-func NewLogr(handler slog.Handler) logr.Logger {
- return logr.FromSlogHandler(handler)
-}
-
-// NewSlogHandler returns a slog.Handler which writes to the same sink as the logr.Logger.
-//
-// Deprecated: use [logr.ToSlogHandler] instead.
-func NewSlogHandler(logger logr.Logger) slog.Handler {
- return logr.ToSlogHandler(logger)
-}
-
-// ToSlogHandler returns a slog.Handler which writes to the same sink as the logr.Logger.
-//
-// Deprecated: use [logr.ToSlogHandler] instead.
-func ToSlogHandler(logger logr.Logger) slog.Handler {
- return logr.ToSlogHandler(logger)
-}
-
-// SlogSink is an optional interface that a LogSink can implement to support
-// logging through the slog.Logger or slog.Handler APIs better.
-//
-// Deprecated: use [logr.SlogSink] instead.
-type SlogSink = logr.SlogSink
diff --git a/vendor/github.com/go-openapi/jsonpointer/.golangci.yml b/vendor/github.com/go-openapi/jsonpointer/.golangci.yml
new file mode 100644
index 000000000..22f8d21cc
--- /dev/null
+++ b/vendor/github.com/go-openapi/jsonpointer/.golangci.yml
@@ -0,0 +1,61 @@
+linters-settings:
+ govet:
+ check-shadowing: true
+ golint:
+ min-confidence: 0
+ gocyclo:
+ min-complexity: 45
+ maligned:
+ suggest-new: true
+ dupl:
+ threshold: 200
+ goconst:
+ min-len: 2
+ min-occurrences: 3
+
+linters:
+ enable-all: true
+ disable:
+ - maligned
+ - unparam
+ - lll
+ - gochecknoinits
+ - gochecknoglobals
+ - funlen
+ - godox
+ - gocognit
+ - whitespace
+ - wsl
+ - wrapcheck
+ - testpackage
+ - nlreturn
+ - gomnd
+ - exhaustivestruct
+ - goerr113
+ - errorlint
+ - nestif
+ - godot
+ - gofumpt
+ - paralleltest
+ - tparallel
+ - thelper
+ - ifshort
+ - exhaustruct
+ - varnamelen
+ - gci
+ - depguard
+ - errchkjson
+ - inamedparam
+ - nonamedreturns
+ - musttag
+ - ireturn
+ - forcetypeassert
+ - cyclop
+ # deprecated linters
+ - deadcode
+ - interfacer
+ - scopelint
+ - varcheck
+ - structcheck
+ - golint
+ - nosnakecase
diff --git a/vendor/github.com/go-openapi/jsonpointer/README.md b/vendor/github.com/go-openapi/jsonpointer/README.md
index 813788aff..0108f1d57 100644
--- a/vendor/github.com/go-openapi/jsonpointer/README.md
+++ b/vendor/github.com/go-openapi/jsonpointer/README.md
@@ -1,6 +1,10 @@
-# gojsonpointer [![Build Status](https://travis-ci.org/go-openapi/jsonpointer.svg?branch=master)](https://travis-ci.org/go-openapi/jsonpointer) [![codecov](https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonpointer) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+# gojsonpointer [![Build Status](https://github.com/go-openapi/jsonpointer/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/jsonpointer/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonpointer)
+
+[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE)
+[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/jsonpointer.svg)](https://pkg.go.dev/github.com/go-openapi/jsonpointer)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/jsonpointer)](https://goreportcard.com/report/github.com/go-openapi/jsonpointer)
-[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/jsonpointer?status.svg)](http://godoc.org/github.com/go-openapi/jsonpointer)
An implementation of JSON Pointer - Go language
## Status
diff --git a/vendor/github.com/go-openapi/jsonpointer/pointer.go b/vendor/github.com/go-openapi/jsonpointer/pointer.go
index 7df9853de..d970c7cf4 100644
--- a/vendor/github.com/go-openapi/jsonpointer/pointer.go
+++ b/vendor/github.com/go-openapi/jsonpointer/pointer.go
@@ -26,6 +26,7 @@
package jsonpointer
import (
+ "encoding/json"
"errors"
"fmt"
"reflect"
@@ -40,6 +41,7 @@ const (
pointerSeparator = `/`
invalidStart = `JSON pointer must be empty or start with a "` + pointerSeparator
+ notFound = `Can't find the pointer in the document`
)
var jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem()
@@ -48,13 +50,13 @@ var jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem()
// JSONPointable is an interface for structs to implement when they need to customize the
// json pointer process
type JSONPointable interface {
- JSONLookup(string) (interface{}, error)
+ JSONLookup(string) (any, error)
}
// JSONSetable is an interface for structs to implement when they need to customize the
// json pointer process
type JSONSetable interface {
- JSONSet(string, interface{}) error
+ JSONSet(string, any) error
}
// New creates a new json pointer for the given string
@@ -81,9 +83,7 @@ func (p *Pointer) parse(jsonPointerString string) error {
err = errors.New(invalidStart)
} else {
referenceTokens := strings.Split(jsonPointerString, pointerSeparator)
- for _, referenceToken := range referenceTokens[1:] {
- p.referenceTokens = append(p.referenceTokens, referenceToken)
- }
+ p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...)
}
}
@@ -91,38 +91,58 @@ func (p *Pointer) parse(jsonPointerString string) error {
}
// Get uses the pointer to retrieve a value from a JSON document
-func (p *Pointer) Get(document interface{}) (interface{}, reflect.Kind, error) {
+func (p *Pointer) Get(document any) (any, reflect.Kind, error) {
return p.get(document, swag.DefaultJSONNameProvider)
}
// Set uses the pointer to set a value from a JSON document
-func (p *Pointer) Set(document interface{}, value interface{}) (interface{}, error) {
+func (p *Pointer) Set(document any, value any) (any, error) {
return document, p.set(document, value, swag.DefaultJSONNameProvider)
}
// GetForToken gets a value for a json pointer token 1 level deep
-func GetForToken(document interface{}, decodedToken string) (interface{}, reflect.Kind, error) {
+func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) {
return getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider)
}
// SetForToken gets a value for a json pointer token 1 level deep
-func SetForToken(document interface{}, decodedToken string, value interface{}) (interface{}, error) {
+func SetForToken(document any, decodedToken string, value any) (any, error) {
return document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider)
}
-func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) {
+func isNil(input any) bool {
+ if input == nil {
+ return true
+ }
+
+ kind := reflect.TypeOf(input).Kind()
+ switch kind { //nolint:exhaustive
+ case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan:
+ return reflect.ValueOf(input).IsNil()
+ default:
+ return false
+ }
+}
+
+func getSingleImpl(node any, decodedToken string, nameProvider *swag.NameProvider) (any, reflect.Kind, error) {
rValue := reflect.Indirect(reflect.ValueOf(node))
kind := rValue.Kind()
+ if isNil(node) {
+ return nil, kind, fmt.Errorf("nil value has not field %q", decodedToken)
+ }
- if rValue.Type().Implements(jsonPointableType) {
- r, err := node.(JSONPointable).JSONLookup(decodedToken)
+ switch typed := node.(type) {
+ case JSONPointable:
+ r, err := typed.JSONLookup(decodedToken)
if err != nil {
return nil, kind, err
}
return r, kind, nil
+ case *any: // case of a pointer to interface, that is not resolved by reflect.Indirect
+ return getSingleImpl(*typed, decodedToken, nameProvider)
}
- switch kind {
+ switch kind { //nolint:exhaustive
case reflect.Struct:
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
if !ok {
@@ -159,7 +179,7 @@ func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.Nam
}
-func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *swag.NameProvider) error {
+func setSingleImpl(node, data any, decodedToken string, nameProvider *swag.NameProvider) error {
rValue := reflect.Indirect(reflect.ValueOf(node))
if ns, ok := node.(JSONSetable); ok { // pointer impl
@@ -170,7 +190,7 @@ func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *sw
return node.(JSONSetable).JSONSet(decodedToken, data)
}
- switch rValue.Kind() {
+ switch rValue.Kind() { //nolint:exhaustive
case reflect.Struct:
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
if !ok {
@@ -210,7 +230,7 @@ func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *sw
}
-func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) {
+func (p *Pointer) get(node any, nameProvider *swag.NameProvider) (any, reflect.Kind, error) {
if nameProvider == nil {
nameProvider = swag.DefaultJSONNameProvider
@@ -231,8 +251,7 @@ func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interf
if err != nil {
return nil, knd, err
}
- node, kind = r, knd
-
+ node = r
}
rValue := reflect.ValueOf(node)
@@ -241,11 +260,11 @@ func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interf
return node, kind, nil
}
-func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) error {
+func (p *Pointer) set(node, data any, nameProvider *swag.NameProvider) error {
knd := reflect.ValueOf(node).Kind()
if knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array {
- return fmt.Errorf("only structs, pointers, maps and slices are supported for setting values")
+ return errors.New("only structs, pointers, maps and slices are supported for setting values")
}
if nameProvider == nil {
@@ -284,7 +303,7 @@ func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) e
continue
}
- switch kind {
+ switch kind { //nolint:exhaustive
case reflect.Struct:
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
if !ok {
@@ -363,6 +382,128 @@ func (p *Pointer) String() string {
return pointerString
}
+func (p *Pointer) Offset(document string) (int64, error) {
+ dec := json.NewDecoder(strings.NewReader(document))
+ var offset int64
+ for _, ttk := range p.DecodedTokens() {
+ tk, err := dec.Token()
+ if err != nil {
+ return 0, err
+ }
+ switch tk := tk.(type) {
+ case json.Delim:
+ switch tk {
+ case '{':
+ offset, err = offsetSingleObject(dec, ttk)
+ if err != nil {
+ return 0, err
+ }
+ case '[':
+ offset, err = offsetSingleArray(dec, ttk)
+ if err != nil {
+ return 0, err
+ }
+ default:
+ return 0, fmt.Errorf("invalid token %#v", tk)
+ }
+ default:
+ return 0, fmt.Errorf("invalid token %#v", tk)
+ }
+ }
+ return offset, nil
+}
+
+func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) {
+ for dec.More() {
+ offset := dec.InputOffset()
+ tk, err := dec.Token()
+ if err != nil {
+ return 0, err
+ }
+ switch tk := tk.(type) {
+ case json.Delim:
+ switch tk {
+ case '{':
+ if err = drainSingle(dec); err != nil {
+ return 0, err
+ }
+ case '[':
+ if err = drainSingle(dec); err != nil {
+ return 0, err
+ }
+ }
+ case string:
+ if tk == decodedToken {
+ return offset, nil
+ }
+ default:
+ return 0, fmt.Errorf("invalid token %#v", tk)
+ }
+ }
+ return 0, fmt.Errorf("token reference %q not found", decodedToken)
+}
+
+func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) {
+ idx, err := strconv.Atoi(decodedToken)
+ if err != nil {
+ return 0, fmt.Errorf("token reference %q is not a number: %v", decodedToken, err)
+ }
+ var i int
+ for i = 0; i < idx && dec.More(); i++ {
+ tk, err := dec.Token()
+ if err != nil {
+ return 0, err
+ }
+
+ if delim, isDelim := tk.(json.Delim); isDelim {
+ switch delim {
+ case '{':
+ if err = drainSingle(dec); err != nil {
+ return 0, err
+ }
+ case '[':
+ if err = drainSingle(dec); err != nil {
+ return 0, err
+ }
+ }
+ }
+ }
+
+ if !dec.More() {
+ return 0, fmt.Errorf("token reference %q not found", decodedToken)
+ }
+ return dec.InputOffset(), nil
+}
+
+// drainSingle drains a single level of object or array.
+// The decoder has to guarantee the beginning delim (i.e. '{' or '[') has been consumed.
+func drainSingle(dec *json.Decoder) error {
+ for dec.More() {
+ tk, err := dec.Token()
+ if err != nil {
+ return err
+ }
+ if delim, isDelim := tk.(json.Delim); isDelim {
+ switch delim {
+ case '{':
+ if err = drainSingle(dec); err != nil {
+ return err
+ }
+ case '[':
+ if err = drainSingle(dec); err != nil {
+ return err
+ }
+ }
+ }
+ }
+
+ // Consumes the ending delim
+ if _, err := dec.Token(); err != nil {
+ return err
+ }
+ return nil
+}
+
// Specific JSON pointer encoding here
// ~0 => ~
// ~1 => /
@@ -377,14 +518,14 @@ const (
// Unescape unescapes a json pointer reference token string to the original representation
func Unescape(token string) string {
- step1 := strings.Replace(token, encRefTok1, decRefTok1, -1)
- step2 := strings.Replace(step1, encRefTok0, decRefTok0, -1)
+ step1 := strings.ReplaceAll(token, encRefTok1, decRefTok1)
+ step2 := strings.ReplaceAll(step1, encRefTok0, decRefTok0)
return step2
}
// Escape escapes a pointer reference token string
func Escape(token string) string {
- step1 := strings.Replace(token, decRefTok0, encRefTok0, -1)
- step2 := strings.Replace(step1, decRefTok1, encRefTok1, -1)
+ step1 := strings.ReplaceAll(token, decRefTok0, encRefTok0)
+ step2 := strings.ReplaceAll(step1, decRefTok1, encRefTok1)
return step2
}
diff --git a/vendor/github.com/go-openapi/swag/.gitignore b/vendor/github.com/go-openapi/swag/.gitignore
index d69b53acc..c4b1b64f0 100644
--- a/vendor/github.com/go-openapi/swag/.gitignore
+++ b/vendor/github.com/go-openapi/swag/.gitignore
@@ -2,3 +2,4 @@ secrets.yml
vendor
Godeps
.idea
+*.out
diff --git a/vendor/github.com/go-openapi/swag/.golangci.yml b/vendor/github.com/go-openapi/swag/.golangci.yml
index bf503e400..80e2be004 100644
--- a/vendor/github.com/go-openapi/swag/.golangci.yml
+++ b/vendor/github.com/go-openapi/swag/.golangci.yml
@@ -4,14 +4,14 @@ linters-settings:
golint:
min-confidence: 0
gocyclo:
- min-complexity: 25
+ min-complexity: 45
maligned:
suggest-new: true
dupl:
- threshold: 100
+ threshold: 200
goconst:
min-len: 3
- min-occurrences: 2
+ min-occurrences: 3
linters:
enable-all: true
@@ -20,35 +20,41 @@ linters:
- lll
- gochecknoinits
- gochecknoglobals
- - nlreturn
- - testpackage
+ - funlen
+ - godox
+ - gocognit
+ - whitespace
+ - wsl
- wrapcheck
+ - testpackage
+ - nlreturn
- gomnd
- - exhaustive
- exhaustivestruct
- goerr113
- - wsl
- - whitespace
- - gofumpt
- - godot
+ - errorlint
- nestif
- - godox
- - funlen
- - gci
- - gocognit
+ - godot
+ - gofumpt
- paralleltest
+ - tparallel
- thelper
- ifshort
- - gomoddirectives
- - cyclop
- - forcetypeassert
- - ireturn
- - tagliatelle
- - varnamelen
- - goimports
- - tenv
- - golint
- exhaustruct
- - nilnil
+ - varnamelen
+ - gci
+ - depguard
+ - errchkjson
+ - inamedparam
- nonamedreturns
+ - musttag
+ - ireturn
+ - forcetypeassert
+ - cyclop
+ # deprecated linters
+ - deadcode
+ - interfacer
+ - scopelint
+ - varcheck
+ - structcheck
+ - golint
- nosnakecase
diff --git a/vendor/github.com/go-openapi/swag/BENCHMARK.md b/vendor/github.com/go-openapi/swag/BENCHMARK.md
new file mode 100644
index 000000000..e7f28ed6b
--- /dev/null
+++ b/vendor/github.com/go-openapi/swag/BENCHMARK.md
@@ -0,0 +1,52 @@
+# Benchmarks
+
+## Name mangling utilities
+
+```bash
+go test -bench XXX -run XXX -benchtime 30s
+```
+
+### Benchmarks at b3e7a5386f996177e4808f11acb2aa93a0f660df
+
+```
+goos: linux
+goarch: amd64
+pkg: github.com/go-openapi/swag
+cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
+BenchmarkToXXXName/ToGoName-4 862623 44101 ns/op 10450 B/op 732 allocs/op
+BenchmarkToXXXName/ToVarName-4 853656 40728 ns/op 10468 B/op 734 allocs/op
+BenchmarkToXXXName/ToFileName-4 1268312 27813 ns/op 9785 B/op 617 allocs/op
+BenchmarkToXXXName/ToCommandName-4 1276322 27903 ns/op 9785 B/op 617 allocs/op
+BenchmarkToXXXName/ToHumanNameLower-4 895334 40354 ns/op 10472 B/op 731 allocs/op
+BenchmarkToXXXName/ToHumanNameTitle-4 882441 40678 ns/op 10566 B/op 749 allocs/op
+```
+
+### Benchmarks after PR #79
+
+~ x10 performance improvement and ~ /100 memory allocations.
+
+```
+goos: linux
+goarch: amd64
+pkg: github.com/go-openapi/swag
+cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
+BenchmarkToXXXName/ToGoName-4 9595830 3991 ns/op 42 B/op 5 allocs/op
+BenchmarkToXXXName/ToVarName-4 9194276 3984 ns/op 62 B/op 7 allocs/op
+BenchmarkToXXXName/ToFileName-4 17002711 2123 ns/op 147 B/op 7 allocs/op
+BenchmarkToXXXName/ToCommandName-4 16772926 2111 ns/op 147 B/op 7 allocs/op
+BenchmarkToXXXName/ToHumanNameLower-4 9788331 3749 ns/op 92 B/op 6 allocs/op
+BenchmarkToXXXName/ToHumanNameTitle-4 9188260 3941 ns/op 104 B/op 6 allocs/op
+```
+
+```
+goos: linux
+goarch: amd64
+pkg: github.com/go-openapi/swag
+cpu: AMD Ryzen 7 5800X 8-Core Processor
+BenchmarkToXXXName/ToGoName-16 18527378 1972 ns/op 42 B/op 5 allocs/op
+BenchmarkToXXXName/ToVarName-16 15552692 2093 ns/op 62 B/op 7 allocs/op
+BenchmarkToXXXName/ToFileName-16 32161176 1117 ns/op 147 B/op 7 allocs/op
+BenchmarkToXXXName/ToCommandName-16 32256634 1137 ns/op 147 B/op 7 allocs/op
+BenchmarkToXXXName/ToHumanNameLower-16 18599661 1946 ns/op 92 B/op 6 allocs/op
+BenchmarkToXXXName/ToHumanNameTitle-16 17581353 2054 ns/op 105 B/op 6 allocs/op
+```
diff --git a/vendor/github.com/go-openapi/swag/README.md b/vendor/github.com/go-openapi/swag/README.md
index 217f6fa50..a72922299 100644
--- a/vendor/github.com/go-openapi/swag/README.md
+++ b/vendor/github.com/go-openapi/swag/README.md
@@ -1,7 +1,8 @@
-# Swag [![Build Status](https://travis-ci.org/go-openapi/swag.svg?branch=master)](https://travis-ci.org/go-openapi/swag) [![codecov](https://codecov.io/gh/go-openapi/swag/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/swag) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+# Swag [![Build Status](https://github.com/go-openapi/swag/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/swag/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/swag/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/swag)
+[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE)
-[![GoDoc](https://godoc.org/github.com/go-openapi/swag?status.svg)](http://godoc.org/github.com/go-openapi/swag)
+[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/swag.svg)](https://pkg.go.dev/github.com/go-openapi/swag)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/swag)](https://goreportcard.com/report/github.com/go-openapi/swag)
Contains a bunch of helper functions for go-openapi and go-swagger projects.
@@ -18,4 +19,5 @@ You may also use it standalone for your projects.
This repo has only few dependencies outside of the standard library:
-* YAML utilities depend on gopkg.in/yaml.v2
+* YAML utilities depend on `gopkg.in/yaml.v3`
+* `github.com/mailru/easyjson v0.7.7`
diff --git a/vendor/github.com/go-openapi/swag/initialism_index.go b/vendor/github.com/go-openapi/swag/initialism_index.go
new file mode 100644
index 000000000..20a359bb6
--- /dev/null
+++ b/vendor/github.com/go-openapi/swag/initialism_index.go
@@ -0,0 +1,202 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 swag
+
+import (
+ "sort"
+ "strings"
+ "sync"
+)
+
+var (
+ // commonInitialisms are common acronyms that are kept as whole uppercased words.
+ commonInitialisms *indexOfInitialisms
+
+ // initialisms is a slice of sorted initialisms
+ initialisms []string
+
+ // a copy of initialisms pre-baked as []rune
+ initialismsRunes [][]rune
+ initialismsUpperCased [][]rune
+
+ isInitialism func(string) bool
+
+ maxAllocMatches int
+)
+
+func init() {
+ // Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
+ configuredInitialisms := map[string]bool{
+ "ACL": true,
+ "API": true,
+ "ASCII": true,
+ "CPU": true,
+ "CSS": true,
+ "DNS": true,
+ "EOF": true,
+ "GUID": true,
+ "HTML": true,
+ "HTTPS": true,
+ "HTTP": true,
+ "ID": true,
+ "IP": true,
+ "IPv4": true,
+ "IPv6": true,
+ "JSON": true,
+ "LHS": true,
+ "OAI": true,
+ "QPS": true,
+ "RAM": true,
+ "RHS": true,
+ "RPC": true,
+ "SLA": true,
+ "SMTP": true,
+ "SQL": true,
+ "SSH": true,
+ "TCP": true,
+ "TLS": true,
+ "TTL": true,
+ "UDP": true,
+ "UI": true,
+ "UID": true,
+ "UUID": true,
+ "URI": true,
+ "URL": true,
+ "UTF8": true,
+ "VM": true,
+ "XML": true,
+ "XMPP": true,
+ "XSRF": true,
+ "XSS": true,
+ }
+
+ // a thread-safe index of initialisms
+ commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
+ initialisms = commonInitialisms.sorted()
+ initialismsRunes = asRunes(initialisms)
+ initialismsUpperCased = asUpperCased(initialisms)
+ maxAllocMatches = maxAllocHeuristic(initialismsRunes)
+
+ // a test function
+ isInitialism = commonInitialisms.isInitialism
+}
+
+func asRunes(in []string) [][]rune {
+ out := make([][]rune, len(in))
+ for i, initialism := range in {
+ out[i] = []rune(initialism)
+ }
+
+ return out
+}
+
+func asUpperCased(in []string) [][]rune {
+ out := make([][]rune, len(in))
+
+ for i, initialism := range in {
+ out[i] = []rune(upper(trim(initialism)))
+ }
+
+ return out
+}
+
+func maxAllocHeuristic(in [][]rune) int {
+ heuristic := make(map[rune]int)
+ for _, initialism := range in {
+ heuristic[initialism[0]]++
+ }
+
+ var maxAlloc int
+ for _, val := range heuristic {
+ if val > maxAlloc {
+ maxAlloc = val
+ }
+ }
+
+ return maxAlloc
+}
+
+// AddInitialisms add additional initialisms
+func AddInitialisms(words ...string) {
+ for _, word := range words {
+ // commonInitialisms[upper(word)] = true
+ commonInitialisms.add(upper(word))
+ }
+ // sort again
+ initialisms = commonInitialisms.sorted()
+ initialismsRunes = asRunes(initialisms)
+ initialismsUpperCased = asUpperCased(initialisms)
+}
+
+// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
+// Since go1.9, this may be implemented with sync.Map.
+type indexOfInitialisms struct {
+ sortMutex *sync.Mutex
+ index *sync.Map
+}
+
+func newIndexOfInitialisms() *indexOfInitialisms {
+ return &indexOfInitialisms{
+ sortMutex: new(sync.Mutex),
+ index: new(sync.Map),
+ }
+}
+
+func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
+ m.sortMutex.Lock()
+ defer m.sortMutex.Unlock()
+ for k, v := range initial {
+ m.index.Store(k, v)
+ }
+ return m
+}
+
+func (m *indexOfInitialisms) isInitialism(key string) bool {
+ _, ok := m.index.Load(key)
+ return ok
+}
+
+func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
+ m.index.Store(key, true)
+ return m
+}
+
+func (m *indexOfInitialisms) sorted() (result []string) {
+ m.sortMutex.Lock()
+ defer m.sortMutex.Unlock()
+ m.index.Range(func(key, _ interface{}) bool {
+ k := key.(string)
+ result = append(result, k)
+ return true
+ })
+ sort.Sort(sort.Reverse(byInitialism(result)))
+ return
+}
+
+type byInitialism []string
+
+func (s byInitialism) Len() int {
+ return len(s)
+}
+func (s byInitialism) Swap(i, j int) {
+ s[i], s[j] = s[j], s[i]
+}
+func (s byInitialism) Less(i, j int) bool {
+ if len(s[i]) != len(s[j]) {
+ return len(s[i]) < len(s[j])
+ }
+
+ return strings.Compare(s[i], s[j]) > 0
+}
diff --git a/vendor/github.com/go-openapi/swag/loading.go b/vendor/github.com/go-openapi/swag/loading.go
index 00038c377..783442fdd 100644
--- a/vendor/github.com/go-openapi/swag/loading.go
+++ b/vendor/github.com/go-openapi/swag/loading.go
@@ -21,6 +21,7 @@ import (
"net/http"
"net/url"
"os"
+ "path"
"path/filepath"
"runtime"
"strings"
@@ -40,43 +41,97 @@ var LoadHTTPBasicAuthPassword = ""
var LoadHTTPCustomHeaders = map[string]string{}
// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in
-func LoadFromFileOrHTTP(path string) ([]byte, error) {
- return LoadStrategy(path, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)
+func LoadFromFileOrHTTP(pth string) ([]byte, error) {
+ return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(pth)
}
// LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in
// timeout arg allows for per request overriding of the request timeout
-func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) {
- return LoadStrategy(path, os.ReadFile, loadHTTPBytes(timeout))(path)
+func LoadFromFileOrHTTPWithTimeout(pth string, timeout time.Duration) ([]byte, error) {
+ return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(timeout))(pth)
}
-// LoadStrategy returns a loader function for a given path or uri
-func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) {
- if strings.HasPrefix(path, "http") {
+// LoadStrategy returns a loader function for a given path or URI.
+//
+// The load strategy returns the remote load for any path starting with `http`.
+// So this works for any URI with a scheme `http` or `https`.
+//
+// The fallback strategy is to call the local loader.
+//
+// The local loader takes a local file system path (absolute or relative) as argument,
+// or alternatively a `file://...` URI, **without host** (see also below for windows).
+//
+// There are a few liberalities, initially intended to be tolerant regarding the URI syntax,
+// especially on windows.
+//
+// Before the local loader is called, the given path is transformed:
+// - percent-encoded characters are unescaped
+// - simple paths (e.g. `./folder/file`) are passed as-is
+// - on windows, occurrences of `/` are replaced by `\`, so providing a relative path such a `folder/file` works too.
+//
+// For paths provided as URIs with the "file" scheme, please note that:
+// - `file://` is simply stripped.
+// This means that the host part of the URI is not parsed at all.
+// For example, `file:///folder/file" becomes "/folder/file`,
+// but `file://localhost/folder/file` becomes `localhost/folder/file` on unix systems.
+// Similarly, `file://./folder/file` yields `./folder/file`.
+// - on windows, `file://...` can take a host so as to specify an UNC share location.
+//
+// Reminder about windows-specifics:
+// - `file://host/folder/file` becomes an UNC path like `\\host\folder\file` (no port specification is supported)
+// - `file:///c:/folder/file` becomes `C:\folder\file`
+// - `file://c:/folder/file` is tolerated (without leading `/`) and becomes `c:\folder\file`
+func LoadStrategy(pth string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) {
+ if strings.HasPrefix(pth, "http") {
return remote
}
- return func(pth string) ([]byte, error) {
- upth, err := pathUnescape(pth)
+
+ return func(p string) ([]byte, error) {
+ upth, err := url.PathUnescape(p)
if err != nil {
return nil, err
}
- if strings.HasPrefix(pth, `file://`) {
- if runtime.GOOS == "windows" {
- // support for canonical file URIs on windows.
- // Zero tolerance here for dodgy URIs.
- u, _ := url.Parse(upth)
- if u.Host != "" {
- // assume UNC name (volume share)
- // file://host/share/folder\... ==> \\host\share\path\folder
- // NOTE: UNC port not yet supported
- upth = strings.Join([]string{`\`, u.Host, u.Path}, `\`)
- } else {
- // file:///c:/folder/... ==> just remove the leading slash
- upth = strings.TrimPrefix(upth, `file:///`)
- }
- } else {
- upth = strings.TrimPrefix(upth, `file://`)
+ if !strings.HasPrefix(p, `file://`) {
+ // regular file path provided: just normalize slashes
+ return local(filepath.FromSlash(upth))
+ }
+
+ if runtime.GOOS != "windows" {
+ // crude processing: this leaves full URIs with a host with a (mostly) unexpected result
+ upth = strings.TrimPrefix(upth, `file://`)
+
+ return local(filepath.FromSlash(upth))
+ }
+
+ // windows-only pre-processing of file://... URIs
+
+ // support for canonical file URIs on windows.
+ u, err := url.Parse(filepath.ToSlash(upth))
+ if err != nil {
+ return nil, err
+ }
+
+ if u.Host != "" {
+ // assume UNC name (volume share)
+ // NOTE: UNC port not yet supported
+
+ // when the "host" segment is a drive letter:
+ // file://C:/folder/... => C:\folder
+ upth = path.Clean(strings.Join([]string{u.Host, u.Path}, `/`))
+ if !strings.HasSuffix(u.Host, ":") && u.Host[0] != '.' {
+ // tolerance: if we have a leading dot, this can't be a host
+ // file://host/share/folder\... ==> \\host\share\path\folder
+ upth = "//" + upth
+ }
+ } else {
+ // no host, let's figure out if this is a drive letter
+ upth = strings.TrimPrefix(upth, `file://`)
+ first, _, _ := strings.Cut(strings.TrimPrefix(u.Path, "/"), "/")
+ if strings.HasSuffix(first, ":") {
+ // drive letter in the first segment:
+ // file:///c:/folder/... ==> strip the leading slash
+ upth = strings.TrimPrefix(upth, `/`)
}
}
diff --git a/vendor/github.com/go-openapi/swag/name_lexem.go b/vendor/github.com/go-openapi/swag/name_lexem.go
index aa7f6a9bb..8bb64ac32 100644
--- a/vendor/github.com/go-openapi/swag/name_lexem.go
+++ b/vendor/github.com/go-openapi/swag/name_lexem.go
@@ -14,74 +14,80 @@
package swag
-import "unicode"
+import (
+ "unicode"
+ "unicode/utf8"
+)
type (
- nameLexem interface {
- GetUnsafeGoName() string
- GetOriginal() string
- IsInitialism() bool
- }
+ lexemKind uint8
- initialismNameLexem struct {
+ nameLexem struct {
original string
matchedInitialism string
+ kind lexemKind
}
+)
- casualNameLexem struct {
- original string
- }
+const (
+ lexemKindCasualName lexemKind = iota
+ lexemKindInitialismName
)
-func newInitialismNameLexem(original, matchedInitialism string) *initialismNameLexem {
- return &initialismNameLexem{
+func newInitialismNameLexem(original, matchedInitialism string) nameLexem {
+ return nameLexem{
+ kind: lexemKindInitialismName,
original: original,
matchedInitialism: matchedInitialism,
}
}
-func newCasualNameLexem(original string) *casualNameLexem {
- return &casualNameLexem{
+func newCasualNameLexem(original string) nameLexem {
+ return nameLexem{
+ kind: lexemKindCasualName,
original: original,
}
}
-func (l *initialismNameLexem) GetUnsafeGoName() string {
- return l.matchedInitialism
-}
+func (l nameLexem) GetUnsafeGoName() string {
+ if l.kind == lexemKindInitialismName {
+ return l.matchedInitialism
+ }
+
+ var (
+ first rune
+ rest string
+ )
-func (l *casualNameLexem) GetUnsafeGoName() string {
- var first rune
- var rest string
for i, orig := range l.original {
if i == 0 {
first = orig
continue
}
+
if i > 0 {
rest = l.original[i:]
break
}
}
+
if len(l.original) > 1 {
- return string(unicode.ToUpper(first)) + lower(rest)
+ b := poolOfBuffers.BorrowBuffer(utf8.UTFMax + len(rest))
+ defer func() {
+ poolOfBuffers.RedeemBuffer(b)
+ }()
+ b.WriteRune(unicode.ToUpper(first))
+ b.WriteString(lower(rest))
+ return b.String()
}
return l.original
}
-func (l *initialismNameLexem) GetOriginal() string {
+func (l nameLexem) GetOriginal() string {
return l.original
}
-func (l *casualNameLexem) GetOriginal() string {
- return l.original
-}
-
-func (l *initialismNameLexem) IsInitialism() bool {
- return true
-}
-
-func (l *casualNameLexem) IsInitialism() bool {
- return false
+func (l nameLexem) IsInitialism() bool {
+ return l.kind == lexemKindInitialismName
}
diff --git a/vendor/github.com/go-openapi/swag/post_go18.go b/vendor/github.com/go-openapi/swag/post_go18.go
deleted file mode 100644
index f5228b82c..000000000
--- a/vendor/github.com/go-openapi/swag/post_go18.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2015 go-swagger maintainers
-//
-// 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.
-
-//go:build go1.8
-// +build go1.8
-
-package swag
-
-import "net/url"
-
-func pathUnescape(path string) (string, error) {
- return url.PathUnescape(path)
-}
diff --git a/vendor/github.com/go-openapi/swag/post_go19.go b/vendor/github.com/go-openapi/swag/post_go19.go
deleted file mode 100644
index 7c7da9c08..000000000
--- a/vendor/github.com/go-openapi/swag/post_go19.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2015 go-swagger maintainers
-//
-// 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.
-
-//go:build go1.9
-// +build go1.9
-
-package swag
-
-import (
- "sort"
- "sync"
-)
-
-// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
-// Since go1.9, this may be implemented with sync.Map.
-type indexOfInitialisms struct {
- sortMutex *sync.Mutex
- index *sync.Map
-}
-
-func newIndexOfInitialisms() *indexOfInitialisms {
- return &indexOfInitialisms{
- sortMutex: new(sync.Mutex),
- index: new(sync.Map),
- }
-}
-
-func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
- m.sortMutex.Lock()
- defer m.sortMutex.Unlock()
- for k, v := range initial {
- m.index.Store(k, v)
- }
- return m
-}
-
-func (m *indexOfInitialisms) isInitialism(key string) bool {
- _, ok := m.index.Load(key)
- return ok
-}
-
-func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
- m.index.Store(key, true)
- return m
-}
-
-func (m *indexOfInitialisms) sorted() (result []string) {
- m.sortMutex.Lock()
- defer m.sortMutex.Unlock()
- m.index.Range(func(key, value interface{}) bool {
- k := key.(string)
- result = append(result, k)
- return true
- })
- sort.Sort(sort.Reverse(byInitialism(result)))
- return
-}
diff --git a/vendor/github.com/go-openapi/swag/pre_go18.go b/vendor/github.com/go-openapi/swag/pre_go18.go
deleted file mode 100644
index 2757d9b95..000000000
--- a/vendor/github.com/go-openapi/swag/pre_go18.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2015 go-swagger maintainers
-//
-// 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.
-
-//go:build !go1.8
-// +build !go1.8
-
-package swag
-
-import "net/url"
-
-func pathUnescape(path string) (string, error) {
- return url.QueryUnescape(path)
-}
diff --git a/vendor/github.com/go-openapi/swag/pre_go19.go b/vendor/github.com/go-openapi/swag/pre_go19.go
deleted file mode 100644
index 0565db377..000000000
--- a/vendor/github.com/go-openapi/swag/pre_go19.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2015 go-swagger maintainers
-//
-// 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.
-
-//go:build !go1.9
-// +build !go1.9
-
-package swag
-
-import (
- "sort"
- "sync"
-)
-
-// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
-// Before go1.9, this may be implemented with a mutex on the map.
-type indexOfInitialisms struct {
- getMutex *sync.Mutex
- index map[string]bool
-}
-
-func newIndexOfInitialisms() *indexOfInitialisms {
- return &indexOfInitialisms{
- getMutex: new(sync.Mutex),
- index: make(map[string]bool, 50),
- }
-}
-
-func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
- m.getMutex.Lock()
- defer m.getMutex.Unlock()
- for k, v := range initial {
- m.index[k] = v
- }
- return m
-}
-
-func (m *indexOfInitialisms) isInitialism(key string) bool {
- m.getMutex.Lock()
- defer m.getMutex.Unlock()
- _, ok := m.index[key]
- return ok
-}
-
-func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
- m.getMutex.Lock()
- defer m.getMutex.Unlock()
- m.index[key] = true
- return m
-}
-
-func (m *indexOfInitialisms) sorted() (result []string) {
- m.getMutex.Lock()
- defer m.getMutex.Unlock()
- for k := range m.index {
- result = append(result, k)
- }
- sort.Sort(sort.Reverse(byInitialism(result)))
- return
-}
diff --git a/vendor/github.com/go-openapi/swag/split.go b/vendor/github.com/go-openapi/swag/split.go
index a1825fb7d..274727a86 100644
--- a/vendor/github.com/go-openapi/swag/split.go
+++ b/vendor/github.com/go-openapi/swag/split.go
@@ -15,124 +15,269 @@
package swag
import (
+ "bytes"
+ "sync"
"unicode"
+ "unicode/utf8"
)
-var nameReplaceTable = map[rune]string{
- '@': "At ",
- '&': "And ",
- '|': "Pipe ",
- '$': "Dollar ",
- '!': "Bang ",
- '-': "",
- '_': "",
-}
-
type (
splitter struct {
- postSplitInitialismCheck bool
initialisms []string
+ initialismsRunes [][]rune
+ initialismsUpperCased [][]rune // initialisms cached in their trimmed, upper-cased version
+ postSplitInitialismCheck bool
+ }
+
+ splitterOption func(*splitter)
+
+ initialismMatch struct {
+ body []rune
+ start, end int
+ complete bool
+ }
+ initialismMatches []initialismMatch
+)
+
+type (
+ // memory pools of temporary objects.
+ //
+ // These are used to recycle temporarily allocated objects
+ // and relieve the GC from undue pressure.
+
+ matchesPool struct {
+ *sync.Pool
}
- splitterOption func(*splitter) *splitter
+ buffersPool struct {
+ *sync.Pool
+ }
+
+ lexemsPool struct {
+ *sync.Pool
+ }
+
+ splittersPool struct {
+ *sync.Pool
+ }
)
-// split calls the splitter; splitter provides more control and post options
+var (
+ // poolOfMatches holds temporary slices for recycling during the initialism match process
+ poolOfMatches = matchesPool{
+ Pool: &sync.Pool{
+ New: func() any {
+ s := make(initialismMatches, 0, maxAllocMatches)
+
+ return &s
+ },
+ },
+ }
+
+ poolOfBuffers = buffersPool{
+ Pool: &sync.Pool{
+ New: func() any {
+ return new(bytes.Buffer)
+ },
+ },
+ }
+
+ poolOfLexems = lexemsPool{
+ Pool: &sync.Pool{
+ New: func() any {
+ s := make([]nameLexem, 0, maxAllocMatches)
+
+ return &s
+ },
+ },
+ }
+
+ poolOfSplitters = splittersPool{
+ Pool: &sync.Pool{
+ New: func() any {
+ s := newSplitter()
+
+ return &s
+ },
+ },
+ }
+)
+
+// nameReplaceTable finds a word representation for special characters.
+func nameReplaceTable(r rune) (string, bool) {
+ switch r {
+ case '@':
+ return "At ", true
+ case '&':
+ return "And ", true
+ case '|':
+ return "Pipe ", true
+ case '$':
+ return "Dollar ", true
+ case '!':
+ return "Bang ", true
+ case '-':
+ return "", true
+ case '_':
+ return "", true
+ default:
+ return "", false
+ }
+}
+
+// split calls the splitter.
+//
+// Use newSplitter for more control and options
func split(str string) []string {
- lexems := newSplitter().split(str)
- result := make([]string, 0, len(lexems))
+ s := poolOfSplitters.BorrowSplitter()
+ lexems := s.split(str)
+ result := make([]string, 0, len(*lexems))
- for _, lexem := range lexems {
+ for _, lexem := range *lexems {
result = append(result, lexem.GetOriginal())
}
+ poolOfLexems.RedeemLexems(lexems)
+ poolOfSplitters.RedeemSplitter(s)
return result
}
-func (s *splitter) split(str string) []nameLexem {
- return s.toNameLexems(str)
-}
-
-func newSplitter(options ...splitterOption) *splitter {
- splitter := &splitter{
+func newSplitter(options ...splitterOption) splitter {
+ s := splitter{
postSplitInitialismCheck: false,
initialisms: initialisms,
+ initialismsRunes: initialismsRunes,
+ initialismsUpperCased: initialismsUpperCased,
}
for _, option := range options {
- splitter = option(splitter)
+ option(&s)
}
- return splitter
+ return s
}
// withPostSplitInitialismCheck allows to catch initialisms after main split process
-func withPostSplitInitialismCheck(s *splitter) *splitter {
+func withPostSplitInitialismCheck(s *splitter) {
s.postSplitInitialismCheck = true
+}
+
+func (p matchesPool) BorrowMatches() *initialismMatches {
+ s := p.Get().(*initialismMatches)
+ *s = (*s)[:0] // reset slice, keep allocated capacity
+
return s
}
-type (
- initialismMatch struct {
- start, end int
- body []rune
- complete bool
+func (p buffersPool) BorrowBuffer(size int) *bytes.Buffer {
+ s := p.Get().(*bytes.Buffer)
+ s.Reset()
+
+ if s.Cap() < size {
+ s.Grow(size)
}
- initialismMatches []*initialismMatch
-)
-func (s *splitter) toNameLexems(name string) []nameLexem {
+ return s
+}
+
+func (p lexemsPool) BorrowLexems() *[]nameLexem {
+ s := p.Get().(*[]nameLexem)
+ *s = (*s)[:0] // reset slice, keep allocated capacity
+
+ return s
+}
+
+func (p splittersPool) BorrowSplitter(options ...splitterOption) *splitter {
+ s := p.Get().(*splitter)
+ s.postSplitInitialismCheck = false // reset options
+ for _, apply := range options {
+ apply(s)
+ }
+
+ return s
+}
+
+func (p matchesPool) RedeemMatches(s *initialismMatches) {
+ p.Put(s)
+}
+
+func (p buffersPool) RedeemBuffer(s *bytes.Buffer) {
+ p.Put(s)
+}
+
+func (p lexemsPool) RedeemLexems(s *[]nameLexem) {
+ p.Put(s)
+}
+
+func (p splittersPool) RedeemSplitter(s *splitter) {
+ p.Put(s)
+}
+
+func (m initialismMatch) isZero() bool {
+ return m.start == 0 && m.end == 0
+}
+
+func (s splitter) split(name string) *[]nameLexem {
nameRunes := []rune(name)
matches := s.gatherInitialismMatches(nameRunes)
+ if matches == nil {
+ return poolOfLexems.BorrowLexems()
+ }
+
return s.mapMatchesToNameLexems(nameRunes, matches)
}
-func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches {
- matches := make(initialismMatches, 0)
+func (s splitter) gatherInitialismMatches(nameRunes []rune) *initialismMatches {
+ var matches *initialismMatches
for currentRunePosition, currentRune := range nameRunes {
- newMatches := make(initialismMatches, 0, len(matches))
+ // recycle these allocations as we loop over runes
+ // with such recycling, only 2 slices should be allocated per call
+ // instead of o(n).
+ newMatches := poolOfMatches.BorrowMatches()
// check current initialism matches
- for _, match := range matches {
- if keepCompleteMatch := match.complete; keepCompleteMatch {
- newMatches = append(newMatches, match)
- continue
- }
+ if matches != nil { // skip first iteration
+ for _, match := range *matches {
+ if keepCompleteMatch := match.complete; keepCompleteMatch {
+ *newMatches = append(*newMatches, match)
+ continue
+ }
- // drop failed match
- currentMatchRune := match.body[currentRunePosition-match.start]
- if !s.initialismRuneEqual(currentMatchRune, currentRune) {
- continue
- }
+ // drop failed match
+ currentMatchRune := match.body[currentRunePosition-match.start]
+ if currentMatchRune != currentRune {
+ continue
+ }
- // try to complete ongoing match
- if currentRunePosition-match.start == len(match.body)-1 {
- // we are close; the next step is to check the symbol ahead
- // if it is a small letter, then it is not the end of match
- // but beginning of the next word
-
- if currentRunePosition < len(nameRunes)-1 {
- nextRune := nameRunes[currentRunePosition+1]
- if newWord := unicode.IsLower(nextRune); newWord {
- // oh ok, it was the start of a new word
- continue
+ // try to complete ongoing match
+ if currentRunePosition-match.start == len(match.body)-1 {
+ // we are close; the next step is to check the symbol ahead
+ // if it is a small letter, then it is not the end of match
+ // but beginning of the next word
+
+ if currentRunePosition < len(nameRunes)-1 {
+ nextRune := nameRunes[currentRunePosition+1]
+ if newWord := unicode.IsLower(nextRune); newWord {
+ // oh ok, it was the start of a new word
+ continue
+ }
}
+
+ match.complete = true
+ match.end = currentRunePosition
}
- match.complete = true
- match.end = currentRunePosition
+ *newMatches = append(*newMatches, match)
}
-
- newMatches = append(newMatches, match)
}
// check for new initialism matches
- for _, initialism := range s.initialisms {
- initialismRunes := []rune(initialism)
- if s.initialismRuneEqual(initialismRunes[0], currentRune) {
- newMatches = append(newMatches, &initialismMatch{
+ for i := range s.initialisms {
+ initialismRunes := s.initialismsRunes[i]
+ if initialismRunes[0] == currentRune {
+ *newMatches = append(*newMatches, initialismMatch{
start: currentRunePosition,
body: initialismRunes,
complete: false,
@@ -140,24 +285,28 @@ func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches {
}
}
+ if matches != nil {
+ poolOfMatches.RedeemMatches(matches)
+ }
matches = newMatches
}
+ // up to the caller to redeem this last slice
return matches
}
-func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMatches) []nameLexem {
- nameLexems := make([]nameLexem, 0)
+func (s splitter) mapMatchesToNameLexems(nameRunes []rune, matches *initialismMatches) *[]nameLexem {
+ nameLexems := poolOfLexems.BorrowLexems()
- var lastAcceptedMatch *initialismMatch
- for _, match := range matches {
+ var lastAcceptedMatch initialismMatch
+ for _, match := range *matches {
if !match.complete {
continue
}
- if firstMatch := lastAcceptedMatch == nil; firstMatch {
- nameLexems = append(nameLexems, s.breakCasualString(nameRunes[:match.start])...)
- nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
+ if firstMatch := lastAcceptedMatch.isZero(); firstMatch {
+ s.appendBrokenDownCasualString(nameLexems, nameRunes[:match.start])
+ *nameLexems = append(*nameLexems, s.breakInitialism(string(match.body)))
lastAcceptedMatch = match
@@ -169,63 +318,66 @@ func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMa
}
middle := nameRunes[lastAcceptedMatch.end+1 : match.start]
- nameLexems = append(nameLexems, s.breakCasualString(middle)...)
- nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
+ s.appendBrokenDownCasualString(nameLexems, middle)
+ *nameLexems = append(*nameLexems, s.breakInitialism(string(match.body)))
lastAcceptedMatch = match
}
// we have not found any accepted matches
- if lastAcceptedMatch == nil {
- return s.breakCasualString(nameRunes)
- }
-
- if lastAcceptedMatch.end+1 != len(nameRunes) {
+ if lastAcceptedMatch.isZero() {
+ *nameLexems = (*nameLexems)[:0]
+ s.appendBrokenDownCasualString(nameLexems, nameRunes)
+ } else if lastAcceptedMatch.end+1 != len(nameRunes) {
rest := nameRunes[lastAcceptedMatch.end+1:]
- nameLexems = append(nameLexems, s.breakCasualString(rest)...)
+ s.appendBrokenDownCasualString(nameLexems, rest)
}
- return nameLexems
-}
+ poolOfMatches.RedeemMatches(matches)
-func (s *splitter) initialismRuneEqual(a, b rune) bool {
- return a == b
+ return nameLexems
}
-func (s *splitter) breakInitialism(original string) nameLexem {
+func (s splitter) breakInitialism(original string) nameLexem {
return newInitialismNameLexem(original, original)
}
-func (s *splitter) breakCasualString(str []rune) []nameLexem {
- segments := make([]nameLexem, 0)
- currentSegment := ""
+func (s splitter) appendBrokenDownCasualString(segments *[]nameLexem, str []rune) {
+ currentSegment := poolOfBuffers.BorrowBuffer(len(str)) // unlike strings.Builder, bytes.Buffer initial storage can reused
+ defer func() {
+ poolOfBuffers.RedeemBuffer(currentSegment)
+ }()
addCasualNameLexem := func(original string) {
- segments = append(segments, newCasualNameLexem(original))
+ *segments = append(*segments, newCasualNameLexem(original))
}
addInitialismNameLexem := func(original, match string) {
- segments = append(segments, newInitialismNameLexem(original, match))
+ *segments = append(*segments, newInitialismNameLexem(original, match))
}
- addNameLexem := func(original string) {
- if s.postSplitInitialismCheck {
- for _, initialism := range s.initialisms {
- if upper(initialism) == upper(original) {
- addInitialismNameLexem(original, initialism)
+ var addNameLexem func(string)
+ if s.postSplitInitialismCheck {
+ addNameLexem = func(original string) {
+ for i := range s.initialisms {
+ if isEqualFoldIgnoreSpace(s.initialismsUpperCased[i], original) {
+ addInitialismNameLexem(original, s.initialisms[i])
+
return
}
}
- }
- addCasualNameLexem(original)
+ addCasualNameLexem(original)
+ }
+ } else {
+ addNameLexem = addCasualNameLexem
}
- for _, rn := range string(str) {
- if replace, found := nameReplaceTable[rn]; found {
- if currentSegment != "" {
- addNameLexem(currentSegment)
- currentSegment = ""
+ for _, rn := range str {
+ if replace, found := nameReplaceTable(rn); found {
+ if currentSegment.Len() > 0 {
+ addNameLexem(currentSegment.String())
+ currentSegment.Reset()
}
if replace != "" {
@@ -236,27 +388,121 @@ func (s *splitter) breakCasualString(str []rune) []nameLexem {
}
if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) {
- if currentSegment != "" {
- addNameLexem(currentSegment)
- currentSegment = ""
+ if currentSegment.Len() > 0 {
+ addNameLexem(currentSegment.String())
+ currentSegment.Reset()
}
continue
}
if unicode.IsUpper(rn) {
- if currentSegment != "" {
- addNameLexem(currentSegment)
+ if currentSegment.Len() > 0 {
+ addNameLexem(currentSegment.String())
}
- currentSegment = ""
+ currentSegment.Reset()
}
- currentSegment += string(rn)
+ currentSegment.WriteRune(rn)
+ }
+
+ if currentSegment.Len() > 0 {
+ addNameLexem(currentSegment.String())
}
+}
+
+// isEqualFoldIgnoreSpace is the same as strings.EqualFold, but
+// it ignores leading and trailing blank spaces in the compared
+// string.
+//
+// base is assumed to be composed of upper-cased runes, and be already
+// trimmed.
+//
+// This code is heavily inspired from strings.EqualFold.
+func isEqualFoldIgnoreSpace(base []rune, str string) bool {
+ var i, baseIndex int
+ // equivalent to b := []byte(str), but without data copy
+ b := hackStringBytes(str)
+
+ for i < len(b) {
+ if c := b[i]; c < utf8.RuneSelf {
+ // fast path for ASCII
+ if c != ' ' && c != '\t' {
+ break
+ }
+ i++
+
+ continue
+ }
+
+ // unicode case
+ r, size := utf8.DecodeRune(b[i:])
+ if !unicode.IsSpace(r) {
+ break
+ }
+ i += size
+ }
+
+ if i >= len(b) {
+ return len(base) == 0
+ }
+
+ for _, baseRune := range base {
+ if i >= len(b) {
+ break
+ }
+
+ if c := b[i]; c < utf8.RuneSelf {
+ // single byte rune case (ASCII)
+ if baseRune >= utf8.RuneSelf {
+ return false
+ }
+
+ baseChar := byte(baseRune)
+ if c != baseChar &&
+ !('a' <= c && c <= 'z' && c-'a'+'A' == baseChar) {
+ return false
+ }
+
+ baseIndex++
+ i++
+
+ continue
+ }
+
+ // unicode case
+ r, size := utf8.DecodeRune(b[i:])
+ if unicode.ToUpper(r) != baseRune {
+ return false
+ }
+ baseIndex++
+ i += size
+ }
+
+ if baseIndex != len(base) {
+ return false
+ }
+
+ // all passed: now we should only have blanks
+ for i < len(b) {
+ if c := b[i]; c < utf8.RuneSelf {
+ // fast path for ASCII
+ if c != ' ' && c != '\t' {
+ return false
+ }
+ i++
+
+ continue
+ }
+
+ // unicode case
+ r, size := utf8.DecodeRune(b[i:])
+ if !unicode.IsSpace(r) {
+ return false
+ }
- if currentSegment != "" {
- addNameLexem(currentSegment)
+ i += size
}
- return segments
+ return true
}
diff --git a/vendor/github.com/go-openapi/swag/string_bytes.go b/vendor/github.com/go-openapi/swag/string_bytes.go
new file mode 100644
index 000000000..90745d5ca
--- /dev/null
+++ b/vendor/github.com/go-openapi/swag/string_bytes.go
@@ -0,0 +1,8 @@
+package swag
+
+import "unsafe"
+
+// hackStringBytes returns the (unsafe) underlying bytes slice of a string.
+func hackStringBytes(str string) []byte {
+ return unsafe.Slice(unsafe.StringData(str), len(str))
+}
diff --git a/vendor/github.com/go-openapi/swag/util.go b/vendor/github.com/go-openapi/swag/util.go
index d971fbe34..5051401c4 100644
--- a/vendor/github.com/go-openapi/swag/util.go
+++ b/vendor/github.com/go-openapi/swag/util.go
@@ -18,76 +18,25 @@ import (
"reflect"
"strings"
"unicode"
+ "unicode/utf8"
)
-// commonInitialisms are common acronyms that are kept as whole uppercased words.
-var commonInitialisms *indexOfInitialisms
-
-// initialisms is a slice of sorted initialisms
-var initialisms []string
-
-var isInitialism func(string) bool
-
// GoNamePrefixFunc sets an optional rule to prefix go names
// which do not start with a letter.
//
+// The prefix function is assumed to return a string that starts with an upper case letter.
+//
// e.g. to help convert "123" into "{prefix}123"
//
// The default is to prefix with "X"
var GoNamePrefixFunc func(string) string
-func init() {
- // Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
- var configuredInitialisms = map[string]bool{
- "ACL": true,
- "API": true,
- "ASCII": true,
- "CPU": true,
- "CSS": true,
- "DNS": true,
- "EOF": true,
- "GUID": true,
- "HTML": true,
- "HTTPS": true,
- "HTTP": true,
- "ID": true,
- "IP": true,
- "IPv4": true,
- "IPv6": true,
- "JSON": true,
- "LHS": true,
- "OAI": true,
- "QPS": true,
- "RAM": true,
- "RHS": true,
- "RPC": true,
- "SLA": true,
- "SMTP": true,
- "SQL": true,
- "SSH": true,
- "TCP": true,
- "TLS": true,
- "TTL": true,
- "UDP": true,
- "UI": true,
- "UID": true,
- "UUID": true,
- "URI": true,
- "URL": true,
- "UTF8": true,
- "VM": true,
- "XML": true,
- "XMPP": true,
- "XSRF": true,
- "XSS": true,
+func prefixFunc(name, in string) string {
+ if GoNamePrefixFunc == nil {
+ return "X" + in
}
- // a thread-safe index of initialisms
- commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
- initialisms = commonInitialisms.sorted()
-
- // a test function
- isInitialism = commonInitialisms.isInitialism
+ return GoNamePrefixFunc(name) + in
}
const (
@@ -156,25 +105,9 @@ func SplitByFormat(data, format string) []string {
return result
}
-type byInitialism []string
-
-func (s byInitialism) Len() int {
- return len(s)
-}
-func (s byInitialism) Swap(i, j int) {
- s[i], s[j] = s[j], s[i]
-}
-func (s byInitialism) Less(i, j int) bool {
- if len(s[i]) != len(s[j]) {
- return len(s[i]) < len(s[j])
- }
-
- return strings.Compare(s[i], s[j]) > 0
-}
-
// Removes leading whitespaces
func trim(str string) string {
- return strings.Trim(str, " ")
+ return strings.TrimSpace(str)
}
// Shortcut to strings.ToUpper()
@@ -188,15 +121,20 @@ func lower(str string) string {
}
// Camelize an uppercased word
-func Camelize(word string) (camelized string) {
+func Camelize(word string) string {
+ camelized := poolOfBuffers.BorrowBuffer(len(word))
+ defer func() {
+ poolOfBuffers.RedeemBuffer(camelized)
+ }()
+
for pos, ru := range []rune(word) {
if pos > 0 {
- camelized += string(unicode.ToLower(ru))
+ camelized.WriteRune(unicode.ToLower(ru))
} else {
- camelized += string(unicode.ToUpper(ru))
+ camelized.WriteRune(unicode.ToUpper(ru))
}
}
- return
+ return camelized.String()
}
// ToFileName lowercases and underscores a go type name
@@ -224,33 +162,40 @@ func ToCommandName(name string) string {
// ToHumanNameLower represents a code name as a human series of words
func ToHumanNameLower(name string) string {
- in := newSplitter(withPostSplitInitialismCheck).split(name)
- out := make([]string, 0, len(in))
+ s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
+ in := s.split(name)
+ poolOfSplitters.RedeemSplitter(s)
+ out := make([]string, 0, len(*in))
- for _, w := range in {
+ for _, w := range *in {
if !w.IsInitialism() {
out = append(out, lower(w.GetOriginal()))
} else {
- out = append(out, w.GetOriginal())
+ out = append(out, trim(w.GetOriginal()))
}
}
+ poolOfLexems.RedeemLexems(in)
return strings.Join(out, " ")
}
// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized
func ToHumanNameTitle(name string) string {
- in := newSplitter(withPostSplitInitialismCheck).split(name)
+ s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
+ in := s.split(name)
+ poolOfSplitters.RedeemSplitter(s)
- out := make([]string, 0, len(in))
- for _, w := range in {
- original := w.GetOriginal()
+ out := make([]string, 0, len(*in))
+ for _, w := range *in {
+ original := trim(w.GetOriginal())
if !w.IsInitialism() {
out = append(out, Camelize(original))
} else {
out = append(out, original)
}
}
+ poolOfLexems.RedeemLexems(in)
+
return strings.Join(out, " ")
}
@@ -264,7 +209,7 @@ func ToJSONName(name string) string {
out = append(out, lower(w))
continue
}
- out = append(out, Camelize(w))
+ out = append(out, Camelize(trim(w)))
}
return strings.Join(out, "")
}
@@ -283,35 +228,70 @@ func ToVarName(name string) string {
// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes
func ToGoName(name string) string {
- lexems := newSplitter(withPostSplitInitialismCheck).split(name)
+ s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
+ lexems := s.split(name)
+ poolOfSplitters.RedeemSplitter(s)
+ defer func() {
+ poolOfLexems.RedeemLexems(lexems)
+ }()
+ lexemes := *lexems
+
+ if len(lexemes) == 0 {
+ return ""
+ }
+
+ result := poolOfBuffers.BorrowBuffer(len(name))
+ defer func() {
+ poolOfBuffers.RedeemBuffer(result)
+ }()
+
+ // check if not starting with a letter, upper case
+ firstPart := lexemes[0].GetUnsafeGoName()
+ if lexemes[0].IsInitialism() {
+ firstPart = upper(firstPart)
+ }
+
+ if c := firstPart[0]; c < utf8.RuneSelf {
+ // ASCII
+ switch {
+ case 'A' <= c && c <= 'Z':
+ result.WriteString(firstPart)
+ case 'a' <= c && c <= 'z':
+ result.WriteByte(c - 'a' + 'A')
+ result.WriteString(firstPart[1:])
+ default:
+ result.WriteString(prefixFunc(name, firstPart))
+ // NOTE: no longer check if prefixFunc returns a string that starts with uppercase:
+ // assume this is always the case
+ }
+ } else {
+ // unicode
+ firstRune, _ := utf8.DecodeRuneInString(firstPart)
+ switch {
+ case !unicode.IsLetter(firstRune):
+ result.WriteString(prefixFunc(name, firstPart))
+ case !unicode.IsUpper(firstRune):
+ result.WriteString(prefixFunc(name, firstPart))
+ /*
+ result.WriteRune(unicode.ToUpper(firstRune))
+ result.WriteString(firstPart[offset:])
+ */
+ default:
+ result.WriteString(firstPart)
+ }
+ }
- result := ""
- for _, lexem := range lexems {
+ for _, lexem := range lexemes[1:] {
goName := lexem.GetUnsafeGoName()
// to support old behavior
if lexem.IsInitialism() {
goName = upper(goName)
}
- result += goName
+ result.WriteString(goName)
}
- if len(result) > 0 {
- // Only prefix with X when the first character isn't an ascii letter
- first := []rune(result)[0]
- if !unicode.IsLetter(first) || (first > unicode.MaxASCII && !unicode.IsUpper(first)) {
- if GoNamePrefixFunc == nil {
- return "X" + result
- }
- result = GoNamePrefixFunc(name) + result
- }
- first = []rune(result)[0]
- if unicode.IsLetter(first) && !unicode.IsUpper(first) {
- result = string(append([]rune{unicode.ToUpper(first)}, []rune(result)[1:]...))
- }
- }
-
- return result
+ return result.String()
}
// ContainsStrings searches a slice of strings for a case-sensitive match
@@ -343,7 +323,7 @@ type zeroable interface {
func IsZero(data interface{}) bool {
v := reflect.ValueOf(data)
// check for nil data
- switch v.Kind() {
+ switch v.Kind() { //nolint:exhaustive
case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
if v.IsNil() {
return true
@@ -356,7 +336,7 @@ func IsZero(data interface{}) bool {
}
// continue with slightly more complex reflection
- switch v.Kind() {
+ switch v.Kind() { //nolint:exhaustive
case reflect.String:
return v.Len() == 0
case reflect.Bool:
@@ -376,16 +356,6 @@ func IsZero(data interface{}) bool {
}
}
-// AddInitialisms add additional initialisms
-func AddInitialisms(words ...string) {
- for _, word := range words {
- // commonInitialisms[upper(word)] = true
- commonInitialisms.add(upper(word))
- }
- // sort again
- initialisms = commonInitialisms.sorted()
-}
-
// CommandLineOptionsGroup represents a group of user-defined command line options
type CommandLineOptionsGroup struct {
ShortDescription string
diff --git a/vendor/github.com/go-openapi/swag/yaml.go b/vendor/github.com/go-openapi/swag/yaml.go
index f09ee609f..f59e02593 100644
--- a/vendor/github.com/go-openapi/swag/yaml.go
+++ b/vendor/github.com/go-openapi/swag/yaml.go
@@ -16,8 +16,11 @@ package swag
import (
"encoding/json"
+ "errors"
"fmt"
"path/filepath"
+ "reflect"
+ "sort"
"strconv"
"github.com/mailru/easyjson/jlexer"
@@ -48,7 +51,7 @@ func BytesToYAMLDoc(data []byte) (interface{}, error) {
return nil, err
}
if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode {
- return nil, fmt.Errorf("only YAML documents that are objects are supported")
+ return nil, errors.New("only YAML documents that are objects are supported")
}
return &document, nil
}
@@ -147,7 +150,7 @@ func yamlScalar(node *yaml.Node) (interface{}, error) {
case yamlTimestamp:
return node.Value, nil
case yamlNull:
- return nil, nil
+ return nil, nil //nolint:nilnil
default:
return nil, fmt.Errorf("YAML tag %q is not supported", node.LongTag())
}
@@ -245,7 +248,27 @@ func (s JSONMapSlice) MarshalYAML() (interface{}, error) {
return yaml.Marshal(&n)
}
+func isNil(input interface{}) bool {
+ if input == nil {
+ return true
+ }
+ kind := reflect.TypeOf(input).Kind()
+ switch kind { //nolint:exhaustive
+ case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan:
+ return reflect.ValueOf(input).IsNil()
+ default:
+ return false
+ }
+}
+
func json2yaml(item interface{}) (*yaml.Node, error) {
+ if isNil(item) {
+ return &yaml.Node{
+ Kind: yaml.ScalarNode,
+ Value: "null",
+ }, nil
+ }
+
switch val := item.(type) {
case JSONMapSlice:
var n yaml.Node
@@ -265,7 +288,14 @@ func json2yaml(item interface{}) (*yaml.Node, error) {
case map[string]interface{}:
var n yaml.Node
n.Kind = yaml.MappingNode
- for k, v := range val {
+ keys := make([]string, 0, len(val))
+ for k := range val {
+ keys = append(keys, k)
+ }
+ sort.Strings(keys)
+
+ for _, k := range keys {
+ v := val[k]
childNode, err := json2yaml(v)
if err != nil {
return nil, err
@@ -318,8 +348,9 @@ func json2yaml(item interface{}) (*yaml.Node, error) {
Tag: yamlBoolScalar,
Value: strconv.FormatBool(val),
}, nil
+ default:
+ return nil, fmt.Errorf("unhandled type: %T", val)
}
- return nil, nil
}
// JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice
diff --git a/vendor/github.com/moby/sys/mountinfo/LICENSE b/vendor/github.com/moby/sys/mountinfo/LICENSE
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/vendor/github.com/moby/sys/mountinfo/doc.go b/vendor/github.com/moby/sys/mountinfo/doc.go
new file mode 100644
index 000000000..b80e05efd
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/doc.go
@@ -0,0 +1,44 @@
+// Package mountinfo provides a set of functions to retrieve information about OS mounts.
+//
+// Currently it supports Linux. For historical reasons, there is also some support for FreeBSD and OpenBSD,
+// and a shallow implementation for Windows, but in general this is Linux-only package, so
+// the rest of the document only applies to Linux, unless explicitly specified otherwise.
+//
+// In Linux, information about mounts seen by the current process is available from
+// /proc/self/mountinfo. Note that due to mount namespaces, different processes can
+// see different mounts. A per-process mountinfo table is available from /proc//mountinfo,
+// where is a numerical process identifier.
+//
+// In general, /proc is not a very efficient interface, and mountinfo is not an exception.
+// For example, there is no way to get information about a specific mount point (i.e. it
+// is all-or-nothing). This package tries to hide the /proc ineffectiveness by using
+// parse filters while reading mountinfo. A filter can skip some entries, or stop
+// processing the rest of the file once the needed information is found.
+//
+// For mountinfo filters that accept path as an argument, the path must be absolute,
+// having all symlinks resolved, and being cleaned (i.e. no extra slashes or dots).
+// One way to achieve all of the above is to employ filepath.Abs followed by
+// filepath.EvalSymlinks (the latter calls filepath.Clean on the result so
+// there is no need to explicitly call filepath.Clean).
+//
+// NOTE that in many cases there is no need to consult mountinfo at all. Here are some
+// of the cases where mountinfo should not be parsed:
+//
+// 1. Before performing a mount. Usually, this is not needed, but if required (say to
+// prevent over-mounts), to check whether a directory is mounted, call os.Lstat
+// on it and its parent directory, and compare their st.Sys().(*syscall.Stat_t).Dev
+// fields -- if they differ, then the directory is the mount point. NOTE this does
+// not work for bind mounts. Optionally, the filesystem type can also be checked
+// by calling unix.Statfs and checking the Type field (i.e. filesystem type).
+//
+// 2. After performing a mount. If there is no error returned, the mount succeeded;
+// checking the mount table for a new mount is redundant and expensive.
+//
+// 3. Before performing an unmount. It is more efficient to do an unmount and ignore
+// a specific error (EINVAL) which tells the directory is not mounted.
+//
+// 4. After performing an unmount. If there is no error returned, the unmount succeeded.
+//
+// 5. To find the mount point root of a specific directory. You can perform os.Stat()
+// on the directory and traverse up until the Dev field of a parent directory differs.
+package mountinfo
diff --git a/vendor/github.com/moby/sys/mountinfo/mounted_linux.go b/vendor/github.com/moby/sys/mountinfo/mounted_linux.go
new file mode 100644
index 000000000..58f13c269
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mounted_linux.go
@@ -0,0 +1,101 @@
+package mountinfo
+
+import (
+ "os"
+ "path/filepath"
+
+ "golang.org/x/sys/unix"
+)
+
+// MountedFast is a method of detecting a mount point without reading
+// mountinfo from procfs. A caller can only trust the result if no error
+// and sure == true are returned. Otherwise, other methods (e.g. parsing
+// /proc/mounts) have to be used. If unsure, use Mounted instead (which
+// uses MountedFast, but falls back to parsing mountinfo if needed).
+//
+// If a non-existent path is specified, an appropriate error is returned.
+// In case the caller is not interested in this particular error, it should
+// be handled separately using e.g. errors.Is(err, fs.ErrNotExist).
+//
+// This function is only available on Linux. When available (since kernel
+// v5.6), openat2(2) syscall is used to reliably detect all mounts. Otherwise,
+// the implementation falls back to using stat(2), which can reliably detect
+// normal (but not bind) mounts.
+func MountedFast(path string) (mounted, sure bool, err error) {
+ // Root is always mounted.
+ if path == string(os.PathSeparator) {
+ return true, true, nil
+ }
+
+ path, err = normalizePath(path)
+ if err != nil {
+ return false, false, err
+ }
+ mounted, sure, err = mountedFast(path)
+ return
+}
+
+// mountedByOpenat2 is a method of detecting a mount that works for all kinds
+// of mounts (incl. bind mounts), but requires a recent (v5.6+) linux kernel.
+func mountedByOpenat2(path string) (bool, error) {
+ dir, last := filepath.Split(path)
+
+ dirfd, err := unix.Openat2(unix.AT_FDCWD, dir, &unix.OpenHow{
+ Flags: unix.O_PATH | unix.O_CLOEXEC,
+ })
+ if err != nil {
+ return false, &os.PathError{Op: "openat2", Path: dir, Err: err}
+ }
+ fd, err := unix.Openat2(dirfd, last, &unix.OpenHow{
+ Flags: unix.O_PATH | unix.O_CLOEXEC | unix.O_NOFOLLOW,
+ Resolve: unix.RESOLVE_NO_XDEV,
+ })
+ _ = unix.Close(dirfd)
+ switch err {
+ case nil: // definitely not a mount
+ _ = unix.Close(fd)
+ return false, nil
+ case unix.EXDEV: // definitely a mount
+ return true, nil
+ }
+ // not sure
+ return false, &os.PathError{Op: "openat2", Path: path, Err: err}
+}
+
+// mountedFast is similar to MountedFast, except it expects a normalized path.
+func mountedFast(path string) (mounted, sure bool, err error) {
+ // Root is always mounted.
+ if path == string(os.PathSeparator) {
+ return true, true, nil
+ }
+
+ // Try a fast path, using openat2() with RESOLVE_NO_XDEV.
+ mounted, err = mountedByOpenat2(path)
+ if err == nil {
+ return mounted, true, nil
+ }
+
+ // Another fast path: compare st.st_dev fields.
+ mounted, err = mountedByStat(path)
+ // This does not work for bind mounts, so false negative
+ // is possible, therefore only trust if return is true.
+ if mounted && err == nil {
+ return true, true, nil
+ }
+
+ return
+}
+
+func mounted(path string) (bool, error) {
+ path, err := normalizePath(path)
+ if err != nil {
+ return false, err
+ }
+ mounted, sure, err := mountedFast(path)
+ if sure && err == nil {
+ return mounted, nil
+ }
+
+ // Fallback to parsing mountinfo.
+ return mountedByMountinfo(path)
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mounted_unix.go b/vendor/github.com/moby/sys/mountinfo/mounted_unix.go
new file mode 100644
index 000000000..c7b7678f9
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mounted_unix.go
@@ -0,0 +1,53 @@
+//go:build linux || freebsd || openbsd || darwin
+// +build linux freebsd openbsd darwin
+
+package mountinfo
+
+import (
+ "os"
+ "path/filepath"
+
+ "golang.org/x/sys/unix"
+)
+
+func mountedByStat(path string) (bool, error) {
+ var st unix.Stat_t
+
+ if err := unix.Lstat(path, &st); err != nil {
+ return false, &os.PathError{Op: "stat", Path: path, Err: err}
+ }
+ dev := st.Dev
+ parent := filepath.Dir(path)
+ if err := unix.Lstat(parent, &st); err != nil {
+ return false, &os.PathError{Op: "stat", Path: parent, Err: err}
+ }
+ if dev != st.Dev {
+ // Device differs from that of parent,
+ // so definitely a mount point.
+ return true, nil
+ }
+ // NB: this does not detect bind mounts on Linux.
+ return false, nil
+}
+
+func normalizePath(path string) (realPath string, err error) {
+ if realPath, err = filepath.Abs(path); err != nil {
+ return "", err
+ }
+ if realPath, err = filepath.EvalSymlinks(realPath); err != nil {
+ return "", err
+ }
+ if _, err := os.Stat(realPath); err != nil {
+ return "", err
+ }
+ return realPath, nil
+}
+
+func mountedByMountinfo(path string) (bool, error) {
+ entries, err := GetMounts(SingleEntryFilter(path))
+ if err != nil {
+ return false, err
+ }
+
+ return len(entries) > 0, nil
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo.go b/vendor/github.com/moby/sys/mountinfo/mountinfo.go
new file mode 100644
index 000000000..574aeb876
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo.go
@@ -0,0 +1,67 @@
+package mountinfo
+
+import (
+ "os"
+)
+
+// GetMounts retrieves a list of mounts for the current running process,
+// with an optional filter applied (use nil for no filter).
+func GetMounts(f FilterFunc) ([]*Info, error) {
+ return parseMountTable(f)
+}
+
+// Mounted determines if a specified path is a mount point. In case of any
+// error, false (and an error) is returned.
+//
+// If a non-existent path is specified, an appropriate error is returned.
+// In case the caller is not interested in this particular error, it should
+// be handled separately using e.g. errors.Is(err, fs.ErrNotExist).
+func Mounted(path string) (bool, error) {
+ // root is always mounted
+ if path == string(os.PathSeparator) {
+ return true, nil
+ }
+ return mounted(path)
+}
+
+// Info reveals information about a particular mounted filesystem. This
+// struct is populated from the content in the /proc//mountinfo file.
+type Info struct {
+ // ID is a unique identifier of the mount (may be reused after umount).
+ ID int
+
+ // Parent is the ID of the parent mount (or of self for the root
+ // of this mount namespace's mount tree).
+ Parent int
+
+ // Major and Minor are the major and the minor components of the Dev
+ // field of unix.Stat_t structure returned by unix.*Stat calls for
+ // files on this filesystem.
+ Major, Minor int
+
+ // Root is the pathname of the directory in the filesystem which forms
+ // the root of this mount.
+ Root string
+
+ // Mountpoint is the pathname of the mount point relative to the
+ // process's root directory.
+ Mountpoint string
+
+ // Options is a comma-separated list of mount options.
+ Options string
+
+ // Optional are zero or more fields of the form "tag[:value]",
+ // separated by a space. Currently, the possible optional fields are
+ // "shared", "master", "propagate_from", and "unbindable". For more
+ // information, see mount_namespaces(7) Linux man page.
+ Optional string
+
+ // FSType is the filesystem type in the form "type[.subtype]".
+ FSType string
+
+ // Source is filesystem-specific information, or "none".
+ Source string
+
+ // VFSOptions is a comma-separated list of superblock options.
+ VFSOptions string
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go
new file mode 100644
index 000000000..8420f58c7
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go
@@ -0,0 +1,56 @@
+//go:build freebsd || openbsd || darwin
+// +build freebsd openbsd darwin
+
+package mountinfo
+
+import "golang.org/x/sys/unix"
+
+// parseMountTable returns information about mounted filesystems
+func parseMountTable(filter FilterFunc) ([]*Info, error) {
+ count, err := unix.Getfsstat(nil, unix.MNT_WAIT)
+ if err != nil {
+ return nil, err
+ }
+
+ entries := make([]unix.Statfs_t, count)
+ _, err = unix.Getfsstat(entries, unix.MNT_WAIT)
+ if err != nil {
+ return nil, err
+ }
+
+ var out []*Info
+ for _, entry := range entries {
+ var skip, stop bool
+ mountinfo := getMountinfo(&entry)
+
+ if filter != nil {
+ // filter out entries we're not interested in
+ skip, stop = filter(mountinfo)
+ if skip {
+ continue
+ }
+ }
+
+ out = append(out, mountinfo)
+ if stop {
+ break
+ }
+ }
+ return out, nil
+}
+
+func mounted(path string) (bool, error) {
+ path, err := normalizePath(path)
+ if err != nil {
+ return false, err
+ }
+ // Fast path: compare st.st_dev fields.
+ // This should always work for FreeBSD and OpenBSD.
+ mounted, err := mountedByStat(path)
+ if err == nil {
+ return mounted, nil
+ }
+
+ // Fallback to parsing mountinfo
+ return mountedByMountinfo(path)
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go
new file mode 100644
index 000000000..16079c3c5
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go
@@ -0,0 +1,63 @@
+package mountinfo
+
+import "strings"
+
+// FilterFunc is a type defining a callback function for GetMount(),
+// used to filter out mountinfo entries we're not interested in,
+// and/or stop further processing if we found what we wanted.
+//
+// It takes a pointer to the Info struct (fully populated with all available
+// fields on the GOOS platform), and returns two booleans:
+//
+// skip: true if the entry should be skipped;
+//
+// stop: true if parsing should be stopped after the entry.
+type FilterFunc func(*Info) (skip, stop bool)
+
+// PrefixFilter discards all entries whose mount points do not start with, or
+// are equal to the path specified in prefix. The prefix path must be absolute,
+// have all symlinks resolved, and cleaned (i.e. no extra slashes or dots).
+//
+// PrefixFilter treats prefix as a path, not a partial prefix, which means that
+// given "/foo", "/foo/bar" and "/foobar" entries, PrefixFilter("/foo") returns
+// "/foo" and "/foo/bar", and discards "/foobar".
+func PrefixFilter(prefix string) FilterFunc {
+ return func(m *Info) (bool, bool) {
+ skip := !strings.HasPrefix(m.Mountpoint+"/", prefix+"/")
+ return skip, false
+ }
+}
+
+// SingleEntryFilter looks for a specific entry.
+func SingleEntryFilter(mp string) FilterFunc {
+ return func(m *Info) (bool, bool) {
+ if m.Mountpoint == mp {
+ return false, true // don't skip, stop now
+ }
+ return true, false // skip, keep going
+ }
+}
+
+// ParentsFilter returns all entries whose mount points
+// can be parents of a path specified, discarding others.
+//
+// For example, given /var/lib/docker/something, entries
+// like /var/lib/docker, /var and / are returned.
+func ParentsFilter(path string) FilterFunc {
+ return func(m *Info) (bool, bool) {
+ skip := !strings.HasPrefix(path, m.Mountpoint)
+ return skip, false
+ }
+}
+
+// FSTypeFilter returns all entries that match provided fstype(s).
+func FSTypeFilter(fstype ...string) FilterFunc {
+ return func(m *Info) (bool, bool) {
+ for _, t := range fstype {
+ if m.FSType == t {
+ return false, false // don't skip, keep going
+ }
+ }
+ return true, false // skip, keep going
+ }
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsdlike.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsdlike.go
new file mode 100644
index 000000000..ecaaa7a9c
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsdlike.go
@@ -0,0 +1,14 @@
+//go:build freebsd || darwin
+// +build freebsd darwin
+
+package mountinfo
+
+import "golang.org/x/sys/unix"
+
+func getMountinfo(entry *unix.Statfs_t) *Info {
+ return &Info{
+ Mountpoint: unix.ByteSliceToString(entry.Mntonname[:]),
+ FSType: unix.ByteSliceToString(entry.Fstypename[:]),
+ Source: unix.ByteSliceToString(entry.Mntfromname[:]),
+ }
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go
new file mode 100644
index 000000000..b32b5c9b1
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go
@@ -0,0 +1,250 @@
+package mountinfo
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "os"
+ "runtime"
+ "strconv"
+ "strings"
+ "sync"
+
+ "golang.org/x/sys/unix"
+)
+
+// GetMountsFromReader retrieves a list of mounts from the
+// reader provided, with an optional filter applied (use nil
+// for no filter). This can be useful in tests or benchmarks
+// that provide fake mountinfo data, or when a source other
+// than /proc/thread-self/mountinfo needs to be read from.
+//
+// This function is Linux-specific.
+func GetMountsFromReader(r io.Reader, filter FilterFunc) ([]*Info, error) {
+ s := bufio.NewScanner(r)
+ out := []*Info{}
+ for s.Scan() {
+ var err error
+
+ /*
+ See http://man7.org/linux/man-pages/man5/proc.5.html
+
+ 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
+ (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
+
+ (1) mount ID: unique identifier of the mount (may be reused after umount)
+ (2) parent ID: ID of parent (or of self for the top of the mount tree)
+ (3) major:minor: value of st_dev for files on filesystem
+ (4) root: root of the mount within the filesystem
+ (5) mount point: mount point relative to the process's root
+ (6) mount options: per mount options
+ (7) optional fields: zero or more fields of the form "tag[:value]"
+ (8) separator: marks the end of the optional fields
+ (9) filesystem type: name of filesystem of the form "type[.subtype]"
+ (10) mount source: filesystem specific information or "none"
+ (11) super options: per super block options
+
+ In other words, we have:
+ * 6 mandatory fields (1)..(6)
+ * 0 or more optional fields (7)
+ * a separator field (8)
+ * 3 mandatory fields (9)..(11)
+ */
+
+ text := s.Text()
+ fields := strings.Split(text, " ")
+ numFields := len(fields)
+ if numFields < 10 {
+ // should be at least 10 fields
+ return nil, fmt.Errorf("parsing '%s' failed: not enough fields (%d)", text, numFields)
+ }
+
+ // separator field
+ sepIdx := numFields - 4
+ // In Linux <= 3.9 mounting a cifs with spaces in a share
+ // name (like "//srv/My Docs") _may_ end up having a space
+ // in the last field of mountinfo (like "unc=//serv/My Docs").
+ // Since kernel 3.10-rc1, cifs option "unc=" is ignored,
+ // so spaces should not appear.
+ //
+ // Check for a separator, and work around the spaces bug
+ for fields[sepIdx] != "-" {
+ sepIdx--
+ if sepIdx == 5 {
+ return nil, fmt.Errorf("parsing '%s' failed: missing - separator", text)
+ }
+ }
+
+ p := &Info{}
+
+ p.Mountpoint, err = unescape(fields[4])
+ if err != nil {
+ return nil, fmt.Errorf("parsing '%s' failed: mount point: %w", fields[4], err)
+ }
+ p.FSType, err = unescape(fields[sepIdx+1])
+ if err != nil {
+ return nil, fmt.Errorf("parsing '%s' failed: fstype: %w", fields[sepIdx+1], err)
+ }
+ p.Source, err = unescape(fields[sepIdx+2])
+ if err != nil {
+ return nil, fmt.Errorf("parsing '%s' failed: source: %w", fields[sepIdx+2], err)
+ }
+ p.VFSOptions = fields[sepIdx+3]
+
+ // ignore any numbers parsing errors, as there should not be any
+ p.ID, _ = strconv.Atoi(fields[0])
+ p.Parent, _ = strconv.Atoi(fields[1])
+ mm := strings.SplitN(fields[2], ":", 3)
+ if len(mm) != 2 {
+ return nil, fmt.Errorf("parsing '%s' failed: unexpected major:minor pair %s", text, mm)
+ }
+ p.Major, _ = strconv.Atoi(mm[0])
+ p.Minor, _ = strconv.Atoi(mm[1])
+
+ p.Root, err = unescape(fields[3])
+ if err != nil {
+ return nil, fmt.Errorf("parsing '%s' failed: root: %w", fields[3], err)
+ }
+
+ p.Options = fields[5]
+
+ // zero or more optional fields
+ p.Optional = strings.Join(fields[6:sepIdx], " ")
+
+ // Run the filter after parsing all fields.
+ var skip, stop bool
+ if filter != nil {
+ skip, stop = filter(p)
+ if skip {
+ continue
+ }
+ }
+
+ out = append(out, p)
+ if stop {
+ break
+ }
+ }
+ if err := s.Err(); err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+var (
+ haveProcThreadSelf bool
+ haveProcThreadSelfOnce sync.Once
+)
+
+func parseMountTable(filter FilterFunc) (_ []*Info, err error) {
+ haveProcThreadSelfOnce.Do(func() {
+ _, err := os.Stat("/proc/thread-self/mountinfo")
+ haveProcThreadSelf = err == nil
+ })
+
+ // We need to lock ourselves to the current OS thread in order to make sure
+ // that the thread referenced by /proc/thread-self stays alive until we
+ // finish parsing the file.
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ var f *os.File
+ if haveProcThreadSelf {
+ f, err = os.Open("/proc/thread-self/mountinfo")
+ } else {
+ // On pre-3.17 kernels (such as CentOS 7), we don't have
+ // /proc/thread-self/ so we need to manually construct
+ // /proc/self/task// as a fallback.
+ f, err = os.Open("/proc/self/task/" + strconv.Itoa(unix.Gettid()) + "/mountinfo")
+ if os.IsNotExist(err) {
+ // If /proc/self/task/... failed, it means that our active pid
+ // namespace doesn't match the pid namespace of the /proc mount. In
+ // this case we just have to make do with /proc/self, since there
+ // is no other way of figuring out our tid in a parent pid
+ // namespace on pre-3.17 kernels.
+ f, err = os.Open("/proc/self/mountinfo")
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ return GetMountsFromReader(f, filter)
+}
+
+// PidMountInfo retrieves the list of mounts from a given process' mount
+// namespace. Unless there is a need to get mounts from a mount namespace
+// different from that of a calling process, use GetMounts.
+//
+// This function is Linux-specific.
+//
+// Deprecated: this will be removed before v1; use GetMountsFromReader with
+// opened /proc//mountinfo as an argument instead.
+func PidMountInfo(pid int) ([]*Info, error) {
+ f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid))
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ return GetMountsFromReader(f, nil)
+}
+
+// A few specific characters in mountinfo path entries (root and mountpoint)
+// are escaped using a backslash followed by a character's ascii code in octal.
+//
+// space -- as \040
+// tab (aka \t) -- as \011
+// newline (aka \n) -- as \012
+// backslash (aka \\) -- as \134
+//
+// This function converts path from mountinfo back, i.e. it unescapes the above sequences.
+func unescape(path string) (string, error) {
+ // try to avoid copying
+ if strings.IndexByte(path, '\\') == -1 {
+ return path, nil
+ }
+
+ // The following code is UTF-8 transparent as it only looks for some
+ // specific characters (backslash and 0..7) with values < utf8.RuneSelf,
+ // and everything else is passed through as is.
+ buf := make([]byte, len(path))
+ bufLen := 0
+ for i := 0; i < len(path); i++ {
+ if path[i] != '\\' {
+ buf[bufLen] = path[i]
+ bufLen++
+ continue
+ }
+ s := path[i:]
+ if len(s) < 4 {
+ // too short
+ return "", fmt.Errorf("bad escape sequence %q: too short", s)
+ }
+ c := s[1]
+ switch c {
+ case '0', '1', '2', '3', '4', '5', '6', '7':
+ v := c - '0'
+ for j := 2; j < 4; j++ { // one digit already; two more
+ if s[j] < '0' || s[j] > '7' {
+ return "", fmt.Errorf("bad escape sequence %q: not a digit", s[:3])
+ }
+ x := s[j] - '0'
+ v = (v << 3) | x
+ }
+ if v > 255 {
+ return "", fmt.Errorf("bad escape sequence %q: out of range" + s[:3])
+ }
+ buf[bufLen] = v
+ bufLen++
+ i += 3
+ continue
+ default:
+ return "", fmt.Errorf("bad escape sequence %q: not a digit" + s[:3])
+
+ }
+ }
+
+ return string(buf[:bufLen]), nil
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_openbsd.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_openbsd.go
new file mode 100644
index 000000000..f682c2d3b
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_openbsd.go
@@ -0,0 +1,11 @@
+package mountinfo
+
+import "golang.org/x/sys/unix"
+
+func getMountinfo(entry *unix.Statfs_t) *Info {
+ return &Info{
+ Mountpoint: unix.ByteSliceToString(entry.F_mntonname[:]),
+ FSType: unix.ByteSliceToString(entry.F_fstypename[:]),
+ Source: unix.ByteSliceToString(entry.F_mntfromname[:]),
+ }
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go
new file mode 100644
index 000000000..c2e64bc81
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go
@@ -0,0 +1,19 @@
+//go:build !windows && !linux && !freebsd && !openbsd && !darwin
+// +build !windows,!linux,!freebsd,!openbsd,!darwin
+
+package mountinfo
+
+import (
+ "fmt"
+ "runtime"
+)
+
+var errNotImplemented = fmt.Errorf("not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+
+func parseMountTable(_ FilterFunc) ([]*Info, error) {
+ return nil, errNotImplemented
+}
+
+func mounted(path string) (bool, error) {
+ return false, errNotImplemented
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go
new file mode 100644
index 000000000..13fad165e
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go
@@ -0,0 +1,10 @@
+package mountinfo
+
+func parseMountTable(_ FilterFunc) ([]*Info, error) {
+ // Do NOT return an error!
+ return nil, nil
+}
+
+func mounted(_ string) (bool, error) {
+ return false, nil
+}
diff --git a/vendor/github.com/moby/sys/userns/LICENSE b/vendor/github.com/moby/sys/userns/LICENSE
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/vendor/github.com/moby/sys/userns/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/vendor/github.com/moby/sys/userns/userns.go b/vendor/github.com/moby/sys/userns/userns.go
new file mode 100644
index 000000000..56b24c44a
--- /dev/null
+++ b/vendor/github.com/moby/sys/userns/userns.go
@@ -0,0 +1,16 @@
+// Package userns provides utilities to detect whether we are currently running
+// in a Linux user namespace.
+//
+// This code was migrated from [libcontainer/runc], which based its implementation
+// on code from [lcx/incus].
+//
+// [libcontainer/runc]: https://github.com/opencontainers/runc/blob/3778ae603c706494fd1e2c2faf83b406e38d687d/libcontainer/userns/userns_linux.go#L12-L49
+// [lcx/incus]: https://github.com/lxc/incus/blob/e45085dd42f826b3c8c3228e9733c0b6f998eafe/shared/util.go#L678-L700
+package userns
+
+// RunningInUserNS detects whether we are currently running in a Linux
+// user namespace and memoizes the result. It returns false on non-Linux
+// platforms.
+func RunningInUserNS() bool {
+ return inUserNS()
+}
diff --git a/vendor/github.com/moby/sys/userns/userns_linux.go b/vendor/github.com/moby/sys/userns/userns_linux.go
new file mode 100644
index 000000000..87c1c38ee
--- /dev/null
+++ b/vendor/github.com/moby/sys/userns/userns_linux.go
@@ -0,0 +1,53 @@
+package userns
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "sync"
+)
+
+var inUserNS = sync.OnceValue(runningInUserNS)
+
+// runningInUserNS detects whether we are currently running in a user namespace.
+//
+// This code was migrated from [libcontainer/runc] and based on an implementation
+// from [lcx/incus].
+//
+// [libcontainer/runc]: https://github.com/opencontainers/runc/blob/3778ae603c706494fd1e2c2faf83b406e38d687d/libcontainer/userns/userns_linux.go#L12-L49
+// [lcx/incus]: https://github.com/lxc/incus/blob/e45085dd42f826b3c8c3228e9733c0b6f998eafe/shared/util.go#L678-L700
+func runningInUserNS() bool {
+ file, err := os.Open("/proc/self/uid_map")
+ if err != nil {
+ // This kernel-provided file only exists if user namespaces are supported.
+ return false
+ }
+ defer file.Close()
+
+ buf := bufio.NewReader(file)
+ l, _, err := buf.ReadLine()
+ if err != nil {
+ return false
+ }
+
+ return uidMapInUserNS(string(l))
+}
+
+func uidMapInUserNS(uidMap string) bool {
+ if uidMap == "" {
+ // File exist but empty (the initial state when userns is created,
+ // see user_namespaces(7)).
+ return true
+ }
+
+ var a, b, c int64
+ if _, err := fmt.Sscanf(uidMap, "%d %d %d", &a, &b, &c); err != nil {
+ // Assume we are in a regular, non user namespace.
+ return false
+ }
+
+ // As per user_namespaces(7), /proc/self/uid_map of
+ // the initial user namespace shows 0 0 4294967295.
+ initNS := a == 0 && b == 0 && c == 4294967295
+ return !initNS
+}
diff --git a/vendor/github.com/moby/sys/userns/userns_linux_fuzzer.go b/vendor/github.com/moby/sys/userns/userns_linux_fuzzer.go
new file mode 100644
index 000000000..26ba2e16e
--- /dev/null
+++ b/vendor/github.com/moby/sys/userns/userns_linux_fuzzer.go
@@ -0,0 +1,8 @@
+//go:build linux && gofuzz
+
+package userns
+
+func FuzzUIDMap(uidmap []byte) int {
+ _ = uidMapInUserNS(string(uidmap))
+ return 1
+}
diff --git a/vendor/github.com/moby/sys/userns/userns_unsupported.go b/vendor/github.com/moby/sys/userns/userns_unsupported.go
new file mode 100644
index 000000000..8ed83072c
--- /dev/null
+++ b/vendor/github.com/moby/sys/userns/userns_unsupported.go
@@ -0,0 +1,6 @@
+//go:build !linux
+
+package userns
+
+// inUserNS is a stub for non-Linux systems. Always returns false.
+func inUserNS() bool { return false }
diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md
index 7972bbc3a..9f6090b8d 100644
--- a/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,3 +1,23 @@
+## 1.35.1
+
+### Fixes
+- Export EnforceDefaultTimeoutsWhenUsingContexts and DisableDefaultTimeoutsWhenUsingContext [ca36da1]
+
+## 1.35.0
+
+### Features
+
+- You can now call `EnforceDefaultTimeoutsWhenUsingContexts()` to have `Eventually` honor the default timeout when passed a context. (prior to this you had to expclility add a timeout) [e4c4265]
+- You can call `StopTrying(message).Successfully()` to abort a `Consistently` early without failure [eeca931]
+
+### Fixes
+
+- Stop memoizing the result of `HaveField` to avoid unexpected errors when used with async assertions. [3bdbc4e]
+
+### Maintenance
+
+- Bump all dependencies [a05a416]
+
## 1.34.2
Require Go 1.22+
diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go
index edacf8c13..1038d7dd4 100644
--- a/vendor/github.com/onsi/gomega/gomega_dsl.go
+++ b/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -22,7 +22,7 @@ import (
"github.com/onsi/gomega/types"
)
-const GOMEGA_VERSION = "1.34.2"
+const GOMEGA_VERSION = "1.35.1"
const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler.
If you're using Ginkgo then you probably forgot to put your assertion in an It().
@@ -319,7 +319,19 @@ you an also use Eventually().WithContext(ctx) to pass in the context. Passed-in
Eventually(client.FetchCount).WithContext(ctx).WithArguments("/users").Should(BeNumerically(">=", 17))
}, SpecTimeout(time.Second))
-Either way the context passd to Eventually is also passed to the underlying function. Now, when Ginkgo cancels the context both the FetchCount client and Gomega will be informed and can exit.
+Either way the context pasesd to Eventually is also passed to the underlying function. Now, when Ginkgo cancels the context both the FetchCount client and Gomega will be informed and can exit.
+
+By default, when a context is passed to Eventually *without* an explicit timeout, Gomega will rely solely on the context's cancellation to determine when to stop polling. If you want to specify a timeout in addition to the context you can do so using the .WithTimeout() method. For example:
+
+ Eventually(client.FetchCount).WithContext(ctx).WithTimeout(10*time.Second).Should(BeNumerically(">=", 17))
+
+now either the context cacnellation or the timeout will cause Eventually to stop polling.
+
+If, instead, you would like to opt out of this behavior and have Gomega's default timeouts govern Eventuallys that take a context you can call:
+
+ EnforceDefaultTimeoutsWhenUsingContexts()
+
+in the DSL (or on a Gomega instance). Now all calls to Eventually that take a context will fail if eitehr the context is cancelled or the default timeout elapses.
**Category 3: Making assertions _in_ the function passed into Eventually**
@@ -491,6 +503,16 @@ func SetDefaultConsistentlyPollingInterval(t time.Duration) {
Default.SetDefaultConsistentlyPollingInterval(t)
}
+// EnforceDefaultTimeoutsWhenUsingContexts forces `Eventually` to apply a default timeout even when a context is provided.
+func EnforceDefaultTimeoutsWhenUsingContexts() {
+ Default.EnforceDefaultTimeoutsWhenUsingContexts()
+}
+
+// DisableDefaultTimeoutsWhenUsingContext disables the default timeout when a context is provided to `Eventually`.
+func DisableDefaultTimeoutsWhenUsingContext() {
+ Default.DisableDefaultTimeoutsWhenUsingContext()
+}
+
// AsyncAssertion is returned by Eventually and Consistently and polls the actual value passed into Eventually against
// the matcher passed to the Should and ShouldNot methods.
//
diff --git a/vendor/github.com/onsi/gomega/internal/async_assertion.go b/vendor/github.com/onsi/gomega/internal/async_assertion.go
index cde9e2ec8..8b4cd1f5b 100644
--- a/vendor/github.com/onsi/gomega/internal/async_assertion.go
+++ b/vendor/github.com/onsi/gomega/internal/async_assertion.go
@@ -335,7 +335,7 @@ func (assertion *AsyncAssertion) afterTimeout() <-chan time.Time {
if assertion.asyncType == AsyncAssertionTypeConsistently {
return time.After(assertion.g.DurationBundle.ConsistentlyDuration)
} else {
- if assertion.ctx == nil {
+ if assertion.ctx == nil || assertion.g.DurationBundle.EnforceDefaultTimeoutsWhenUsingContexts {
return time.After(assertion.g.DurationBundle.EventuallyTimeout)
} else {
return nil
@@ -496,7 +496,15 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch
for _, err := range []error{actualErr, matcherErr} {
if pollingSignalErr, ok := AsPollingSignalError(err); ok {
if pollingSignalErr.IsStopTrying() {
- fail("Told to stop trying")
+ if pollingSignalErr.IsSuccessful() {
+ if assertion.asyncType == AsyncAssertionTypeEventually {
+ fail("Told to stop trying (and ignoring call to Successfully(), as it is only relevant with Consistently)")
+ } else {
+ return true // early escape hatch for Consistently
+ }
+ } else {
+ fail("Told to stop trying")
+ }
return false
}
if pollingSignalErr.IsTryAgainAfter() {
diff --git a/vendor/github.com/onsi/gomega/internal/duration_bundle.go b/vendor/github.com/onsi/gomega/internal/duration_bundle.go
index 6e0d90d3a..2e026c336 100644
--- a/vendor/github.com/onsi/gomega/internal/duration_bundle.go
+++ b/vendor/github.com/onsi/gomega/internal/duration_bundle.go
@@ -8,10 +8,11 @@ import (
)
type DurationBundle struct {
- EventuallyTimeout time.Duration
- EventuallyPollingInterval time.Duration
- ConsistentlyDuration time.Duration
- ConsistentlyPollingInterval time.Duration
+ EventuallyTimeout time.Duration
+ EventuallyPollingInterval time.Duration
+ ConsistentlyDuration time.Duration
+ ConsistentlyPollingInterval time.Duration
+ EnforceDefaultTimeoutsWhenUsingContexts bool
}
const (
@@ -20,15 +21,19 @@ const (
ConsistentlyDurationEnvVarName = "GOMEGA_DEFAULT_CONSISTENTLY_DURATION"
ConsistentlyPollingIntervalEnvVarName = "GOMEGA_DEFAULT_CONSISTENTLY_POLLING_INTERVAL"
+
+ EnforceDefaultTimeoutsWhenUsingContextsEnvVarName = "GOMEGA_ENFORCE_DEFAULT_TIMEOUTS_WHEN_USING_CONTEXTS"
)
func FetchDefaultDurationBundle() DurationBundle {
+ _, EnforceDefaultTimeoutsWhenUsingContexts := os.LookupEnv(EnforceDefaultTimeoutsWhenUsingContextsEnvVarName)
return DurationBundle{
EventuallyTimeout: durationFromEnv(EventuallyTimeoutEnvVarName, time.Second),
EventuallyPollingInterval: durationFromEnv(EventuallyPollingIntervalEnvVarName, 10*time.Millisecond),
- ConsistentlyDuration: durationFromEnv(ConsistentlyDurationEnvVarName, 100*time.Millisecond),
- ConsistentlyPollingInterval: durationFromEnv(ConsistentlyPollingIntervalEnvVarName, 10*time.Millisecond),
+ ConsistentlyDuration: durationFromEnv(ConsistentlyDurationEnvVarName, 100*time.Millisecond),
+ ConsistentlyPollingInterval: durationFromEnv(ConsistentlyPollingIntervalEnvVarName, 10*time.Millisecond),
+ EnforceDefaultTimeoutsWhenUsingContexts: EnforceDefaultTimeoutsWhenUsingContexts,
}
}
diff --git a/vendor/github.com/onsi/gomega/internal/gomega.go b/vendor/github.com/onsi/gomega/internal/gomega.go
index de1f4f336..c6e2fcc0e 100644
--- a/vendor/github.com/onsi/gomega/internal/gomega.go
+++ b/vendor/github.com/onsi/gomega/internal/gomega.go
@@ -127,3 +127,11 @@ func (g *Gomega) SetDefaultConsistentlyDuration(t time.Duration) {
func (g *Gomega) SetDefaultConsistentlyPollingInterval(t time.Duration) {
g.DurationBundle.ConsistentlyPollingInterval = t
}
+
+func (g *Gomega) EnforceDefaultTimeoutsWhenUsingContexts() {
+ g.DurationBundle.EnforceDefaultTimeoutsWhenUsingContexts = true
+}
+
+func (g *Gomega) DisableDefaultTimeoutsWhenUsingContext() {
+ g.DurationBundle.EnforceDefaultTimeoutsWhenUsingContexts = false
+}
diff --git a/vendor/github.com/onsi/gomega/internal/polling_signal_error.go b/vendor/github.com/onsi/gomega/internal/polling_signal_error.go
index 83b04b1a4..3a4f7ddd9 100644
--- a/vendor/github.com/onsi/gomega/internal/polling_signal_error.go
+++ b/vendor/github.com/onsi/gomega/internal/polling_signal_error.go
@@ -17,6 +17,7 @@ type PollingSignalError interface {
error
Wrap(err error) PollingSignalError
Attach(description string, obj any) PollingSignalError
+ Successfully() PollingSignalError
Now()
}
@@ -45,6 +46,7 @@ type PollingSignalErrorImpl struct {
wrappedErr error
pollingSignalErrorType PollingSignalErrorType
duration time.Duration
+ successful bool
Attachments []PollingSignalErrorAttachment
}
@@ -73,6 +75,11 @@ func (s *PollingSignalErrorImpl) Unwrap() error {
return s.wrappedErr
}
+func (s *PollingSignalErrorImpl) Successfully() PollingSignalError {
+ s.successful = true
+ return s
+}
+
func (s *PollingSignalErrorImpl) Now() {
panic(s)
}
@@ -81,6 +88,10 @@ func (s *PollingSignalErrorImpl) IsStopTrying() bool {
return s.pollingSignalErrorType == PollingSignalErrorTypeStopTrying
}
+func (s *PollingSignalErrorImpl) IsSuccessful() bool {
+ return s.successful
+}
+
func (s *PollingSignalErrorImpl) IsTryAgainAfter() bool {
return s.pollingSignalErrorType == PollingSignalErrorTypeTryAgainAfter
}
diff --git a/vendor/github.com/onsi/gomega/matchers/have_field.go b/vendor/github.com/onsi/gomega/matchers/have_field.go
index 6989f78c4..8dd3f871a 100644
--- a/vendor/github.com/onsi/gomega/matchers/have_field.go
+++ b/vendor/github.com/onsi/gomega/matchers/have_field.go
@@ -17,7 +17,7 @@ func (e missingFieldError) Error() string {
return string(e)
}
-func extractField(actual interface{}, field string, matchername string) (interface{}, error) {
+func extractField(actual interface{}, field string, matchername string) (any, error) {
fields := strings.SplitN(field, ".", 2)
actualValue := reflect.ValueOf(actual)
@@ -64,36 +64,46 @@ func extractField(actual interface{}, field string, matchername string) (interfa
type HaveFieldMatcher struct {
Field string
Expected interface{}
+}
- extractedField interface{}
- expectedMatcher omegaMatcher
+func (matcher *HaveFieldMatcher) expectedMatcher() omegaMatcher {
+ var isMatcher bool
+ expectedMatcher, isMatcher := matcher.Expected.(omegaMatcher)
+ if !isMatcher {
+ expectedMatcher = &EqualMatcher{Expected: matcher.Expected}
+ }
+ return expectedMatcher
}
func (matcher *HaveFieldMatcher) Match(actual interface{}) (success bool, err error) {
- matcher.extractedField, err = extractField(actual, matcher.Field, "HaveField")
+ extractedField, err := extractField(actual, matcher.Field, "HaveField")
if err != nil {
return false, err
}
- var isMatcher bool
- matcher.expectedMatcher, isMatcher = matcher.Expected.(omegaMatcher)
- if !isMatcher {
- matcher.expectedMatcher = &EqualMatcher{Expected: matcher.Expected}
- }
-
- return matcher.expectedMatcher.Match(matcher.extractedField)
+ return matcher.expectedMatcher().Match(extractedField)
}
func (matcher *HaveFieldMatcher) FailureMessage(actual interface{}) (message string) {
+ extractedField, err := extractField(actual, matcher.Field, "HaveField")
+ if err != nil {
+ // this really shouldn't happen
+ return fmt.Sprintf("Failed to extract field '%s': %s", matcher.Field, err)
+ }
message = fmt.Sprintf("Value for field '%s' failed to satisfy matcher.\n", matcher.Field)
- message += matcher.expectedMatcher.FailureMessage(matcher.extractedField)
+ message += matcher.expectedMatcher().FailureMessage(extractedField)
return message
}
func (matcher *HaveFieldMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+ extractedField, err := extractField(actual, matcher.Field, "HaveField")
+ if err != nil {
+ // this really shouldn't happen
+ return fmt.Sprintf("Failed to extract field '%s': %s", matcher.Field, err)
+ }
message = fmt.Sprintf("Value for field '%s' satisfied matcher, but should not have.\n", matcher.Field)
- message += matcher.expectedMatcher.NegatedFailureMessage(matcher.extractedField)
+ message += matcher.expectedMatcher().NegatedFailureMessage(extractedField)
return message
}
diff --git a/vendor/github.com/onsi/gomega/types/types.go b/vendor/github.com/onsi/gomega/types/types.go
index 7c7adb941..30f2beed3 100644
--- a/vendor/github.com/onsi/gomega/types/types.go
+++ b/vendor/github.com/onsi/gomega/types/types.go
@@ -29,6 +29,8 @@ type Gomega interface {
SetDefaultEventuallyPollingInterval(time.Duration)
SetDefaultConsistentlyDuration(time.Duration)
SetDefaultConsistentlyPollingInterval(time.Duration)
+ EnforceDefaultTimeoutsWhenUsingContexts()
+ DisableDefaultTimeoutsWhenUsingContext()
}
// All Gomega matchers must implement the GomegaMatcher interface
diff --git a/vendor/github.com/x448/float16/.travis.yml b/vendor/github.com/x448/float16/.travis.yml
new file mode 100644
index 000000000..8902bdaaf
--- /dev/null
+++ b/vendor/github.com/x448/float16/.travis.yml
@@ -0,0 +1,13 @@
+language: go
+
+go:
+ - 1.11.x
+
+env:
+ - GO111MODULE=on
+
+script:
+ - go test -short -coverprofile=coverage.txt -covermode=count ./...
+
+after_success:
+ - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/x448/float16/LICENSE b/vendor/github.com/x448/float16/LICENSE
new file mode 100644
index 000000000..bf6e35785
--- /dev/null
+++ b/vendor/github.com/x448/float16/LICENSE
@@ -0,0 +1,22 @@
+MIT License
+
+Copyright (c) 2019 Montgomery Edwards⁴⁴⁸ and Faye Amacker
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/vendor/github.com/x448/float16/README.md b/vendor/github.com/x448/float16/README.md
new file mode 100644
index 000000000..b524b8135
--- /dev/null
+++ b/vendor/github.com/x448/float16/README.md
@@ -0,0 +1,133 @@
+# Float16 (Binary16) in Go/Golang
+[![Build Status](https://travis-ci.org/x448/float16.svg?branch=master)](https://travis-ci.org/x448/float16)
+[![codecov](https://codecov.io/gh/x448/float16/branch/master/graph/badge.svg?v=4)](https://codecov.io/gh/x448/float16)
+[![Go Report Card](https://goreportcard.com/badge/github.com/x448/float16)](https://goreportcard.com/report/github.com/x448/float16)
+[![Release](https://img.shields.io/github/release/x448/float16.svg?style=flat-square)](https://github.com/x448/float16/releases)
+[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/x448/float16/master/LICENSE)
+
+`float16` package provides [IEEE 754 half-precision floating-point format (binary16)](https://en.wikipedia.org/wiki/Half-precision_floating-point_format) with IEEE 754 default rounding for conversions. IEEE 754-2008 refers to this 16-bit floating-point format as binary16.
+
+IEEE 754 default rounding ("Round-to-Nearest RoundTiesToEven") is considered the most accurate and statistically unbiased estimate of the true result.
+
+All possible 4+ billion floating-point conversions with this library are verified to be correct.
+
+Lowercase "float16" refers to IEEE 754 binary16. And capitalized "Float16" refers to exported Go data type provided by this library.
+
+## Features
+Current features include:
+
+* float16 to float32 conversions use lossless conversion.
+* float32 to float16 conversions use IEEE 754-2008 "Round-to-Nearest RoundTiesToEven".
+* conversions using pure Go take about 2.65 ns/op on a desktop amd64.
+* unit tests provide 100% code coverage and check all possible 4+ billion conversions.
+* other functions include: IsInf(), IsNaN(), IsNormal(), PrecisionFromfloat32(), String(), etc.
+* all functions in this library use zero allocs except String().
+
+## Status
+This library is used by [fxamacker/cbor](https://github.com/fxamacker/cbor) and is ready for production use on supported platforms. The version number < 1.0 indicates more functions and options are planned but not yet published.
+
+Current status:
+
+* core API is done and breaking API changes are unlikely.
+* 100% of unit tests pass:
+ * short mode (`go test -short`) tests around 65765 conversions in 0.005s.
+ * normal mode (`go test`) tests all possible 4+ billion conversions in about 95s.
+* 100% code coverage with both short mode and normal mode.
+* tested on amd64 but it should work on all little-endian platforms supported by Go.
+
+Roadmap:
+
+* add functions for fast batch conversions leveraging SIMD when supported by hardware.
+* speed up unit test when verifying all possible 4+ billion conversions.
+* test on additional platforms.
+
+## Float16 to Float32 Conversion
+Conversions from float16 to float32 are lossless conversions. All 65536 possible float16 to float32 conversions (in pure Go) are confirmed to be correct.
+
+Unit tests take a fraction of a second to check all 65536 expected values for float16 to float32 conversions.
+
+## Float32 to Float16 Conversion
+Conversions from float32 to float16 use IEEE 754 default rounding ("Round-to-Nearest RoundTiesToEven"). All 4294967296 possible float32 to float16 conversions (in pure Go) are confirmed to be correct.
+
+Unit tests in normal mode take about 1-2 minutes to check all 4+ billion float32 input values and results for Fromfloat32(), FromNaN32ps(), and PrecisionFromfloat32().
+
+Unit tests in short mode use a small subset (around 229 float32 inputs) and finish in under 0.01 second while still reaching 100% code coverage.
+
+## Usage
+Install with `go get github.com/x448/float16`.
+```
+// Convert float32 to float16
+pi := float32(math.Pi)
+pi16 := float16.Fromfloat32(pi)
+
+// Convert float16 to float32
+pi32 := pi16.Float32()
+
+// PrecisionFromfloat32() is faster than the overhead of calling a function.
+// This example only converts if there's no data loss and input is not a subnormal.
+if float16.PrecisionFromfloat32(pi) == float16.PrecisionExact {
+ pi16 := float16.Fromfloat32(pi)
+}
+```
+
+## Float16 Type and API
+Float16 (capitalized) is a Go type with uint16 as the underlying state. There are 6 exported functions and 9 exported methods.
+```
+package float16 // import "github.com/x448/float16"
+
+// Exported types and consts
+type Float16 uint16
+const ErrInvalidNaNValue = float16Error("float16: invalid NaN value, expected IEEE 754 NaN")
+
+// Exported functions
+Fromfloat32(f32 float32) Float16 // Float16 number converted from f32 using IEEE 754 default rounding
+ with identical results to AMD and Intel F16C hardware. NaN inputs
+ are converted with quiet bit always set on, to be like F16C.
+
+FromNaN32ps(nan float32) (Float16, error) // Float16 NaN without modifying quiet bit.
+ // The "ps" suffix means "preserve signaling".
+ // Returns sNaN and ErrInvalidNaNValue if nan isn't a NaN.
+
+Frombits(b16 uint16) Float16 // Float16 number corresponding to b16 (IEEE 754 binary16 rep.)
+NaN() Float16 // Float16 of IEEE 754 binary16 not-a-number
+Inf(sign int) Float16 // Float16 of IEEE 754 binary16 infinity according to sign
+
+PrecisionFromfloat32(f32 float32) Precision // quickly indicates exact, ..., overflow, underflow
+ // (inline and < 1 ns/op)
+// Exported methods
+(f Float16) Float32() float32 // float32 number converted from f16 using lossless conversion
+(f Float16) Bits() uint16 // the IEEE 754 binary16 representation of f
+(f Float16) IsNaN() bool // true if f is not-a-number (NaN)
+(f Float16) IsQuietNaN() bool // true if f is a quiet not-a-number (NaN)
+(f Float16) IsInf(sign int) bool // true if f is infinite based on sign (-1=NegInf, 0=any, 1=PosInf)
+(f Float16) IsFinite() bool // true if f is not infinite or NaN
+(f Float16) IsNormal() bool // true if f is not zero, infinite, subnormal, or NaN.
+(f Float16) Signbit() bool // true if f is negative or negative zero
+(f Float16) String() string // string representation of f to satisfy fmt.Stringer interface
+```
+See [API](https://godoc.org/github.com/x448/float16) at godoc.org for more info.
+
+## Benchmarks
+Conversions (in pure Go) are around 2.65 ns/op for float16 -> float32 and float32 -> float16 on amd64. Speeds can vary depending on input value.
+
+```
+All functions have zero allocations except float16.String().
+
+FromFloat32pi-2 2.59ns ± 0% // speed using Fromfloat32() to convert a float32 of math.Pi to Float16
+ToFloat32pi-2 2.69ns ± 0% // speed using Float32() to convert a float16 of math.Pi to float32
+Frombits-2 0.29ns ± 5% // speed using Frombits() to cast a uint16 to Float16
+
+PrecisionFromFloat32-2 0.29ns ± 1% // speed using PrecisionFromfloat32() to check for overflows, etc.
+```
+
+## System Requirements
+* Tested on Go 1.11, 1.12, and 1.13 but it should also work with older versions.
+* Tested on amd64 but it should also work on all little-endian platforms supported by Go.
+
+## Special Thanks
+Special thanks to Kathryn Long (starkat99) for creating [half-rs](https://github.com/starkat99/half-rs), a very nice rust implementation of float16.
+
+## License
+Copyright (c) 2019 Montgomery Edwards⁴⁴⁸ and Faye Amacker
+
+Licensed under [MIT License](LICENSE)
diff --git a/vendor/github.com/x448/float16/float16.go b/vendor/github.com/x448/float16/float16.go
new file mode 100644
index 000000000..1a0e6dad0
--- /dev/null
+++ b/vendor/github.com/x448/float16/float16.go
@@ -0,0 +1,302 @@
+// Copyright 2019 Montgomery Edwards⁴⁴⁸ and Faye Amacker
+//
+// Special thanks to Kathryn Long for her Rust implementation
+// of float16 at github.com/starkat99/half-rs (MIT license)
+
+package float16
+
+import (
+ "math"
+ "strconv"
+)
+
+// Float16 represents IEEE 754 half-precision floating-point numbers (binary16).
+type Float16 uint16
+
+// Precision indicates whether the conversion to Float16 is
+// exact, subnormal without dropped bits, inexact, underflow, or overflow.
+type Precision int
+
+const (
+
+ // PrecisionExact is for non-subnormals that don't drop bits during conversion.
+ // All of these can round-trip. Should always convert to float16.
+ PrecisionExact Precision = iota
+
+ // PrecisionUnknown is for subnormals that don't drop bits during conversion but
+ // not all of these can round-trip so precision is unknown without more effort.
+ // Only 2046 of these can round-trip and the rest cannot round-trip.
+ PrecisionUnknown
+
+ // PrecisionInexact is for dropped significand bits and cannot round-trip.
+ // Some of these are subnormals. Cannot round-trip float32->float16->float32.
+ PrecisionInexact
+
+ // PrecisionUnderflow is for Underflows. Cannot round-trip float32->float16->float32.
+ PrecisionUnderflow
+
+ // PrecisionOverflow is for Overflows. Cannot round-trip float32->float16->float32.
+ PrecisionOverflow
+)
+
+// PrecisionFromfloat32 returns Precision without performing
+// the conversion. Conversions from both Infinity and NaN
+// values will always report PrecisionExact even if NaN payload
+// or NaN-Quiet-Bit is lost. This function is kept simple to
+// allow inlining and run < 0.5 ns/op, to serve as a fast filter.
+func PrecisionFromfloat32(f32 float32) Precision {
+ u32 := math.Float32bits(f32)
+
+ if u32 == 0 || u32 == 0x80000000 {
+ // +- zero will always be exact conversion
+ return PrecisionExact
+ }
+
+ const COEFMASK uint32 = 0x7fffff // 23 least significant bits
+ const EXPSHIFT uint32 = 23
+ const EXPBIAS uint32 = 127
+ const EXPMASK uint32 = uint32(0xff) << EXPSHIFT
+ const DROPMASK uint32 = COEFMASK >> 10
+
+ exp := int32(((u32 & EXPMASK) >> EXPSHIFT) - EXPBIAS)
+ coef := u32 & COEFMASK
+
+ if exp == 128 {
+ // +- infinity or NaN
+ // apps may want to do extra checks for NaN separately
+ return PrecisionExact
+ }
+
+ // https://en.wikipedia.org/wiki/Half-precision_floating-point_format says,
+ // "Decimals between 2^−24 (minimum positive subnormal) and 2^−14 (maximum subnormal): fixed interval 2^−24"
+ if exp < -24 {
+ return PrecisionUnderflow
+ }
+ if exp > 15 {
+ return PrecisionOverflow
+ }
+ if (coef & DROPMASK) != uint32(0) {
+ // these include subnormals and non-subnormals that dropped bits
+ return PrecisionInexact
+ }
+
+ if exp < -14 {
+ // Subnormals. Caller may want to test these further.
+ // There are 2046 subnormals that can successfully round-trip f32->f16->f32
+ // and 20 of those 2046 have 32-bit input coef == 0.
+ // RFC 7049 and 7049bis Draft 12 don't precisely define "preserves value"
+ // so some protocols and libraries will choose to handle subnormals differently
+ // when deciding to encode them to CBOR float32 vs float16.
+ return PrecisionUnknown
+ }
+
+ return PrecisionExact
+}
+
+// Frombits returns the float16 number corresponding to the IEEE 754 binary16
+// representation u16, with the sign bit of u16 and the result in the same bit
+// position. Frombits(Bits(x)) == x.
+func Frombits(u16 uint16) Float16 {
+ return Float16(u16)
+}
+
+// Fromfloat32 returns a Float16 value converted from f32. Conversion uses
+// IEEE default rounding (nearest int, with ties to even).
+func Fromfloat32(f32 float32) Float16 {
+ return Float16(f32bitsToF16bits(math.Float32bits(f32)))
+}
+
+// ErrInvalidNaNValue indicates a NaN was not received.
+const ErrInvalidNaNValue = float16Error("float16: invalid NaN value, expected IEEE 754 NaN")
+
+type float16Error string
+
+func (e float16Error) Error() string { return string(e) }
+
+// FromNaN32ps converts nan to IEEE binary16 NaN while preserving both
+// signaling and payload. Unlike Fromfloat32(), which can only return
+// qNaN because it sets quiet bit = 1, this can return both sNaN and qNaN.
+// If the result is infinity (sNaN with empty payload), then the
+// lowest bit of payload is set to make the result a NaN.
+// Returns ErrInvalidNaNValue and 0x7c01 (sNaN) if nan isn't IEEE 754 NaN.
+// This function was kept simple to be able to inline.
+func FromNaN32ps(nan float32) (Float16, error) {
+ const SNAN = Float16(uint16(0x7c01)) // signalling NaN
+
+ u32 := math.Float32bits(nan)
+ sign := u32 & 0x80000000
+ exp := u32 & 0x7f800000
+ coef := u32 & 0x007fffff
+
+ if (exp != 0x7f800000) || (coef == 0) {
+ return SNAN, ErrInvalidNaNValue
+ }
+
+ u16 := uint16((sign >> 16) | uint32(0x7c00) | (coef >> 13))
+
+ if (u16 & 0x03ff) == 0 {
+ // result became infinity, make it NaN by setting lowest bit in payload
+ u16 = u16 | 0x0001
+ }
+
+ return Float16(u16), nil
+}
+
+// NaN returns a Float16 of IEEE 754 binary16 not-a-number (NaN).
+// Returned NaN value 0x7e01 has all exponent bits = 1 with the
+// first and last bits = 1 in the significand. This is consistent
+// with Go's 64-bit math.NaN(). Canonical CBOR in RFC 7049 uses 0x7e00.
+func NaN() Float16 {
+ return Float16(0x7e01)
+}
+
+// Inf returns a Float16 with an infinity value with the specified sign.
+// A sign >= returns positive infinity.
+// A sign < 0 returns negative infinity.
+func Inf(sign int) Float16 {
+ if sign >= 0 {
+ return Float16(0x7c00)
+ }
+ return Float16(0x8000 | 0x7c00)
+}
+
+// Float32 returns a float32 converted from f (Float16).
+// This is a lossless conversion.
+func (f Float16) Float32() float32 {
+ u32 := f16bitsToF32bits(uint16(f))
+ return math.Float32frombits(u32)
+}
+
+// Bits returns the IEEE 754 binary16 representation of f, with the sign bit
+// of f and the result in the same bit position. Bits(Frombits(x)) == x.
+func (f Float16) Bits() uint16 {
+ return uint16(f)
+}
+
+// IsNaN reports whether f is an IEEE 754 binary16 “not-a-number” value.
+func (f Float16) IsNaN() bool {
+ return (f&0x7c00 == 0x7c00) && (f&0x03ff != 0)
+}
+
+// IsQuietNaN reports whether f is a quiet (non-signaling) IEEE 754 binary16
+// “not-a-number” value.
+func (f Float16) IsQuietNaN() bool {
+ return (f&0x7c00 == 0x7c00) && (f&0x03ff != 0) && (f&0x0200 != 0)
+}
+
+// IsInf reports whether f is an infinity (inf).
+// A sign > 0 reports whether f is positive inf.
+// A sign < 0 reports whether f is negative inf.
+// A sign == 0 reports whether f is either inf.
+func (f Float16) IsInf(sign int) bool {
+ return ((f == 0x7c00) && sign >= 0) ||
+ (f == 0xfc00 && sign <= 0)
+}
+
+// IsFinite returns true if f is neither infinite nor NaN.
+func (f Float16) IsFinite() bool {
+ return (uint16(f) & uint16(0x7c00)) != uint16(0x7c00)
+}
+
+// IsNormal returns true if f is neither zero, infinite, subnormal, or NaN.
+func (f Float16) IsNormal() bool {
+ exp := uint16(f) & uint16(0x7c00)
+ return (exp != uint16(0x7c00)) && (exp != 0)
+}
+
+// Signbit reports whether f is negative or negative zero.
+func (f Float16) Signbit() bool {
+ return (uint16(f) & uint16(0x8000)) != 0
+}
+
+// String satisfies the fmt.Stringer interface.
+func (f Float16) String() string {
+ return strconv.FormatFloat(float64(f.Float32()), 'f', -1, 32)
+}
+
+// f16bitsToF32bits returns uint32 (float32 bits) converted from specified uint16.
+func f16bitsToF32bits(in uint16) uint32 {
+ // All 65536 conversions with this were confirmed to be correct
+ // by Montgomery Edwards⁴⁴⁸ (github.com/x448).
+
+ sign := uint32(in&0x8000) << 16 // sign for 32-bit
+ exp := uint32(in&0x7c00) >> 10 // exponenent for 16-bit
+ coef := uint32(in&0x03ff) << 13 // significand for 32-bit
+
+ if exp == 0x1f {
+ if coef == 0 {
+ // infinity
+ return sign | 0x7f800000 | coef
+ }
+ // NaN
+ return sign | 0x7fc00000 | coef
+ }
+
+ if exp == 0 {
+ if coef == 0 {
+ // zero
+ return sign
+ }
+
+ // normalize subnormal numbers
+ exp++
+ for coef&0x7f800000 == 0 {
+ coef <<= 1
+ exp--
+ }
+ coef &= 0x007fffff
+ }
+
+ return sign | ((exp + (0x7f - 0xf)) << 23) | coef
+}
+
+// f32bitsToF16bits returns uint16 (Float16 bits) converted from the specified float32.
+// Conversion rounds to nearest integer with ties to even.
+func f32bitsToF16bits(u32 uint32) uint16 {
+ // Translated from Rust to Go by Montgomery Edwards⁴⁴⁸ (github.com/x448).
+ // All 4294967296 conversions with this were confirmed to be correct by x448.
+ // Original Rust implementation is by Kathryn Long (github.com/starkat99) with MIT license.
+
+ sign := u32 & 0x80000000
+ exp := u32 & 0x7f800000
+ coef := u32 & 0x007fffff
+
+ if exp == 0x7f800000 {
+ // NaN or Infinity
+ nanBit := uint32(0)
+ if coef != 0 {
+ nanBit = uint32(0x0200)
+ }
+ return uint16((sign >> 16) | uint32(0x7c00) | nanBit | (coef >> 13))
+ }
+
+ halfSign := sign >> 16
+
+ unbiasedExp := int32(exp>>23) - 127
+ halfExp := unbiasedExp + 15
+
+ if halfExp >= 0x1f {
+ return uint16(halfSign | uint32(0x7c00))
+ }
+
+ if halfExp <= 0 {
+ if 14-halfExp > 24 {
+ return uint16(halfSign)
+ }
+ coef := coef | uint32(0x00800000)
+ halfCoef := coef >> uint32(14-halfExp)
+ roundBit := uint32(1) << uint32(13-halfExp)
+ if (coef&roundBit) != 0 && (coef&(3*roundBit-1)) != 0 {
+ halfCoef++
+ }
+ return uint16(halfSign | halfCoef)
+ }
+
+ uHalfExp := uint32(halfExp) << 10
+ halfCoef := coef >> 13
+ roundBit := uint32(0x00001000)
+ if (coef&roundBit) != 0 && (coef&(3*roundBit-1)) != 0 {
+ return uint16((halfSign | uHalfExp | halfCoef) + 1)
+ }
+ return uint16(halfSign | uHalfExp | halfCoef)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/api/equality/semantic.go b/vendor/k8s.io/apimachinery/pkg/api/equality/semantic.go
new file mode 100644
index 000000000..f02fa8e43
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/api/equality/semantic.go
@@ -0,0 +1,49 @@
+/*
+Copyright 2014 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 equality
+
+import (
+ "k8s.io/apimachinery/pkg/api/resource"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/conversion"
+ "k8s.io/apimachinery/pkg/fields"
+ "k8s.io/apimachinery/pkg/labels"
+)
+
+// Semantic can do semantic deep equality checks for api objects.
+// Example: apiequality.Semantic.DeepEqual(aPod, aPodWithNonNilButEmptyMaps) == true
+var Semantic = conversion.EqualitiesOrDie(
+ func(a, b resource.Quantity) bool {
+ // Ignore formatting, only care that numeric value stayed the same.
+ // TODO: if we decide it's important, it should be safe to start comparing the format.
+ //
+ // Uninitialized quantities are equivalent to 0 quantities.
+ return a.Cmp(b) == 0
+ },
+ func(a, b metav1.MicroTime) bool {
+ return a.UTC() == b.UTC()
+ },
+ func(a, b metav1.Time) bool {
+ return a.UTC() == b.UTC()
+ },
+ func(a, b labels.Selector) bool {
+ return a.String() == b.String()
+ },
+ func(a, b fields.Selector) bool {
+ return a.String() == b.String()
+ },
+)
diff --git a/vendor/k8s.io/apimachinery/pkg/api/errors/OWNERS b/vendor/k8s.io/apimachinery/pkg/api/errors/OWNERS
index 155648acb..1a9f5e770 100644
--- a/vendor/k8s.io/apimachinery/pkg/api/errors/OWNERS
+++ b/vendor/k8s.io/apimachinery/pkg/api/errors/OWNERS
@@ -2,7 +2,6 @@
reviewers:
- thockin
- - lavalamp
- smarterclayton
- wojtek-t
- deads2k
diff --git a/vendor/k8s.io/apimachinery/pkg/api/errors/errors.go b/vendor/k8s.io/apimachinery/pkg/api/errors/errors.go
index 57e0e71f6..6a3ab8f24 100644
--- a/vendor/k8s.io/apimachinery/pkg/api/errors/errors.go
+++ b/vendor/k8s.io/apimachinery/pkg/api/errors/errors.go
@@ -54,6 +54,7 @@ var knownReasons = map[metav1.StatusReason]struct{}{
metav1.StatusReasonGone: {},
metav1.StatusReasonInvalid: {},
metav1.StatusReasonServerTimeout: {},
+ metav1.StatusReasonStoreReadError: {},
metav1.StatusReasonTimeout: {},
metav1.StatusReasonTooManyRequests: {},
metav1.StatusReasonBadRequest: {},
@@ -775,6 +776,12 @@ func IsUnexpectedObjectError(err error) bool {
return err != nil && (ok || errors.As(err, &uoe))
}
+// IsStoreReadError determines if err is due to either failure to transform the
+// data from the storage, or failure to decode the object appropriately.
+func IsStoreReadError(err error) bool {
+ return ReasonForError(err) == metav1.StatusReasonStoreReadError
+}
+
// SuggestsClientDelay returns true if this error suggests a client delay as well as the
// suggested seconds to wait, or false if the error does not imply a wait. It does not
// address whether the error *should* be retried, since some errors (like a 3xx) may
diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/OWNERS b/vendor/k8s.io/apimachinery/pkg/api/meta/OWNERS
index 1e1330fff..3bd8bf535 100644
--- a/vendor/k8s.io/apimachinery/pkg/api/meta/OWNERS
+++ b/vendor/k8s.io/apimachinery/pkg/api/meta/OWNERS
@@ -10,5 +10,6 @@ reviewers:
- mikedanese
- liggitt
- janetkuo
- - ncdc
- dims
+emeritus_reviewers:
+ - ncdc
diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/conditions.go b/vendor/k8s.io/apimachinery/pkg/api/meta/conditions.go
index 60c8209de..cbdf2eeb8 100644
--- a/vendor/k8s.io/apimachinery/pkg/api/meta/conditions.go
+++ b/vendor/k8s.io/apimachinery/pkg/api/meta/conditions.go
@@ -22,14 +22,15 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
-// SetStatusCondition sets the corresponding condition in conditions to newCondition.
+// SetStatusCondition sets the corresponding condition in conditions to newCondition and returns true
+// if the conditions are changed by this call.
// conditions must be non-nil.
// 1. if the condition of the specified type already exists (all fields of the existing condition are updated to
// newCondition, LastTransitionTime is set to now if the new status differs from the old status)
// 2. if a condition of the specified type does not exist (LastTransitionTime is set to now() if unset, and newCondition is appended)
-func SetStatusCondition(conditions *[]metav1.Condition, newCondition metav1.Condition) {
+func SetStatusCondition(conditions *[]metav1.Condition, newCondition metav1.Condition) (changed bool) {
if conditions == nil {
- return
+ return false
}
existingCondition := FindStatusCondition(*conditions, newCondition.Type)
if existingCondition == nil {
@@ -37,7 +38,7 @@ func SetStatusCondition(conditions *[]metav1.Condition, newCondition metav1.Cond
newCondition.LastTransitionTime = metav1.NewTime(time.Now())
}
*conditions = append(*conditions, newCondition)
- return
+ return true
}
if existingCondition.Status != newCondition.Status {
@@ -47,18 +48,31 @@ func SetStatusCondition(conditions *[]metav1.Condition, newCondition metav1.Cond
} else {
existingCondition.LastTransitionTime = metav1.NewTime(time.Now())
}
+ changed = true
}
- existingCondition.Reason = newCondition.Reason
- existingCondition.Message = newCondition.Message
- existingCondition.ObservedGeneration = newCondition.ObservedGeneration
+ if existingCondition.Reason != newCondition.Reason {
+ existingCondition.Reason = newCondition.Reason
+ changed = true
+ }
+ if existingCondition.Message != newCondition.Message {
+ existingCondition.Message = newCondition.Message
+ changed = true
+ }
+ if existingCondition.ObservedGeneration != newCondition.ObservedGeneration {
+ existingCondition.ObservedGeneration = newCondition.ObservedGeneration
+ changed = true
+ }
+
+ return changed
}
-// RemoveStatusCondition removes the corresponding conditionType from conditions.
+// RemoveStatusCondition removes the corresponding conditionType from conditions if present. Returns
+// true if it was present and got removed.
// conditions must be non-nil.
-func RemoveStatusCondition(conditions *[]metav1.Condition, conditionType string) {
+func RemoveStatusCondition(conditions *[]metav1.Condition, conditionType string) (removed bool) {
if conditions == nil || len(*conditions) == 0 {
- return
+ return false
}
newConditions := make([]metav1.Condition, 0, len(*conditions)-1)
for _, condition := range *conditions {
@@ -67,7 +81,10 @@ func RemoveStatusCondition(conditions *[]metav1.Condition, conditionType string)
}
}
+ removed = len(*conditions) != len(newConditions)
*conditions = newConditions
+
+ return removed
}
// FindStatusCondition finds the conditionType in conditions.
diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/help.go b/vendor/k8s.io/apimachinery/pkg/api/meta/help.go
index 899d3e8a6..1fdd32c4b 100644
--- a/vendor/k8s.io/apimachinery/pkg/api/meta/help.go
+++ b/vendor/k8s.io/apimachinery/pkg/api/meta/help.go
@@ -40,8 +40,7 @@ var (
// IsListType returns true if the provided Object has a slice called Items.
// TODO: Replace the code in this check with an interface comparison by
-//
-// creating and enforcing that lists implement a list accessor.
+// creating and enforcing that lists implement a list accessor.
func IsListType(obj runtime.Object) bool {
switch t := obj.(type) {
case runtime.Unstructured:
@@ -113,8 +112,27 @@ func getItemsPtr(list runtime.Object) (interface{}, error) {
// EachListItem invokes fn on each runtime.Object in the list. Any error immediately terminates
// the loop.
+//
+// If items passed to fn are retained for different durations, and you want to avoid
+// retaining all items in obj as long as any item is referenced, use EachListItemWithAlloc instead.
func EachListItem(obj runtime.Object, fn func(runtime.Object) error) error {
+ return eachListItem(obj, fn, false)
+}
+
+// EachListItemWithAlloc works like EachListItem, but avoids retaining references to the items slice in obj.
+// It does this by making a shallow copy of non-pointer items in obj.
+//
+// If the items passed to fn are not retained, or are retained for the same duration, use EachListItem instead for memory efficiency.
+func EachListItemWithAlloc(obj runtime.Object, fn func(runtime.Object) error) error {
+ return eachListItem(obj, fn, true)
+}
+
+// allocNew: Whether shallow copy is required when the elements in Object.Items are struct
+func eachListItem(obj runtime.Object, fn func(runtime.Object) error, allocNew bool) error {
if unstructured, ok := obj.(runtime.Unstructured); ok {
+ if allocNew {
+ return unstructured.EachListItemWithAlloc(fn)
+ }
return unstructured.EachListItem(fn)
}
// TODO: Change to an interface call?
@@ -141,8 +159,19 @@ func EachListItem(obj runtime.Object, fn func(runtime.Object) error) error {
for i := 0; i < len; i++ {
raw := items.Index(i)
if takeAddr {
- raw = raw.Addr()
+ if allocNew {
+ // shallow copy to avoid retaining a reference to the original list item
+ itemCopy := reflect.New(raw.Type())
+ // assign to itemCopy and type-assert
+ itemCopy.Elem().Set(raw)
+ // reflect.New will guarantee that itemCopy must be a pointer.
+ raw = itemCopy
+ } else {
+ raw = raw.Addr()
+ }
}
+ // raw must be a pointer or an interface
+ // allocate a pointer is cheap
switch item := raw.Interface().(type) {
case *runtime.RawExtension:
if err := fn(item.Object); err != nil {
@@ -167,7 +196,23 @@ func EachListItem(obj runtime.Object, fn func(runtime.Object) error) error {
// ExtractList returns obj's Items element as an array of runtime.Objects.
// Returns an error if obj is not a List type (does not have an Items member).
+//
+// If items in the returned list are retained for different durations, and you want to avoid
+// retaining all items in obj as long as any item is referenced, use ExtractListWithAlloc instead.
func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
+ return extractList(obj, false)
+}
+
+// ExtractListWithAlloc works like ExtractList, but avoids retaining references to the items slice in obj.
+// It does this by making a shallow copy of non-pointer items in obj.
+//
+// If the items in the returned list are not retained, or are retained for the same duration, use ExtractList instead for memory efficiency.
+func ExtractListWithAlloc(obj runtime.Object) ([]runtime.Object, error) {
+ return extractList(obj, true)
+}
+
+// allocNew: Whether shallow copy is required when the elements in Object.Items are struct
+func extractList(obj runtime.Object, allocNew bool) ([]runtime.Object, error) {
itemsPtr, err := GetItemsPtr(obj)
if err != nil {
return nil, err
@@ -177,10 +222,17 @@ func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
return nil, err
}
list := make([]runtime.Object, items.Len())
+ if len(list) == 0 {
+ return list, nil
+ }
+ elemType := items.Type().Elem()
+ isRawExtension := elemType == rawExtensionObjectType
+ implementsObject := elemType.Implements(objectType)
for i := range list {
raw := items.Index(i)
- switch item := raw.Interface().(type) {
- case runtime.RawExtension:
+ switch {
+ case isRawExtension:
+ item := raw.Interface().(runtime.RawExtension)
switch {
case item.Object != nil:
list[i] = item.Object
@@ -190,8 +242,18 @@ func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
default:
list[i] = nil
}
- case runtime.Object:
- list[i] = item
+ case implementsObject:
+ list[i] = raw.Interface().(runtime.Object)
+ case allocNew:
+ // shallow copy to avoid retaining a reference to the original list item
+ itemCopy := reflect.New(raw.Type())
+ // assign to itemCopy and type-assert
+ itemCopy.Elem().Set(raw)
+ var ok bool
+ // reflect.New will guarantee that itemCopy must be a pointer.
+ if list[i], ok = itemCopy.Interface().(runtime.Object); !ok {
+ return nil, fmt.Errorf("%v: item[%v]: Expected object, got %#v(%s)", obj, i, raw.Interface(), raw.Kind())
+ }
default:
var found bool
if list[i], found = raw.Addr().Interface().(runtime.Object); !found {
@@ -202,8 +264,12 @@ func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
return list, nil
}
-// objectSliceType is the type of a slice of Objects
-var objectSliceType = reflect.TypeOf([]runtime.Object{})
+var (
+ // objectSliceType is the type of a slice of Objects
+ objectSliceType = reflect.TypeOf([]runtime.Object{})
+ objectType = reflect.TypeOf((*runtime.Object)(nil)).Elem()
+ rawExtensionObjectType = reflect.TypeOf(runtime.RawExtension{})
+)
// LenList returns the length of this list or 0 if it is not a list.
func LenList(list runtime.Object) int {
@@ -238,7 +304,7 @@ func SetList(list runtime.Object, objects []runtime.Object) error {
slice := reflect.MakeSlice(items.Type(), len(objects), len(objects))
for i := range objects {
dest := slice.Index(i)
- if dest.Type() == reflect.TypeOf(runtime.RawExtension{}) {
+ if dest.Type() == rawExtensionObjectType {
dest = dest.FieldByName("Object")
}
diff --git a/vendor/k8s.io/apimachinery/pkg/api/resource/OWNERS b/vendor/k8s.io/apimachinery/pkg/api/resource/OWNERS
index d1c9f5307..063fd285d 100644
--- a/vendor/k8s.io/apimachinery/pkg/api/resource/OWNERS
+++ b/vendor/k8s.io/apimachinery/pkg/api/resource/OWNERS
@@ -2,7 +2,6 @@
reviewers:
- thockin
- - lavalamp
- smarterclayton
- wojtek-t
- derekwaynecarr
diff --git a/vendor/k8s.io/apimachinery/pkg/api/resource/amount.go b/vendor/k8s.io/apimachinery/pkg/api/resource/amount.go
index a8866a43e..2eebec667 100644
--- a/vendor/k8s.io/apimachinery/pkg/api/resource/amount.go
+++ b/vendor/k8s.io/apimachinery/pkg/api/resource/amount.go
@@ -203,6 +203,44 @@ func (a *int64Amount) Sub(b int64Amount) bool {
return a.Add(int64Amount{value: -b.value, scale: b.scale})
}
+// Mul multiplies the provided b to the current amount, or
+// returns false if overflow or underflow would result.
+func (a *int64Amount) Mul(b int64) bool {
+ switch {
+ case a.value == 0:
+ return true
+ case b == 0:
+ a.value = 0
+ a.scale = 0
+ return true
+ case a.scale == 0:
+ c, ok := int64Multiply(a.value, b)
+ if !ok {
+ return false
+ }
+ a.value = c
+ case a.scale > 0:
+ c, ok := int64Multiply(a.value, b)
+ if !ok {
+ return false
+ }
+ if _, ok = positiveScaleInt64(c, a.scale); !ok {
+ return false
+ }
+ a.value = c
+ default:
+ c, ok := int64Multiply(a.value, b)
+ if !ok {
+ return false
+ }
+ if _, ok = negativeScaleInt64(c, -a.scale); !ok {
+ return false
+ }
+ a.value = c
+ }
+ return true
+}
+
// AsScale adjusts this amount to set a minimum scale, rounding up, and returns true iff no precision
// was lost. (1.1e5).AsScale(5) would return 1.1e5, but (1.1e5).AsScale(6) would return 1e6.
func (a int64Amount) AsScale(scale Scale) (int64Amount, bool) {
diff --git a/vendor/k8s.io/apimachinery/pkg/api/resource/generated.pb.go b/vendor/k8s.io/apimachinery/pkg/api/resource/generated.pb.go
index 53a25d344..c3a272168 100644
--- a/vendor/k8s.io/apimachinery/pkg/api/resource/generated.pb.go
+++ b/vendor/k8s.io/apimachinery/pkg/api/resource/generated.pb.go
@@ -15,7 +15,7 @@ limitations under the License.
*/
// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto
+// source: k8s.io/apimachinery/pkg/api/resource/generated.proto
package resource
@@ -41,7 +41,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func (m *Quantity) Reset() { *m = Quantity{} }
func (*Quantity) ProtoMessage() {}
func (*Quantity) Descriptor() ([]byte, []int) {
- return fileDescriptor_612bba87bd70906c, []int{0}
+ return fileDescriptor_7288c78ff45111e9, []int{0}
}
func (m *Quantity) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Quantity.Unmarshal(m, b)
@@ -64,7 +64,7 @@ var xxx_messageInfo_Quantity proto.InternalMessageInfo
func (m *QuantityValue) Reset() { *m = QuantityValue{} }
func (*QuantityValue) ProtoMessage() {}
func (*QuantityValue) Descriptor() ([]byte, []int) {
- return fileDescriptor_612bba87bd70906c, []int{1}
+ return fileDescriptor_7288c78ff45111e9, []int{1}
}
func (m *QuantityValue) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QuantityValue.Unmarshal(m, b)
@@ -90,25 +90,24 @@ func init() {
}
func init() {
- proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto", fileDescriptor_612bba87bd70906c)
+ proto.RegisterFile("k8s.io/apimachinery/pkg/api/resource/generated.proto", fileDescriptor_7288c78ff45111e9)
}
-var fileDescriptor_612bba87bd70906c = []byte{
- // 254 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xf2, 0xcd, 0xb6, 0x28, 0xd6,
- 0xcb, 0xcc, 0xd7, 0xcf, 0x2e, 0x4d, 0x4a, 0x2d, 0xca, 0x4b, 0x2d, 0x49, 0x2d, 0xd6, 0x2f, 0x4b,
- 0xcd, 0x4b, 0xc9, 0x2f, 0xd2, 0x87, 0x4a, 0x24, 0x16, 0x64, 0xe6, 0x26, 0x26, 0x67, 0x64, 0xe6,
- 0xa5, 0x16, 0x55, 0xea, 0x17, 0x64, 0xa7, 0x83, 0x04, 0xf4, 0x8b, 0x52, 0x8b, 0xf3, 0x4b, 0x8b,
- 0x92, 0x53, 0xf5, 0xd3, 0x53, 0xf3, 0x52, 0x8b, 0x12, 0x4b, 0x52, 0x53, 0xf4, 0x0a, 0x8a, 0xf2,
- 0x4b, 0xf2, 0x85, 0x54, 0x20, 0xba, 0xf4, 0x90, 0x75, 0xe9, 0x15, 0x64, 0xa7, 0x83, 0x04, 0xf4,
- 0x60, 0xba, 0xa4, 0x74, 0xd3, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3,
- 0xf3, 0xd3, 0xf3, 0xf5, 0xc1, 0x9a, 0x93, 0x4a, 0xd3, 0xc0, 0x3c, 0x30, 0x07, 0xcc, 0x82, 0x18,
- 0xaa, 0x64, 0xc1, 0xc5, 0x11, 0x58, 0x9a, 0x98, 0x57, 0x92, 0x59, 0x52, 0x29, 0x24, 0xc6, 0xc5,
- 0x56, 0x5c, 0x52, 0x94, 0x99, 0x97, 0x2e, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x19, 0x04, 0xe5, 0x59,
- 0x89, 0xcc, 0x58, 0x20, 0xcf, 0xd0, 0xb1, 0x50, 0x9e, 0x61, 0xc2, 0x42, 0x79, 0x86, 0x05, 0x0b,
- 0xe5, 0x19, 0x1a, 0xee, 0x28, 0x30, 0x28, 0xd9, 0x72, 0xf1, 0xc2, 0x74, 0x86, 0x25, 0xe6, 0x94,
- 0xa6, 0x92, 0xa6, 0xdd, 0xc9, 0xeb, 0xc4, 0x43, 0x39, 0x86, 0x0b, 0x0f, 0xe5, 0x18, 0x6e, 0x3c,
- 0x94, 0x63, 0x68, 0x78, 0x24, 0xc7, 0x78, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x37,
- 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0x43, 0x94, 0x0a, 0x31, 0x21,
- 0x05, 0x08, 0x00, 0x00, 0xff, 0xff, 0x8e, 0x70, 0x98, 0xa3, 0x69, 0x01, 0x00, 0x00,
+var fileDescriptor_7288c78ff45111e9 = []byte{
+ // 234 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0xc9, 0xb6, 0x28, 0xd6,
+ 0xcb, 0xcc, 0xd7, 0x4f, 0x2c, 0xc8, 0xcc, 0x4d, 0x4c, 0xce, 0xc8, 0xcc, 0x4b, 0x2d, 0xaa, 0xd4,
+ 0x2f, 0xc8, 0x4e, 0x07, 0x09, 0xe8, 0x17, 0xa5, 0x16, 0xe7, 0x97, 0x16, 0x25, 0xa7, 0xea, 0xa7,
+ 0xa7, 0xe6, 0xa5, 0x16, 0x25, 0x96, 0xa4, 0xa6, 0xe8, 0x15, 0x14, 0xe5, 0x97, 0xe4, 0x0b, 0xa9,
+ 0x40, 0x74, 0xe9, 0x21, 0xeb, 0xd2, 0x2b, 0xc8, 0x4e, 0x07, 0x09, 0xe8, 0xc1, 0x74, 0x49, 0xe9,
+ 0xa6, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xa7, 0xe7, 0xa7, 0xe7, 0xeb,
+ 0x83, 0x35, 0x27, 0x95, 0xa6, 0x81, 0x79, 0x60, 0x0e, 0x98, 0x05, 0x31, 0x54, 0xc9, 0x82, 0x8b,
+ 0x23, 0xb0, 0x34, 0x31, 0xaf, 0x24, 0xb3, 0xa4, 0x52, 0x48, 0x8c, 0x8b, 0xad, 0xb8, 0xa4, 0x28,
+ 0x33, 0x2f, 0x5d, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, 0xca, 0xb3, 0x12, 0x99, 0xb1, 0x40,
+ 0x9e, 0xa1, 0x63, 0xa1, 0x3c, 0xc3, 0x84, 0x85, 0xf2, 0x0c, 0x0b, 0x16, 0xca, 0x33, 0x34, 0xdc,
+ 0x51, 0x60, 0x50, 0xb2, 0xe5, 0xe2, 0x85, 0xe9, 0x0c, 0x4b, 0xcc, 0x29, 0x4d, 0x25, 0x4d, 0xbb,
+ 0x93, 0xd7, 0x89, 0x87, 0x72, 0x0c, 0x17, 0x1e, 0xca, 0x31, 0xdc, 0x78, 0x28, 0xc7, 0xd0, 0xf0,
+ 0x48, 0x8e, 0xf1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x6f, 0x3c, 0x92, 0x63, 0x7c,
+ 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x28, 0x15, 0x62, 0x42, 0x0a, 0x10, 0x00, 0x00,
+ 0xff, 0xff, 0x50, 0x91, 0xd0, 0x9c, 0x50, 0x01, 0x00, 0x00,
}
diff --git a/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go b/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go
index b47d554b3..d0aada9dd 100644
--- a/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go
+++ b/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go
@@ -20,11 +20,13 @@ import (
"bytes"
"errors"
"fmt"
- "math"
+ math "math"
"math/big"
"strconv"
"strings"
+ cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
+
inf "gopkg.in/inf.v0"
)
@@ -458,9 +460,10 @@ func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byte) {
}
}
-// AsApproximateFloat64 returns a float64 representation of the quantity which may
-// lose precision. If the value of the quantity is outside the range of a float64
-// +Inf/-Inf will be returned.
+// AsApproximateFloat64 returns a float64 representation of the quantity which
+// may lose precision. If precision matter more than performance, see
+// AsFloat64Slow. If the value of the quantity is outside the range of a
+// float64 +Inf/-Inf will be returned.
func (q *Quantity) AsApproximateFloat64() float64 {
var base float64
var exponent int
@@ -478,6 +481,36 @@ func (q *Quantity) AsApproximateFloat64() float64 {
return base * math.Pow10(exponent)
}
+// AsFloat64Slow returns a float64 representation of the quantity. This is
+// more precise than AsApproximateFloat64 but significantly slower. If the
+// value of the quantity is outside the range of a float64 +Inf/-Inf will be
+// returned.
+func (q *Quantity) AsFloat64Slow() float64 {
+ infDec := q.AsDec()
+
+ var absScale int64
+ if infDec.Scale() < 0 {
+ absScale = int64(-infDec.Scale())
+ } else {
+ absScale = int64(infDec.Scale())
+ }
+ pow10AbsScale := big.NewInt(10)
+ pow10AbsScale = pow10AbsScale.Exp(pow10AbsScale, big.NewInt(absScale), nil)
+
+ var resultBigFloat *big.Float
+ if infDec.Scale() < 0 {
+ resultBigInt := new(big.Int).Mul(infDec.UnscaledBig(), pow10AbsScale)
+ resultBigFloat = new(big.Float).SetInt(resultBigInt)
+ } else {
+ pow10AbsScaleFloat := new(big.Float).SetInt(pow10AbsScale)
+ resultBigFloat = new(big.Float).SetInt(infDec.UnscaledBig())
+ resultBigFloat = resultBigFloat.Quo(resultBigFloat, pow10AbsScaleFloat)
+ }
+
+ result, _ := resultBigFloat.Float64()
+ return result
+}
+
// AsInt64 returns a representation of the current value as an int64 if a fast conversion
// is possible. If false is returned, callers must use the inf.Dec form of this quantity.
func (q *Quantity) AsInt64() (int64, bool) {
@@ -592,6 +625,16 @@ func (q *Quantity) Sub(y Quantity) {
q.ToDec().d.Dec.Sub(q.d.Dec, y.AsDec())
}
+// Mul multiplies the provided y to the current value.
+// It will return false if the result is inexact. Otherwise, it will return true.
+func (q *Quantity) Mul(y int64) bool {
+ q.s = ""
+ if q.d.Dec == nil && q.i.Mul(y) {
+ return true
+ }
+ return q.ToDec().d.Dec.Mul(q.d.Dec, inf.NewDec(y, inf.Scale(0))).UnscaledBig().IsInt64()
+}
+
// Cmp returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the
// quantity is greater than y.
func (q *Quantity) Cmp(y Quantity) int {
@@ -673,6 +716,12 @@ func (q Quantity) MarshalJSON() ([]byte, error) {
return result, nil
}
+func (q Quantity) MarshalCBOR() ([]byte, error) {
+ // The call to String() should never return the string "" because the receiver's
+ // address will never be nil.
+ return cbor.Marshal(q.String())
+}
+
// ToUnstructured implements the value.UnstructuredConverter interface.
func (q Quantity) ToUnstructured() interface{} {
return q.String()
@@ -701,6 +750,27 @@ func (q *Quantity) UnmarshalJSON(value []byte) error {
return nil
}
+func (q *Quantity) UnmarshalCBOR(value []byte) error {
+ var s *string
+ if err := cbor.Unmarshal(value, &s); err != nil {
+ return err
+ }
+
+ if s == nil {
+ q.d.Dec = nil
+ q.i = int64Amount{}
+ return nil
+ }
+
+ parsed, err := ParseQuantity(strings.TrimSpace(*s))
+ if err != nil {
+ return err
+ }
+
+ *q = parsed
+ return nil
+}
+
// NewDecimalQuantity returns a new Quantity representing the given
// value in the given format.
func NewDecimalQuantity(b inf.Dec, format Format) *Quantity {
diff --git a/vendor/k8s.io/apimachinery/pkg/api/validation/OWNERS b/vendor/k8s.io/apimachinery/pkg/api/validation/OWNERS
new file mode 100644
index 000000000..402373247
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/api/validation/OWNERS
@@ -0,0 +1,11 @@
+# See the OWNERS docs at https://go.k8s.io/owners
+
+# Disable inheritance as this is an api owners file
+options:
+ no_parent_owners: true
+approvers:
+ - api-approvers
+reviewers:
+ - api-reviewers
+labels:
+ - kind/api-change
diff --git a/vendor/k8s.io/apimachinery/pkg/api/validation/doc.go b/vendor/k8s.io/apimachinery/pkg/api/validation/doc.go
new file mode 100644
index 000000000..9f20152e4
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/api/validation/doc.go
@@ -0,0 +1,18 @@
+/*
+Copyright 2017 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 validation contains generic api type validation functions.
+package validation // import "k8s.io/apimachinery/pkg/api/validation"
diff --git a/vendor/k8s.io/apimachinery/pkg/api/validation/generic.go b/vendor/k8s.io/apimachinery/pkg/api/validation/generic.go
new file mode 100644
index 000000000..e0b5b1490
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/api/validation/generic.go
@@ -0,0 +1,88 @@
+/*
+Copyright 2014 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 validation
+
+import (
+ "strings"
+
+ "k8s.io/apimachinery/pkg/util/validation"
+ "k8s.io/apimachinery/pkg/util/validation/field"
+)
+
+// IsNegativeErrorMsg is a error message for value must be greater than or equal to 0.
+const IsNegativeErrorMsg string = `must be greater than or equal to 0`
+
+// ValidateNameFunc validates that the provided name is valid for a given resource type.
+// Not all resources have the same validation rules for names. Prefix is true
+// if the name will have a value appended to it. If the name is not valid,
+// this returns a list of descriptions of individual characteristics of the
+// value that were not valid. Otherwise this returns an empty list or nil.
+type ValidateNameFunc func(name string, prefix bool) []string
+
+// NameIsDNSSubdomain is a ValidateNameFunc for names that must be a DNS subdomain.
+func NameIsDNSSubdomain(name string, prefix bool) []string {
+ if prefix {
+ name = maskTrailingDash(name)
+ }
+ return validation.IsDNS1123Subdomain(name)
+}
+
+// NameIsDNSLabel is a ValidateNameFunc for names that must be a DNS 1123 label.
+func NameIsDNSLabel(name string, prefix bool) []string {
+ if prefix {
+ name = maskTrailingDash(name)
+ }
+ return validation.IsDNS1123Label(name)
+}
+
+// NameIsDNS1035Label is a ValidateNameFunc for names that must be a DNS 952 label.
+func NameIsDNS1035Label(name string, prefix bool) []string {
+ if prefix {
+ name = maskTrailingDash(name)
+ }
+ return validation.IsDNS1035Label(name)
+}
+
+// ValidateNamespaceName can be used to check whether the given namespace name is valid.
+// Prefix indicates this name will be used as part of generation, in which case
+// trailing dashes are allowed.
+var ValidateNamespaceName = NameIsDNSLabel
+
+// ValidateServiceAccountName can be used to check whether the given service account name is valid.
+// Prefix indicates this name will be used as part of generation, in which case
+// trailing dashes are allowed.
+var ValidateServiceAccountName = NameIsDNSSubdomain
+
+// maskTrailingDash replaces the final character of a string with a subdomain safe
+// value if it is a dash and if the length of this string is greater than 1. Note that
+// this is used when a value could be appended to the string, see ValidateNameFunc
+// for more info.
+func maskTrailingDash(name string) string {
+ if len(name) > 1 && strings.HasSuffix(name, "-") {
+ return name[:len(name)-2] + "a"
+ }
+ return name
+}
+
+// ValidateNonnegativeField validates that given value is not negative.
+func ValidateNonnegativeField(value int64, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ if value < 0 {
+ allErrs = append(allErrs, field.Invalid(fldPath, value, IsNegativeErrorMsg))
+ }
+ return allErrs
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go b/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go
new file mode 100644
index 000000000..54a2883a3
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go
@@ -0,0 +1,265 @@
+/*
+Copyright 2014 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 validation
+
+import (
+ "fmt"
+ "strings"
+
+ apiequality "k8s.io/apimachinery/pkg/api/equality"
+ "k8s.io/apimachinery/pkg/api/meta"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ v1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/util/sets"
+ "k8s.io/apimachinery/pkg/util/validation"
+ "k8s.io/apimachinery/pkg/util/validation/field"
+)
+
+// FieldImmutableErrorMsg is a error message for field is immutable.
+const FieldImmutableErrorMsg string = `field is immutable`
+
+const TotalAnnotationSizeLimitB int = 256 * (1 << 10) // 256 kB
+
+// BannedOwners is a black list of object that are not allowed to be owners.
+var BannedOwners = map[schema.GroupVersionKind]struct{}{
+ {Group: "", Version: "v1", Kind: "Event"}: {},
+}
+
+// ValidateAnnotations validates that a set of annotations are correctly defined.
+func ValidateAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ for k := range annotations {
+ // The rule is QualifiedName except that case doesn't matter, so convert to lowercase before checking.
+ for _, msg := range validation.IsQualifiedName(strings.ToLower(k)) {
+ allErrs = append(allErrs, field.Invalid(fldPath, k, msg))
+ }
+ }
+ if err := ValidateAnnotationsSize(annotations); err != nil {
+ allErrs = append(allErrs, field.TooLong(fldPath, "" /*unused*/, TotalAnnotationSizeLimitB))
+ }
+ return allErrs
+}
+
+func ValidateAnnotationsSize(annotations map[string]string) error {
+ var totalSize int64
+ for k, v := range annotations {
+ totalSize += (int64)(len(k)) + (int64)(len(v))
+ }
+ if totalSize > (int64)(TotalAnnotationSizeLimitB) {
+ return fmt.Errorf("annotations size %d is larger than limit %d", totalSize, TotalAnnotationSizeLimitB)
+ }
+ return nil
+}
+
+func validateOwnerReference(ownerReference metav1.OwnerReference, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ gvk := schema.FromAPIVersionAndKind(ownerReference.APIVersion, ownerReference.Kind)
+ // gvk.Group is empty for the legacy group.
+ if len(gvk.Version) == 0 {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("apiVersion"), ownerReference.APIVersion, "version must not be empty"))
+ }
+ if len(gvk.Kind) == 0 {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("kind"), ownerReference.Kind, "kind must not be empty"))
+ }
+ if len(ownerReference.Name) == 0 {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), ownerReference.Name, "name must not be empty"))
+ }
+ if len(ownerReference.UID) == 0 {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("uid"), ownerReference.UID, "uid must not be empty"))
+ }
+ if _, ok := BannedOwners[gvk]; ok {
+ allErrs = append(allErrs, field.Invalid(fldPath, ownerReference, fmt.Sprintf("%s is disallowed from being an owner", gvk)))
+ }
+ return allErrs
+}
+
+// ValidateOwnerReferences validates that a set of owner references are correctly defined.
+func ValidateOwnerReferences(ownerReferences []metav1.OwnerReference, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ firstControllerName := ""
+ for _, ref := range ownerReferences {
+ allErrs = append(allErrs, validateOwnerReference(ref, fldPath)...)
+ if ref.Controller != nil && *ref.Controller {
+ curControllerName := ref.Kind + "/" + ref.Name
+ if firstControllerName != "" {
+ allErrs = append(allErrs, field.Invalid(fldPath, ownerReferences,
+ fmt.Sprintf("Only one reference can have Controller set to true. Found \"true\" in references for %v and %v", firstControllerName, curControllerName)))
+ } else {
+ firstControllerName = curControllerName
+ }
+ }
+ }
+ return allErrs
+}
+
+// ValidateFinalizerName validates finalizer names.
+func ValidateFinalizerName(stringValue string, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ for _, msg := range validation.IsQualifiedName(stringValue) {
+ allErrs = append(allErrs, field.Invalid(fldPath, stringValue, msg))
+ }
+
+ return allErrs
+}
+
+// ValidateNoNewFinalizers validates the new finalizers has no new finalizers compare to old finalizers.
+func ValidateNoNewFinalizers(newFinalizers []string, oldFinalizers []string, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ extra := sets.NewString(newFinalizers...).Difference(sets.NewString(oldFinalizers...))
+ if len(extra) != 0 {
+ allErrs = append(allErrs, field.Forbidden(fldPath, fmt.Sprintf("no new finalizers can be added if the object is being deleted, found new finalizers %#v", extra.List())))
+ }
+ return allErrs
+}
+
+// ValidateImmutableField validates the new value and the old value are deeply equal.
+func ValidateImmutableField(newVal, oldVal interface{}, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ if !apiequality.Semantic.DeepEqual(oldVal, newVal) {
+ allErrs = append(allErrs, field.Invalid(fldPath, newVal, FieldImmutableErrorMsg))
+ }
+ return allErrs
+}
+
+// ValidateObjectMeta validates an object's metadata on creation. It expects that name generation has already
+// been performed.
+// It doesn't return an error for rootscoped resources with namespace, because namespace should already be cleared before.
+func ValidateObjectMeta(objMeta *metav1.ObjectMeta, requiresNamespace bool, nameFn ValidateNameFunc, fldPath *field.Path) field.ErrorList {
+ metadata, err := meta.Accessor(objMeta)
+ if err != nil {
+ var allErrs field.ErrorList
+ allErrs = append(allErrs, field.Invalid(fldPath, objMeta, err.Error()))
+ return allErrs
+ }
+ return ValidateObjectMetaAccessor(metadata, requiresNamespace, nameFn, fldPath)
+}
+
+// ValidateObjectMetaAccessor validates an object's metadata on creation. It expects that name generation has already
+// been performed.
+// It doesn't return an error for rootscoped resources with namespace, because namespace should already be cleared before.
+func ValidateObjectMetaAccessor(meta metav1.Object, requiresNamespace bool, nameFn ValidateNameFunc, fldPath *field.Path) field.ErrorList {
+ var allErrs field.ErrorList
+
+ if len(meta.GetGenerateName()) != 0 {
+ for _, msg := range nameFn(meta.GetGenerateName(), true) {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("generateName"), meta.GetGenerateName(), msg))
+ }
+ }
+ // If the generated name validates, but the calculated value does not, it's a problem with generation, and we
+ // report it here. This may confuse users, but indicates a programming bug and still must be validated.
+ // If there are multiple fields out of which one is required then add an or as a separator
+ if len(meta.GetName()) == 0 {
+ allErrs = append(allErrs, field.Required(fldPath.Child("name"), "name or generateName is required"))
+ } else {
+ for _, msg := range nameFn(meta.GetName(), false) {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), meta.GetName(), msg))
+ }
+ }
+ if requiresNamespace {
+ if len(meta.GetNamespace()) == 0 {
+ allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), ""))
+ } else {
+ for _, msg := range ValidateNamespaceName(meta.GetNamespace(), false) {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), meta.GetNamespace(), msg))
+ }
+ }
+ } else {
+ if len(meta.GetNamespace()) != 0 {
+ allErrs = append(allErrs, field.Forbidden(fldPath.Child("namespace"), "not allowed on this type"))
+ }
+ }
+
+ allErrs = append(allErrs, ValidateNonnegativeField(meta.GetGeneration(), fldPath.Child("generation"))...)
+ allErrs = append(allErrs, v1validation.ValidateLabels(meta.GetLabels(), fldPath.Child("labels"))...)
+ allErrs = append(allErrs, ValidateAnnotations(meta.GetAnnotations(), fldPath.Child("annotations"))...)
+ allErrs = append(allErrs, ValidateOwnerReferences(meta.GetOwnerReferences(), fldPath.Child("ownerReferences"))...)
+ allErrs = append(allErrs, ValidateFinalizers(meta.GetFinalizers(), fldPath.Child("finalizers"))...)
+ allErrs = append(allErrs, v1validation.ValidateManagedFields(meta.GetManagedFields(), fldPath.Child("managedFields"))...)
+ return allErrs
+}
+
+// ValidateFinalizers tests if the finalizers name are valid, and if there are conflicting finalizers.
+func ValidateFinalizers(finalizers []string, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ hasFinalizerOrphanDependents := false
+ hasFinalizerDeleteDependents := false
+ for _, finalizer := range finalizers {
+ allErrs = append(allErrs, ValidateFinalizerName(finalizer, fldPath)...)
+ if finalizer == metav1.FinalizerOrphanDependents {
+ hasFinalizerOrphanDependents = true
+ }
+ if finalizer == metav1.FinalizerDeleteDependents {
+ hasFinalizerDeleteDependents = true
+ }
+ }
+ if hasFinalizerDeleteDependents && hasFinalizerOrphanDependents {
+ allErrs = append(allErrs, field.Invalid(fldPath, finalizers, fmt.Sprintf("finalizer %s and %s cannot be both set", metav1.FinalizerOrphanDependents, metav1.FinalizerDeleteDependents)))
+ }
+ return allErrs
+}
+
+// ValidateObjectMetaUpdate validates an object's metadata when updated.
+func ValidateObjectMetaUpdate(newMeta, oldMeta *metav1.ObjectMeta, fldPath *field.Path) field.ErrorList {
+ newMetadata, err := meta.Accessor(newMeta)
+ if err != nil {
+ allErrs := field.ErrorList{}
+ allErrs = append(allErrs, field.Invalid(fldPath, newMeta, err.Error()))
+ return allErrs
+ }
+ oldMetadata, err := meta.Accessor(oldMeta)
+ if err != nil {
+ allErrs := field.ErrorList{}
+ allErrs = append(allErrs, field.Invalid(fldPath, oldMeta, err.Error()))
+ return allErrs
+ }
+ return ValidateObjectMetaAccessorUpdate(newMetadata, oldMetadata, fldPath)
+}
+
+// ValidateObjectMetaAccessorUpdate validates an object's metadata when updated.
+func ValidateObjectMetaAccessorUpdate(newMeta, oldMeta metav1.Object, fldPath *field.Path) field.ErrorList {
+ var allErrs field.ErrorList
+
+ // Finalizers cannot be added if the object is already being deleted.
+ if oldMeta.GetDeletionTimestamp() != nil {
+ allErrs = append(allErrs, ValidateNoNewFinalizers(newMeta.GetFinalizers(), oldMeta.GetFinalizers(), fldPath.Child("finalizers"))...)
+ }
+
+ // Reject updates that don't specify a resource version
+ if len(newMeta.GetResourceVersion()) == 0 {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceVersion"), newMeta.GetResourceVersion(), "must be specified for an update"))
+ }
+
+ // Generation shouldn't be decremented
+ if newMeta.GetGeneration() < oldMeta.GetGeneration() {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("generation"), newMeta.GetGeneration(), "must not be decremented"))
+ }
+
+ allErrs = append(allErrs, ValidateImmutableField(newMeta.GetName(), oldMeta.GetName(), fldPath.Child("name"))...)
+ allErrs = append(allErrs, ValidateImmutableField(newMeta.GetNamespace(), oldMeta.GetNamespace(), fldPath.Child("namespace"))...)
+ allErrs = append(allErrs, ValidateImmutableField(newMeta.GetUID(), oldMeta.GetUID(), fldPath.Child("uid"))...)
+ allErrs = append(allErrs, ValidateImmutableField(newMeta.GetCreationTimestamp(), oldMeta.GetCreationTimestamp(), fldPath.Child("creationTimestamp"))...)
+ allErrs = append(allErrs, ValidateImmutableField(newMeta.GetDeletionTimestamp(), oldMeta.GetDeletionTimestamp(), fldPath.Child("deletionTimestamp"))...)
+ allErrs = append(allErrs, ValidateImmutableField(newMeta.GetDeletionGracePeriodSeconds(), oldMeta.GetDeletionGracePeriodSeconds(), fldPath.Child("deletionGracePeriodSeconds"))...)
+
+ allErrs = append(allErrs, v1validation.ValidateLabels(newMeta.GetLabels(), fldPath.Child("labels"))...)
+ allErrs = append(allErrs, ValidateAnnotations(newMeta.GetAnnotations(), fldPath.Child("annotations"))...)
+ allErrs = append(allErrs, ValidateOwnerReferences(newMeta.GetOwnerReferences(), fldPath.Child("ownerReferences"))...)
+ allErrs = append(allErrs, v1validation.ValidateManagedFields(newMeta.GetManagedFields(), fldPath.Child("managedFields"))...)
+
+ return allErrs
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/defaults.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/defaults.go
new file mode 100644
index 000000000..29c6a48b6
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/defaults.go
@@ -0,0 +1,38 @@
+/*
+Copyright 2023 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 internalversion
+
+import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+// SetListOptionsDefaults sets defaults on the provided ListOptions if applicable.
+//
+// TODO(#115478): once the watch-list fg is always on we register this function in the scheme (via AddTypeDefaultingFunc).
+// TODO(#115478): when the function is registered in the scheme remove all callers of this method.
+func SetListOptionsDefaults(obj *ListOptions, isWatchListFeatureEnabled bool) {
+ if !isWatchListFeatureEnabled {
+ return
+ }
+ if obj.SendInitialEvents != nil || len(obj.ResourceVersionMatch) != 0 {
+ return
+ }
+ legacy := obj.ResourceVersion == "" || obj.ResourceVersion == "0"
+ if obj.Watch && legacy {
+ turnOnInitialEvents := true
+ obj.SendInitialEvents = &turnOnInitialEvents
+ obj.ResourceVersionMatch = metav1.ResourceVersionMatchNotOlderThan
+ }
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go
index a49b5f2be..00d2b8c68 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go
@@ -66,6 +66,31 @@ type ListOptions struct {
// it does not recognize and will return a 410 error if the token can no longer be used because
// it has expired.
Continue string
+
+ // `sendInitialEvents=true` may be set together with `watch=true`.
+ // In that case, the watch stream will begin with synthetic events to
+ // produce the current state of objects in the collection. Once all such
+ // events have been sent, a synthetic "Bookmark" event will be sent.
+ // The bookmark will report the ResourceVersion (RV) corresponding to the
+ // set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation.
+ // Afterwards, the watch stream will proceed as usual, sending watch events
+ // corresponding to changes (subsequent to the RV) to objects watched.
+ //
+ // When `sendInitialEvents` option is set, we require `resourceVersionMatch`
+ // option to also be set. The semantic of the watch request is as following:
+ // - `resourceVersionMatch` = NotOlderThan
+ // is interpreted as "data at least as new as the provided `resourceVersion`"
+ // and the bookmark event is send when the state is synced
+ // to a `resourceVersion` at least as fresh as the one provided by the ListOptions.
+ // If `resourceVersion` is unset, this is interpreted as "consistent read" and the
+ // bookmark event is send when the state is synced at least to the moment
+ // when request started being processed.
+ // - `resourceVersionMatch` set to any other value or unset
+ // Invalid error is returned.
+ //
+ // Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward
+ // compatibility reasons) and to false otherwise.
+ SendInitialEvents *bool
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go
index 6d212b846..a6552c276 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go
@@ -115,6 +115,7 @@ func autoConvert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions,
out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds))
out.Limit = in.Limit
out.Continue = in.Continue
+ out.SendInitialEvents = (*bool)(unsafe.Pointer(in.SendInitialEvents))
return nil
}
@@ -137,6 +138,7 @@ func autoConvert_v1_ListOptions_To_internalversion_ListOptions(in *v1.ListOption
out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds))
out.Limit = in.Limit
out.Continue = in.Continue
+ out.SendInitialEvents = (*bool)(unsafe.Pointer(in.SendInitialEvents))
return nil
}
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go
index 6e1eac5c7..af66a2ac4 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go
@@ -75,6 +75,11 @@ func (in *ListOptions) DeepCopyInto(out *ListOptions) {
*out = new(int64)
**out = **in
}
+ if in.SendInitialEvents != nil {
+ in, out := &in.SendInitialEvents, &out.SendInitialEvents
+ *out = new(bool)
+ **out = **in
+ }
return
}
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/OWNERS b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/OWNERS
index e7e5c152d..ec414a84b 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/OWNERS
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/OWNERS
@@ -11,6 +11,7 @@ reviewers:
- luxas
- janetkuo
- justinsb
- - ncdc
- soltysh
- dims
+emeritus_reviewers:
+ - ncdc
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref.go
index 15b45ffa8..5005beb12 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref.go
@@ -18,6 +18,7 @@ package v1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/utils/ptr"
)
// IsControlledBy checks if the object has a controllerRef set to the given owner
@@ -36,10 +37,14 @@ func GetControllerOf(controllee Object) *OwnerReference {
return nil
}
cp := *ref
+ cp.Controller = ptr.To(*ref.Controller)
+ if ref.BlockOwnerDeletion != nil {
+ cp.BlockOwnerDeletion = ptr.To(*ref.BlockOwnerDeletion)
+ }
return &cp
}
-// GetControllerOf returns a pointer to the controllerRef if controllee has a controller
+// GetControllerOfNoCopy returns a pointer to the controllerRef if controllee has a controller
func GetControllerOfNoCopy(controllee Object) *OwnerReference {
refs := controllee.GetOwnerReferences()
for i := range refs {
@@ -52,14 +57,12 @@ func GetControllerOfNoCopy(controllee Object) *OwnerReference {
// NewControllerRef creates an OwnerReference pointing to the given owner.
func NewControllerRef(owner Object, gvk schema.GroupVersionKind) *OwnerReference {
- blockOwnerDeletion := true
- isController := true
return &OwnerReference{
APIVersion: gvk.GroupVersion().String(),
Kind: gvk.Kind,
Name: owner.GetName(),
UID: owner.GetUID(),
- BlockOwnerDeletion: &blockOwnerDeletion,
- Controller: &isController,
+ BlockOwnerDeletion: ptr.To(true),
+ Controller: ptr.To(true),
}
}
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go
index 7e00eb7d9..9ee6c0591 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go
@@ -15,7 +15,7 @@ limitations under the License.
*/
// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto
+// source: k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto
package v1
@@ -52,7 +52,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func (m *APIGroup) Reset() { *m = APIGroup{} }
func (*APIGroup) ProtoMessage() {}
func (*APIGroup) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{0}
+ return fileDescriptor_a8431b6e0aeeb761, []int{0}
}
func (m *APIGroup) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -80,7 +80,7 @@ var xxx_messageInfo_APIGroup proto.InternalMessageInfo
func (m *APIGroupList) Reset() { *m = APIGroupList{} }
func (*APIGroupList) ProtoMessage() {}
func (*APIGroupList) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{1}
+ return fileDescriptor_a8431b6e0aeeb761, []int{1}
}
func (m *APIGroupList) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -108,7 +108,7 @@ var xxx_messageInfo_APIGroupList proto.InternalMessageInfo
func (m *APIResource) Reset() { *m = APIResource{} }
func (*APIResource) ProtoMessage() {}
func (*APIResource) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{2}
+ return fileDescriptor_a8431b6e0aeeb761, []int{2}
}
func (m *APIResource) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -136,7 +136,7 @@ var xxx_messageInfo_APIResource proto.InternalMessageInfo
func (m *APIResourceList) Reset() { *m = APIResourceList{} }
func (*APIResourceList) ProtoMessage() {}
func (*APIResourceList) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{3}
+ return fileDescriptor_a8431b6e0aeeb761, []int{3}
}
func (m *APIResourceList) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -164,7 +164,7 @@ var xxx_messageInfo_APIResourceList proto.InternalMessageInfo
func (m *APIVersions) Reset() { *m = APIVersions{} }
func (*APIVersions) ProtoMessage() {}
func (*APIVersions) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{4}
+ return fileDescriptor_a8431b6e0aeeb761, []int{4}
}
func (m *APIVersions) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -192,7 +192,7 @@ var xxx_messageInfo_APIVersions proto.InternalMessageInfo
func (m *ApplyOptions) Reset() { *m = ApplyOptions{} }
func (*ApplyOptions) ProtoMessage() {}
func (*ApplyOptions) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{5}
+ return fileDescriptor_a8431b6e0aeeb761, []int{5}
}
func (m *ApplyOptions) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -220,7 +220,7 @@ var xxx_messageInfo_ApplyOptions proto.InternalMessageInfo
func (m *Condition) Reset() { *m = Condition{} }
func (*Condition) ProtoMessage() {}
func (*Condition) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{6}
+ return fileDescriptor_a8431b6e0aeeb761, []int{6}
}
func (m *Condition) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -248,7 +248,7 @@ var xxx_messageInfo_Condition proto.InternalMessageInfo
func (m *CreateOptions) Reset() { *m = CreateOptions{} }
func (*CreateOptions) ProtoMessage() {}
func (*CreateOptions) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{7}
+ return fileDescriptor_a8431b6e0aeeb761, []int{7}
}
func (m *CreateOptions) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -276,7 +276,7 @@ var xxx_messageInfo_CreateOptions proto.InternalMessageInfo
func (m *DeleteOptions) Reset() { *m = DeleteOptions{} }
func (*DeleteOptions) ProtoMessage() {}
func (*DeleteOptions) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{8}
+ return fileDescriptor_a8431b6e0aeeb761, []int{8}
}
func (m *DeleteOptions) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -304,7 +304,7 @@ var xxx_messageInfo_DeleteOptions proto.InternalMessageInfo
func (m *Duration) Reset() { *m = Duration{} }
func (*Duration) ProtoMessage() {}
func (*Duration) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{9}
+ return fileDescriptor_a8431b6e0aeeb761, []int{9}
}
func (m *Duration) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -329,10 +329,38 @@ func (m *Duration) XXX_DiscardUnknown() {
var xxx_messageInfo_Duration proto.InternalMessageInfo
+func (m *FieldSelectorRequirement) Reset() { *m = FieldSelectorRequirement{} }
+func (*FieldSelectorRequirement) ProtoMessage() {}
+func (*FieldSelectorRequirement) Descriptor() ([]byte, []int) {
+ return fileDescriptor_a8431b6e0aeeb761, []int{10}
+}
+func (m *FieldSelectorRequirement) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *FieldSelectorRequirement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+}
+func (m *FieldSelectorRequirement) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_FieldSelectorRequirement.Merge(m, src)
+}
+func (m *FieldSelectorRequirement) XXX_Size() int {
+ return m.Size()
+}
+func (m *FieldSelectorRequirement) XXX_DiscardUnknown() {
+ xxx_messageInfo_FieldSelectorRequirement.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FieldSelectorRequirement proto.InternalMessageInfo
+
func (m *FieldsV1) Reset() { *m = FieldsV1{} }
func (*FieldsV1) ProtoMessage() {}
func (*FieldsV1) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{10}
+ return fileDescriptor_a8431b6e0aeeb761, []int{11}
}
func (m *FieldsV1) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -360,7 +388,7 @@ var xxx_messageInfo_FieldsV1 proto.InternalMessageInfo
func (m *GetOptions) Reset() { *m = GetOptions{} }
func (*GetOptions) ProtoMessage() {}
func (*GetOptions) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{11}
+ return fileDescriptor_a8431b6e0aeeb761, []int{12}
}
func (m *GetOptions) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -388,7 +416,7 @@ var xxx_messageInfo_GetOptions proto.InternalMessageInfo
func (m *GroupKind) Reset() { *m = GroupKind{} }
func (*GroupKind) ProtoMessage() {}
func (*GroupKind) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{12}
+ return fileDescriptor_a8431b6e0aeeb761, []int{13}
}
func (m *GroupKind) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -416,7 +444,7 @@ var xxx_messageInfo_GroupKind proto.InternalMessageInfo
func (m *GroupResource) Reset() { *m = GroupResource{} }
func (*GroupResource) ProtoMessage() {}
func (*GroupResource) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{13}
+ return fileDescriptor_a8431b6e0aeeb761, []int{14}
}
func (m *GroupResource) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -444,7 +472,7 @@ var xxx_messageInfo_GroupResource proto.InternalMessageInfo
func (m *GroupVersion) Reset() { *m = GroupVersion{} }
func (*GroupVersion) ProtoMessage() {}
func (*GroupVersion) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{14}
+ return fileDescriptor_a8431b6e0aeeb761, []int{15}
}
func (m *GroupVersion) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -472,7 +500,7 @@ var xxx_messageInfo_GroupVersion proto.InternalMessageInfo
func (m *GroupVersionForDiscovery) Reset() { *m = GroupVersionForDiscovery{} }
func (*GroupVersionForDiscovery) ProtoMessage() {}
func (*GroupVersionForDiscovery) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{15}
+ return fileDescriptor_a8431b6e0aeeb761, []int{16}
}
func (m *GroupVersionForDiscovery) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -500,7 +528,7 @@ var xxx_messageInfo_GroupVersionForDiscovery proto.InternalMessageInfo
func (m *GroupVersionKind) Reset() { *m = GroupVersionKind{} }
func (*GroupVersionKind) ProtoMessage() {}
func (*GroupVersionKind) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{16}
+ return fileDescriptor_a8431b6e0aeeb761, []int{17}
}
func (m *GroupVersionKind) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -528,7 +556,7 @@ var xxx_messageInfo_GroupVersionKind proto.InternalMessageInfo
func (m *GroupVersionResource) Reset() { *m = GroupVersionResource{} }
func (*GroupVersionResource) ProtoMessage() {}
func (*GroupVersionResource) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{17}
+ return fileDescriptor_a8431b6e0aeeb761, []int{18}
}
func (m *GroupVersionResource) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -556,7 +584,7 @@ var xxx_messageInfo_GroupVersionResource proto.InternalMessageInfo
func (m *LabelSelector) Reset() { *m = LabelSelector{} }
func (*LabelSelector) ProtoMessage() {}
func (*LabelSelector) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{18}
+ return fileDescriptor_a8431b6e0aeeb761, []int{19}
}
func (m *LabelSelector) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -584,7 +612,7 @@ var xxx_messageInfo_LabelSelector proto.InternalMessageInfo
func (m *LabelSelectorRequirement) Reset() { *m = LabelSelectorRequirement{} }
func (*LabelSelectorRequirement) ProtoMessage() {}
func (*LabelSelectorRequirement) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{19}
+ return fileDescriptor_a8431b6e0aeeb761, []int{20}
}
func (m *LabelSelectorRequirement) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -612,7 +640,7 @@ var xxx_messageInfo_LabelSelectorRequirement proto.InternalMessageInfo
func (m *List) Reset() { *m = List{} }
func (*List) ProtoMessage() {}
func (*List) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{20}
+ return fileDescriptor_a8431b6e0aeeb761, []int{21}
}
func (m *List) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -640,7 +668,7 @@ var xxx_messageInfo_List proto.InternalMessageInfo
func (m *ListMeta) Reset() { *m = ListMeta{} }
func (*ListMeta) ProtoMessage() {}
func (*ListMeta) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{21}
+ return fileDescriptor_a8431b6e0aeeb761, []int{22}
}
func (m *ListMeta) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -668,7 +696,7 @@ var xxx_messageInfo_ListMeta proto.InternalMessageInfo
func (m *ListOptions) Reset() { *m = ListOptions{} }
func (*ListOptions) ProtoMessage() {}
func (*ListOptions) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{22}
+ return fileDescriptor_a8431b6e0aeeb761, []int{23}
}
func (m *ListOptions) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -696,7 +724,7 @@ var xxx_messageInfo_ListOptions proto.InternalMessageInfo
func (m *ManagedFieldsEntry) Reset() { *m = ManagedFieldsEntry{} }
func (*ManagedFieldsEntry) ProtoMessage() {}
func (*ManagedFieldsEntry) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{23}
+ return fileDescriptor_a8431b6e0aeeb761, []int{24}
}
func (m *ManagedFieldsEntry) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -724,7 +752,7 @@ var xxx_messageInfo_ManagedFieldsEntry proto.InternalMessageInfo
func (m *MicroTime) Reset() { *m = MicroTime{} }
func (*MicroTime) ProtoMessage() {}
func (*MicroTime) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{24}
+ return fileDescriptor_a8431b6e0aeeb761, []int{25}
}
func (m *MicroTime) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_MicroTime.Unmarshal(m, b)
@@ -747,7 +775,7 @@ var xxx_messageInfo_MicroTime proto.InternalMessageInfo
func (m *ObjectMeta) Reset() { *m = ObjectMeta{} }
func (*ObjectMeta) ProtoMessage() {}
func (*ObjectMeta) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{25}
+ return fileDescriptor_a8431b6e0aeeb761, []int{26}
}
func (m *ObjectMeta) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -775,7 +803,7 @@ var xxx_messageInfo_ObjectMeta proto.InternalMessageInfo
func (m *OwnerReference) Reset() { *m = OwnerReference{} }
func (*OwnerReference) ProtoMessage() {}
func (*OwnerReference) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{26}
+ return fileDescriptor_a8431b6e0aeeb761, []int{27}
}
func (m *OwnerReference) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -803,7 +831,7 @@ var xxx_messageInfo_OwnerReference proto.InternalMessageInfo
func (m *PartialObjectMetadata) Reset() { *m = PartialObjectMetadata{} }
func (*PartialObjectMetadata) ProtoMessage() {}
func (*PartialObjectMetadata) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{27}
+ return fileDescriptor_a8431b6e0aeeb761, []int{28}
}
func (m *PartialObjectMetadata) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -831,7 +859,7 @@ var xxx_messageInfo_PartialObjectMetadata proto.InternalMessageInfo
func (m *PartialObjectMetadataList) Reset() { *m = PartialObjectMetadataList{} }
func (*PartialObjectMetadataList) ProtoMessage() {}
func (*PartialObjectMetadataList) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{28}
+ return fileDescriptor_a8431b6e0aeeb761, []int{29}
}
func (m *PartialObjectMetadataList) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -859,7 +887,7 @@ var xxx_messageInfo_PartialObjectMetadataList proto.InternalMessageInfo
func (m *Patch) Reset() { *m = Patch{} }
func (*Patch) ProtoMessage() {}
func (*Patch) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{29}
+ return fileDescriptor_a8431b6e0aeeb761, []int{30}
}
func (m *Patch) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -887,7 +915,7 @@ var xxx_messageInfo_Patch proto.InternalMessageInfo
func (m *PatchOptions) Reset() { *m = PatchOptions{} }
func (*PatchOptions) ProtoMessage() {}
func (*PatchOptions) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{30}
+ return fileDescriptor_a8431b6e0aeeb761, []int{31}
}
func (m *PatchOptions) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -915,7 +943,7 @@ var xxx_messageInfo_PatchOptions proto.InternalMessageInfo
func (m *Preconditions) Reset() { *m = Preconditions{} }
func (*Preconditions) ProtoMessage() {}
func (*Preconditions) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{31}
+ return fileDescriptor_a8431b6e0aeeb761, []int{32}
}
func (m *Preconditions) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -943,7 +971,7 @@ var xxx_messageInfo_Preconditions proto.InternalMessageInfo
func (m *RootPaths) Reset() { *m = RootPaths{} }
func (*RootPaths) ProtoMessage() {}
func (*RootPaths) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{32}
+ return fileDescriptor_a8431b6e0aeeb761, []int{33}
}
func (m *RootPaths) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -971,7 +999,7 @@ var xxx_messageInfo_RootPaths proto.InternalMessageInfo
func (m *ServerAddressByClientCIDR) Reset() { *m = ServerAddressByClientCIDR{} }
func (*ServerAddressByClientCIDR) ProtoMessage() {}
func (*ServerAddressByClientCIDR) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{33}
+ return fileDescriptor_a8431b6e0aeeb761, []int{34}
}
func (m *ServerAddressByClientCIDR) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -999,7 +1027,7 @@ var xxx_messageInfo_ServerAddressByClientCIDR proto.InternalMessageInfo
func (m *Status) Reset() { *m = Status{} }
func (*Status) ProtoMessage() {}
func (*Status) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{34}
+ return fileDescriptor_a8431b6e0aeeb761, []int{35}
}
func (m *Status) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1027,7 +1055,7 @@ var xxx_messageInfo_Status proto.InternalMessageInfo
func (m *StatusCause) Reset() { *m = StatusCause{} }
func (*StatusCause) ProtoMessage() {}
func (*StatusCause) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{35}
+ return fileDescriptor_a8431b6e0aeeb761, []int{36}
}
func (m *StatusCause) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1055,7 +1083,7 @@ var xxx_messageInfo_StatusCause proto.InternalMessageInfo
func (m *StatusDetails) Reset() { *m = StatusDetails{} }
func (*StatusDetails) ProtoMessage() {}
func (*StatusDetails) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{36}
+ return fileDescriptor_a8431b6e0aeeb761, []int{37}
}
func (m *StatusDetails) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1083,7 +1111,7 @@ var xxx_messageInfo_StatusDetails proto.InternalMessageInfo
func (m *TableOptions) Reset() { *m = TableOptions{} }
func (*TableOptions) ProtoMessage() {}
func (*TableOptions) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{37}
+ return fileDescriptor_a8431b6e0aeeb761, []int{38}
}
func (m *TableOptions) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1111,7 +1139,7 @@ var xxx_messageInfo_TableOptions proto.InternalMessageInfo
func (m *Time) Reset() { *m = Time{} }
func (*Time) ProtoMessage() {}
func (*Time) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{38}
+ return fileDescriptor_a8431b6e0aeeb761, []int{39}
}
func (m *Time) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Time.Unmarshal(m, b)
@@ -1134,7 +1162,7 @@ var xxx_messageInfo_Time proto.InternalMessageInfo
func (m *Timestamp) Reset() { *m = Timestamp{} }
func (*Timestamp) ProtoMessage() {}
func (*Timestamp) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{39}
+ return fileDescriptor_a8431b6e0aeeb761, []int{40}
}
func (m *Timestamp) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1162,7 +1190,7 @@ var xxx_messageInfo_Timestamp proto.InternalMessageInfo
func (m *TypeMeta) Reset() { *m = TypeMeta{} }
func (*TypeMeta) ProtoMessage() {}
func (*TypeMeta) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{40}
+ return fileDescriptor_a8431b6e0aeeb761, []int{41}
}
func (m *TypeMeta) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1190,7 +1218,7 @@ var xxx_messageInfo_TypeMeta proto.InternalMessageInfo
func (m *UpdateOptions) Reset() { *m = UpdateOptions{} }
func (*UpdateOptions) ProtoMessage() {}
func (*UpdateOptions) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{41}
+ return fileDescriptor_a8431b6e0aeeb761, []int{42}
}
func (m *UpdateOptions) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1218,7 +1246,7 @@ var xxx_messageInfo_UpdateOptions proto.InternalMessageInfo
func (m *Verbs) Reset() { *m = Verbs{} }
func (*Verbs) ProtoMessage() {}
func (*Verbs) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{42}
+ return fileDescriptor_a8431b6e0aeeb761, []int{43}
}
func (m *Verbs) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1246,7 +1274,7 @@ var xxx_messageInfo_Verbs proto.InternalMessageInfo
func (m *WatchEvent) Reset() { *m = WatchEvent{} }
func (*WatchEvent) ProtoMessage() {}
func (*WatchEvent) Descriptor() ([]byte, []int) {
- return fileDescriptor_cf52fa777ced5367, []int{43}
+ return fileDescriptor_a8431b6e0aeeb761, []int{44}
}
func (m *WatchEvent) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1282,6 +1310,7 @@ func init() {
proto.RegisterType((*CreateOptions)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.CreateOptions")
proto.RegisterType((*DeleteOptions)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.DeleteOptions")
proto.RegisterType((*Duration)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.Duration")
+ proto.RegisterType((*FieldSelectorRequirement)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.FieldSelectorRequirement")
proto.RegisterType((*FieldsV1)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.FieldsV1")
proto.RegisterType((*GetOptions)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.GetOptions")
proto.RegisterType((*GroupKind)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.GroupKind")
@@ -1322,189 +1351,194 @@ func init() {
}
func init() {
- proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto", fileDescriptor_cf52fa777ced5367)
-}
-
-var fileDescriptor_cf52fa777ced5367 = []byte{
- // 2842 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x1a, 0x4b, 0x6f, 0x24, 0x47,
- 0xd9, 0x3d, 0x0f, 0x7b, 0xe6, 0x9b, 0x19, 0x3f, 0x6a, 0xbd, 0x30, 0x6b, 0x84, 0xc7, 0xe9, 0x44,
- 0xd1, 0x06, 0x92, 0x71, 0x76, 0x09, 0xd1, 0x66, 0x43, 0x02, 0x1e, 0xcf, 0x7a, 0xe3, 0x64, 0x1d,
- 0x5b, 0xe5, 0xdd, 0x05, 0x42, 0x84, 0xd2, 0x9e, 0x2e, 0x8f, 0x1b, 0xf7, 0x74, 0x4f, 0xaa, 0x7a,
- 0xbc, 0x19, 0x38, 0x90, 0x03, 0x08, 0x90, 0x50, 0x14, 0x6e, 0x9c, 0x50, 0x22, 0xf8, 0x01, 0x88,
- 0x0b, 0xdc, 0x41, 0x22, 0xc7, 0x20, 0x2e, 0x91, 0x40, 0xa3, 0xc4, 0x1c, 0x38, 0x22, 0xae, 0xbe,
- 0x80, 0xea, 0xd1, 0xdd, 0xd5, 0xf3, 0x58, 0xf7, 0x64, 0x97, 0x88, 0xdb, 0xf4, 0xf7, 0xae, 0xaa,
- 0xaf, 0xbe, 0x47, 0x7d, 0x03, 0x3b, 0xc7, 0xd7, 0x58, 0xdd, 0xf1, 0xd7, 0x8f, 0x7b, 0x07, 0x84,
- 0x7a, 0x24, 0x20, 0x6c, 0xfd, 0x84, 0x78, 0xb6, 0x4f, 0xd7, 0x15, 0xc2, 0xea, 0x3a, 0x1d, 0xab,
- 0x75, 0xe4, 0x78, 0x84, 0xf6, 0xd7, 0xbb, 0xc7, 0x6d, 0x0e, 0x60, 0xeb, 0x1d, 0x12, 0x58, 0xeb,
- 0x27, 0x57, 0xd6, 0xdb, 0xc4, 0x23, 0xd4, 0x0a, 0x88, 0x5d, 0xef, 0x52, 0x3f, 0xf0, 0xd1, 0x63,
- 0x92, 0xab, 0xae, 0x73, 0xd5, 0xbb, 0xc7, 0x6d, 0x0e, 0x60, 0x75, 0xce, 0x55, 0x3f, 0xb9, 0xb2,
- 0xf2, 0x54, 0xdb, 0x09, 0x8e, 0x7a, 0x07, 0xf5, 0x96, 0xdf, 0x59, 0x6f, 0xfb, 0x6d, 0x7f, 0x5d,
- 0x30, 0x1f, 0xf4, 0x0e, 0xc5, 0x97, 0xf8, 0x10, 0xbf, 0xa4, 0xd0, 0x95, 0x89, 0xa6, 0xd0, 0x9e,
- 0x17, 0x38, 0x1d, 0x32, 0x6c, 0xc5, 0xca, 0xb3, 0xe7, 0x31, 0xb0, 0xd6, 0x11, 0xe9, 0x58, 0xc3,
- 0x7c, 0xe6, 0x9f, 0xb3, 0x50, 0xd8, 0xd8, 0xdb, 0xbe, 0x49, 0xfd, 0x5e, 0x17, 0xad, 0x41, 0xce,
- 0xb3, 0x3a, 0xa4, 0x6a, 0xac, 0x19, 0x97, 0x8b, 0x8d, 0xf2, 0x07, 0x83, 0xda, 0xcc, 0xe9, 0xa0,
- 0x96, 0x7b, 0xd5, 0xea, 0x10, 0x2c, 0x30, 0xc8, 0x85, 0xc2, 0x09, 0xa1, 0xcc, 0xf1, 0x3d, 0x56,
- 0xcd, 0xac, 0x65, 0x2f, 0x97, 0xae, 0xbe, 0x58, 0x4f, 0xb3, 0xfe, 0xba, 0x50, 0x70, 0x57, 0xb2,
- 0x6e, 0xf9, 0xb4, 0xe9, 0xb0, 0x96, 0x7f, 0x42, 0x68, 0xbf, 0xb1, 0xa8, 0xb4, 0x14, 0x14, 0x92,
- 0xe1, 0x48, 0x03, 0xfa, 0x91, 0x01, 0x8b, 0x5d, 0x4a, 0x0e, 0x09, 0xa5, 0xc4, 0x56, 0xf8, 0x6a,
- 0x76, 0xcd, 0x78, 0x08, 0x6a, 0xab, 0x4a, 0xed, 0xe2, 0xde, 0x90, 0x7c, 0x3c, 0xa2, 0x11, 0xfd,
- 0xda, 0x80, 0x15, 0x46, 0xe8, 0x09, 0xa1, 0x1b, 0xb6, 0x4d, 0x09, 0x63, 0x8d, 0xfe, 0xa6, 0xeb,
- 0x10, 0x2f, 0xd8, 0xdc, 0x6e, 0x62, 0x56, 0xcd, 0x89, 0x7d, 0xf8, 0x7a, 0x3a, 0x83, 0xf6, 0x27,
- 0xc9, 0x69, 0x98, 0xca, 0xa2, 0x95, 0x89, 0x24, 0x0c, 0xdf, 0xc7, 0x0c, 0xf3, 0x10, 0xca, 0xe1,
- 0x41, 0xde, 0x72, 0x58, 0x80, 0xee, 0xc2, 0x6c, 0x9b, 0x7f, 0xb0, 0xaa, 0x21, 0x0c, 0xac, 0xa7,
- 0x33, 0x30, 0x94, 0xd1, 0x98, 0x57, 0xf6, 0xcc, 0x8a, 0x4f, 0x86, 0x95, 0x34, 0xf3, 0x67, 0x39,
- 0x28, 0x6d, 0xec, 0x6d, 0x63, 0xc2, 0xfc, 0x1e, 0x6d, 0x91, 0x14, 0x4e, 0x73, 0x0d, 0xca, 0xcc,
- 0xf1, 0xda, 0x3d, 0xd7, 0xa2, 0x1c, 0x5a, 0x9d, 0x15, 0x94, 0xcb, 0x8a, 0xb2, 0xbc, 0xaf, 0xe1,
- 0x70, 0x82, 0x12, 0x5d, 0x05, 0xe0, 0x12, 0x58, 0xd7, 0x6a, 0x11, 0xbb, 0x9a, 0x59, 0x33, 0x2e,
- 0x17, 0x1a, 0x48, 0xf1, 0xc1, 0xab, 0x11, 0x06, 0x6b, 0x54, 0xe8, 0x51, 0xc8, 0x0b, 0x4b, 0xab,
- 0x05, 0xa1, 0xa6, 0xa2, 0xc8, 0xf3, 0x62, 0x19, 0x58, 0xe2, 0xd0, 0x13, 0x30, 0xa7, 0xbc, 0xac,
- 0x5a, 0x14, 0x64, 0x0b, 0x8a, 0x6c, 0x2e, 0x74, 0x83, 0x10, 0xcf, 0xd7, 0x77, 0xec, 0x78, 0xb6,
- 0xf0, 0x3b, 0x6d, 0x7d, 0xaf, 0x38, 0x9e, 0x8d, 0x05, 0x06, 0xdd, 0x82, 0xfc, 0x09, 0xa1, 0x07,
- 0xdc, 0x13, 0xb8, 0x6b, 0x7e, 0x39, 0xdd, 0x46, 0xdf, 0xe5, 0x2c, 0x8d, 0x22, 0x37, 0x4d, 0xfc,
- 0xc4, 0x52, 0x08, 0xaa, 0x03, 0xb0, 0x23, 0x9f, 0x06, 0x62, 0x79, 0xd5, 0xfc, 0x5a, 0xf6, 0x72,
- 0xb1, 0x31, 0xcf, 0xd7, 0xbb, 0x1f, 0x41, 0xb1, 0x46, 0xc1, 0xe9, 0x5b, 0x56, 0x40, 0xda, 0x3e,
- 0x75, 0x08, 0xab, 0xce, 0xc5, 0xf4, 0x9b, 0x11, 0x14, 0x6b, 0x14, 0xe8, 0x65, 0x40, 0x2c, 0xf0,
- 0xa9, 0xd5, 0x26, 0x6a, 0xa9, 0x2f, 0x59, 0xec, 0xa8, 0x0a, 0x62, 0x75, 0x2b, 0x6a, 0x75, 0x68,
- 0x7f, 0x84, 0x02, 0x8f, 0xe1, 0x32, 0x7f, 0x67, 0xc0, 0x82, 0xe6, 0x0b, 0xc2, 0xef, 0xae, 0x41,
- 0xb9, 0xad, 0xdd, 0x3a, 0xe5, 0x17, 0xd1, 0x69, 0xeb, 0x37, 0x12, 0x27, 0x28, 0x11, 0x81, 0x22,
- 0x55, 0x92, 0xc2, 0xe8, 0x72, 0x25, 0xb5, 0xd3, 0x86, 0x36, 0xc4, 0x9a, 0x34, 0x20, 0xc3, 0xb1,
- 0x64, 0xf3, 0x9f, 0x86, 0x70, 0xe0, 0x30, 0xde, 0xa0, 0xcb, 0x5a, 0x4c, 0x33, 0xc4, 0xf6, 0x95,
- 0x27, 0xc4, 0xa3, 0x73, 0x02, 0x41, 0xe6, 0xff, 0x22, 0x10, 0x5c, 0x2f, 0xfc, 0xf2, 0xbd, 0xda,
- 0xcc, 0xdb, 0x7f, 0x5f, 0x9b, 0x31, 0x7f, 0x61, 0x40, 0x79, 0xa3, 0xdb, 0x75, 0xfb, 0xbb, 0xdd,
- 0x40, 0x2c, 0xc0, 0x84, 0x59, 0x9b, 0xf6, 0x71, 0xcf, 0x53, 0x0b, 0x05, 0x7e, 0xbf, 0x9b, 0x02,
- 0x82, 0x15, 0x86, 0xdf, 0x9f, 0x43, 0x9f, 0xb6, 0x88, 0xba, 0x6e, 0xd1, 0xfd, 0xd9, 0xe2, 0x40,
- 0x2c, 0x71, 0xfc, 0x90, 0x0f, 0x1d, 0xe2, 0xda, 0x3b, 0x96, 0x67, 0xb5, 0x09, 0x55, 0x97, 0x23,
- 0xda, 0xfa, 0x2d, 0x0d, 0x87, 0x13, 0x94, 0xe6, 0x7f, 0x32, 0x50, 0xdc, 0xf4, 0x3d, 0xdb, 0x09,
- 0xd4, 0xe5, 0x0a, 0xfa, 0xdd, 0x91, 0xe0, 0x71, 0xbb, 0xdf, 0x25, 0x58, 0x60, 0xd0, 0x73, 0x30,
- 0xcb, 0x02, 0x2b, 0xe8, 0x31, 0x61, 0x4f, 0xb1, 0xf1, 0x48, 0x18, 0x96, 0xf6, 0x05, 0xf4, 0x6c,
- 0x50, 0x5b, 0x88, 0xc4, 0x49, 0x10, 0x56, 0x0c, 0xdc, 0xd3, 0xfd, 0x03, 0xb1, 0x51, 0xf6, 0x4d,
- 0x99, 0xf6, 0xc2, 0xfc, 0x91, 0x8d, 0x3d, 0x7d, 0x77, 0x84, 0x02, 0x8f, 0xe1, 0x42, 0x27, 0x80,
- 0x5c, 0x8b, 0x05, 0xb7, 0xa9, 0xe5, 0x31, 0xa1, 0xeb, 0xb6, 0xd3, 0x21, 0xea, 0xc2, 0x7f, 0x29,
- 0xdd, 0x89, 0x73, 0x8e, 0x58, 0xef, 0xad, 0x11, 0x69, 0x78, 0x8c, 0x06, 0xf4, 0x38, 0xcc, 0x52,
- 0x62, 0x31, 0xdf, 0xab, 0xe6, 0xc5, 0xf2, 0xa3, 0xa8, 0x8c, 0x05, 0x14, 0x2b, 0x2c, 0x0f, 0x68,
- 0x1d, 0xc2, 0x98, 0xd5, 0x0e, 0xc3, 0x6b, 0x14, 0xd0, 0x76, 0x24, 0x18, 0x87, 0x78, 0xf3, 0xb7,
- 0x06, 0x54, 0x36, 0x29, 0xb1, 0x02, 0x32, 0x8d, 0x5b, 0x7c, 0xea, 0x13, 0x47, 0x1b, 0xb0, 0x20,
- 0xbe, 0xef, 0x5a, 0xae, 0x63, 0xcb, 0x33, 0xc8, 0x09, 0xe6, 0xcf, 0x2b, 0xe6, 0x85, 0xad, 0x24,
- 0x1a, 0x0f, 0xd3, 0x9b, 0x3f, 0xc9, 0x42, 0xa5, 0x49, 0x5c, 0x12, 0x9b, 0xbc, 0x05, 0xa8, 0x4d,
- 0xad, 0x16, 0xd9, 0x23, 0xd4, 0xf1, 0xed, 0x7d, 0xd2, 0xf2, 0x3d, 0x9b, 0x09, 0x37, 0xca, 0x36,
- 0x3e, 0xc7, 0xf7, 0xf7, 0xe6, 0x08, 0x16, 0x8f, 0xe1, 0x40, 0x2e, 0x54, 0xba, 0x54, 0xfc, 0x16,
- 0x7b, 0x2e, 0xbd, 0xac, 0x74, 0xf5, 0x2b, 0xe9, 0x8e, 0x74, 0x4f, 0x67, 0x6d, 0x2c, 0x9d, 0x0e,
- 0x6a, 0x95, 0x04, 0x08, 0x27, 0x85, 0xa3, 0x6f, 0xc0, 0xa2, 0x4f, 0xbb, 0x47, 0x96, 0xd7, 0x24,
- 0x5d, 0xe2, 0xd9, 0xc4, 0x0b, 0x98, 0xd8, 0xc8, 0x42, 0x63, 0x99, 0xd7, 0x22, 0xbb, 0x43, 0x38,
- 0x3c, 0x42, 0x8d, 0x5e, 0x83, 0xa5, 0x2e, 0xf5, 0xbb, 0x56, 0x5b, 0x6c, 0xcc, 0x9e, 0xef, 0x3a,
- 0xad, 0xbe, 0xda, 0xce, 0x27, 0x4f, 0x07, 0xb5, 0xa5, 0xbd, 0x61, 0xe4, 0xd9, 0xa0, 0x76, 0x41,
- 0x6c, 0x1d, 0x87, 0xc4, 0x48, 0x3c, 0x2a, 0x46, 0x73, 0x83, 0xfc, 0x24, 0x37, 0x30, 0xb7, 0xa1,
- 0xd0, 0xec, 0xa9, 0x3b, 0xf1, 0x02, 0x14, 0x6c, 0xf5, 0x5b, 0xed, 0x7c, 0x78, 0x39, 0x23, 0x9a,
- 0xb3, 0x41, 0xad, 0xc2, 0xcb, 0xcf, 0x7a, 0x08, 0xc0, 0x11, 0x8b, 0xf9, 0x38, 0x14, 0xc4, 0xc1,
- 0xb3, 0xbb, 0x57, 0xd0, 0x22, 0x64, 0xb1, 0x75, 0x4f, 0x48, 0x29, 0x63, 0xfe, 0x53, 0x8b, 0x62,
- 0xbb, 0x00, 0x37, 0x49, 0x10, 0x1e, 0xfc, 0x06, 0x2c, 0x84, 0xa1, 0x3c, 0x99, 0x61, 0x22, 0x6f,
- 0xc2, 0x49, 0x34, 0x1e, 0xa6, 0x37, 0x5f, 0x87, 0xa2, 0xc8, 0x42, 0x3c, 0x85, 0xc7, 0xe5, 0x82,
- 0x71, 0x9f, 0x72, 0x21, 0xac, 0x01, 0x32, 0x93, 0x6a, 0x00, 0xcd, 0x5c, 0x17, 0x2a, 0x92, 0x37,
- 0x2c, 0x90, 0x52, 0x69, 0x78, 0x12, 0x0a, 0xa1, 0x99, 0x4a, 0x4b, 0x54, 0x18, 0x87, 0x82, 0x70,
- 0x44, 0xa1, 0x69, 0x3b, 0x82, 0x44, 0x46, 0x4d, 0xa7, 0x4c, 0xab, 0x7e, 0x32, 0xf7, 0xaf, 0x7e,
- 0x34, 0x4d, 0x3f, 0x84, 0xea, 0xa4, 0x6a, 0xfa, 0x01, 0x72, 0x7e, 0x7a, 0x53, 0xcc, 0x77, 0x0c,
- 0x58, 0xd4, 0x25, 0xa5, 0x3f, 0xbe, 0xf4, 0x4a, 0xce, 0xaf, 0xf6, 0xb4, 0x1d, 0xf9, 0x95, 0x01,
- 0xcb, 0x89, 0xa5, 0x4d, 0x75, 0xe2, 0x53, 0x18, 0xa5, 0x3b, 0x47, 0x76, 0x0a, 0xe7, 0xf8, 0x6b,
- 0x06, 0x2a, 0xb7, 0xac, 0x03, 0xe2, 0xee, 0x13, 0x97, 0xb4, 0x02, 0x9f, 0xa2, 0x1f, 0x40, 0xa9,
- 0x63, 0x05, 0xad, 0x23, 0x01, 0x0d, 0x3b, 0x83, 0x66, 0xba, 0x60, 0x97, 0x90, 0x54, 0xdf, 0x89,
- 0xc5, 0xdc, 0xf0, 0x02, 0xda, 0x6f, 0x5c, 0x50, 0x26, 0x95, 0x34, 0x0c, 0xd6, 0xb5, 0x89, 0x76,
- 0x4e, 0x7c, 0xdf, 0x78, 0xab, 0xcb, 0xcb, 0x96, 0xe9, 0xbb, 0xc8, 0x84, 0x09, 0x98, 0xbc, 0xd9,
- 0x73, 0x28, 0xe9, 0x10, 0x2f, 0x88, 0xdb, 0xb9, 0x9d, 0x21, 0xf9, 0x78, 0x44, 0xe3, 0xca, 0x8b,
- 0xb0, 0x38, 0x6c, 0x3c, 0x8f, 0x3f, 0xc7, 0xa4, 0x2f, 0xcf, 0x0b, 0xf3, 0x9f, 0x68, 0x19, 0xf2,
- 0x27, 0x96, 0xdb, 0x53, 0xb7, 0x11, 0xcb, 0x8f, 0xeb, 0x99, 0x6b, 0x86, 0xf9, 0x1b, 0x03, 0xaa,
- 0x93, 0x0c, 0x41, 0x5f, 0xd4, 0x04, 0x35, 0x4a, 0xca, 0xaa, 0xec, 0x2b, 0xa4, 0x2f, 0xa5, 0xde,
- 0x80, 0x82, 0xdf, 0xe5, 0x35, 0x85, 0x4f, 0xd5, 0xa9, 0x3f, 0x11, 0x9e, 0xe4, 0xae, 0x82, 0x9f,
- 0x0d, 0x6a, 0x17, 0x13, 0xe2, 0x43, 0x04, 0x8e, 0x58, 0x79, 0xa4, 0x16, 0xf6, 0xf0, 0xec, 0x11,
- 0x45, 0xea, 0xbb, 0x02, 0x82, 0x15, 0xc6, 0xfc, 0x83, 0x01, 0x39, 0x51, 0x90, 0xbf, 0x0e, 0x05,
- 0xbe, 0x7f, 0xb6, 0x15, 0x58, 0xc2, 0xae, 0xd4, 0xad, 0x20, 0xe7, 0xde, 0x21, 0x81, 0x15, 0x7b,
- 0x5b, 0x08, 0xc1, 0x91, 0x44, 0x84, 0x21, 0xef, 0x04, 0xa4, 0x13, 0x1e, 0xe4, 0x53, 0x13, 0x45,
- 0xab, 0x87, 0x88, 0x3a, 0xb6, 0xee, 0xdd, 0x78, 0x2b, 0x20, 0x1e, 0x3f, 0x8c, 0xf8, 0x6a, 0x6c,
- 0x73, 0x19, 0x58, 0x8a, 0x32, 0xff, 0x6d, 0x40, 0xa4, 0x8a, 0x3b, 0x3f, 0x23, 0xee, 0xe1, 0x2d,
- 0xc7, 0x3b, 0x56, 0xdb, 0x1a, 0x99, 0xb3, 0xaf, 0xe0, 0x38, 0xa2, 0x18, 0x97, 0x1e, 0x32, 0xd3,
- 0xa5, 0x07, 0xae, 0xb0, 0xe5, 0x7b, 0x81, 0xe3, 0xf5, 0x46, 0x6e, 0xdb, 0xa6, 0x82, 0xe3, 0x88,
- 0x82, 0x17, 0x22, 0x94, 0x74, 0x2c, 0xc7, 0x73, 0xbc, 0x36, 0x5f, 0xc4, 0xa6, 0xdf, 0xf3, 0x02,
- 0x91, 0x91, 0x55, 0x21, 0x82, 0x47, 0xb0, 0x78, 0x0c, 0x87, 0xf9, 0xfb, 0x1c, 0x94, 0xf8, 0x9a,
- 0xc3, 0x3c, 0xf7, 0x3c, 0x54, 0x5c, 0xdd, 0x0b, 0xd4, 0xda, 0x2f, 0x2a, 0x53, 0x92, 0xf7, 0x1a,
- 0x27, 0x69, 0x39, 0xb3, 0x28, 0xa1, 0x22, 0xe6, 0x4c, 0x92, 0x79, 0x4b, 0x47, 0xe2, 0x24, 0x2d,
- 0x8f, 0x5e, 0xf7, 0xf8, 0xfd, 0x50, 0x95, 0x49, 0x74, 0x44, 0xdf, 0xe4, 0x40, 0x2c, 0x71, 0x68,
- 0x07, 0x2e, 0x58, 0xae, 0xeb, 0xdf, 0x13, 0xc0, 0x86, 0xef, 0x1f, 0x77, 0x2c, 0x7a, 0xcc, 0x44,
- 0x33, 0x5d, 0x68, 0x7c, 0x41, 0xb1, 0x5c, 0xd8, 0x18, 0x25, 0xc1, 0xe3, 0xf8, 0xc6, 0x1d, 0x5b,
- 0x6e, 0xca, 0x63, 0x3b, 0x82, 0xe5, 0x21, 0x90, 0xb8, 0xe5, 0xaa, 0xb3, 0x7d, 0x46, 0xc9, 0x59,
- 0xc6, 0x63, 0x68, 0xce, 0x26, 0xc0, 0xf1, 0x58, 0x89, 0xe8, 0x3a, 0xcc, 0x73, 0x4f, 0xf6, 0x7b,
- 0x41, 0x58, 0x77, 0xe6, 0xc5, 0x71, 0xa3, 0xd3, 0x41, 0x6d, 0xfe, 0x76, 0x02, 0x83, 0x87, 0x28,
- 0xf9, 0xe6, 0xba, 0x4e, 0xc7, 0x09, 0xaa, 0x73, 0x82, 0x25, 0xda, 0xdc, 0x5b, 0x1c, 0x88, 0x25,
- 0x2e, 0xe1, 0x81, 0x85, 0xf3, 0x3c, 0xd0, 0xfc, 0x4b, 0x16, 0x90, 0xac, 0xb5, 0x6d, 0x59, 0x4f,
- 0xc9, 0x90, 0xc6, 0x3b, 0x02, 0x55, 0xab, 0x1b, 0x43, 0x1d, 0x81, 0x2a, 0xd3, 0x43, 0x3c, 0xda,
- 0x81, 0xa2, 0x0c, 0x2d, 0xf1, 0x75, 0x59, 0x57, 0xc4, 0xc5, 0xdd, 0x10, 0x71, 0x36, 0xa8, 0xad,
- 0x24, 0xd4, 0x44, 0x18, 0xd1, 0xad, 0xc5, 0x12, 0xd0, 0x55, 0x00, 0xab, 0xeb, 0xe8, 0xef, 0x75,
- 0xc5, 0xf8, 0xd5, 0x26, 0xee, 0xbc, 0xb1, 0x46, 0x85, 0x5e, 0x82, 0x5c, 0xf0, 0xe9, 0x3a, 0xaa,
- 0x82, 0x68, 0x18, 0x79, 0xff, 0x24, 0x24, 0x70, 0xed, 0xc2, 0x9f, 0x19, 0x37, 0x4b, 0x35, 0x43,
- 0x91, 0xf6, 0xad, 0x08, 0x83, 0x35, 0x2a, 0xf4, 0x2d, 0x28, 0x1c, 0xaa, 0x52, 0x54, 0x1c, 0x4c,
- 0xea, 0x10, 0x19, 0x16, 0xb0, 0xf2, 0xc9, 0x20, 0xfc, 0xc2, 0x91, 0x34, 0xf4, 0x55, 0x28, 0xb1,
- 0xde, 0x41, 0x94, 0xbd, 0xe5, 0x69, 0x46, 0xa9, 0x72, 0x3f, 0x46, 0x61, 0x9d, 0xce, 0x7c, 0x13,
- 0x8a, 0x3b, 0x4e, 0x8b, 0xfa, 0xa2, 0x07, 0x7c, 0x02, 0xe6, 0x58, 0xa2, 0xc1, 0x89, 0x4e, 0x32,
- 0xf4, 0xb2, 0x10, 0xcf, 0xdd, 0xcb, 0xb3, 0x3c, 0x5f, 0xb6, 0x31, 0xf9, 0xd8, 0xbd, 0x5e, 0xe5,
- 0x40, 0x2c, 0x71, 0xd7, 0x97, 0x79, 0x81, 0xf0, 0xd3, 0xf7, 0x6b, 0x33, 0xef, 0xbe, 0x5f, 0x9b,
- 0x79, 0xef, 0x7d, 0x55, 0x2c, 0xfc, 0x11, 0x00, 0x76, 0x0f, 0xbe, 0x47, 0x5a, 0x32, 0xec, 0xa6,
- 0x7a, 0xd6, 0x0b, 0x5f, 0x93, 0xc5, 0xb3, 0x5e, 0x66, 0xa8, 0xe8, 0xd3, 0x70, 0x38, 0x41, 0x89,
- 0xd6, 0xa1, 0x18, 0x3d, 0xd8, 0x29, 0xff, 0x58, 0x0a, 0xfd, 0x2d, 0x7a, 0xd5, 0xc3, 0x31, 0x4d,
- 0x22, 0x07, 0xe4, 0xce, 0xcd, 0x01, 0x0d, 0xc8, 0xf6, 0x1c, 0x5b, 0x35, 0xcc, 0x4f, 0x87, 0x39,
- 0xf8, 0xce, 0x76, 0xf3, 0x6c, 0x50, 0x7b, 0x64, 0xd2, 0x3b, 0x79, 0xd0, 0xef, 0x12, 0x56, 0xbf,
- 0xb3, 0xdd, 0xc4, 0x9c, 0x79, 0x5c, 0x40, 0x9a, 0x9d, 0x32, 0x20, 0x5d, 0x05, 0x68, 0xc7, 0xcf,
- 0x0e, 0xf2, 0xbe, 0x47, 0x8e, 0xa8, 0x3d, 0x37, 0x68, 0x54, 0x88, 0xc1, 0x52, 0x8b, 0xb7, 0xe6,
- 0xaa, 0xfd, 0x67, 0x81, 0xd5, 0x91, 0x0f, 0x99, 0xd3, 0xdd, 0x89, 0x4b, 0x4a, 0xcd, 0xd2, 0xe6,
- 0xb0, 0x30, 0x3c, 0x2a, 0x1f, 0xf9, 0xb0, 0x64, 0xab, 0x0e, 0x31, 0x56, 0x5a, 0x9c, 0x5a, 0xe9,
- 0x45, 0xae, 0xb0, 0x39, 0x2c, 0x08, 0x8f, 0xca, 0x46, 0xdf, 0x85, 0x95, 0x10, 0x38, 0xda, 0xa6,
- 0x8b, 0x80, 0x9d, 0x6d, 0xac, 0x9e, 0x0e, 0x6a, 0x2b, 0xcd, 0x89, 0x54, 0xf8, 0x3e, 0x12, 0x90,
- 0x0d, 0xb3, 0xae, 0x2c, 0x70, 0x4b, 0xa2, 0x28, 0xf9, 0x5a, 0xba, 0x55, 0xc4, 0xde, 0x5f, 0xd7,
- 0x0b, 0xdb, 0xe8, 0xc9, 0x45, 0xd5, 0xb4, 0x4a, 0x36, 0x7a, 0x0b, 0x4a, 0x96, 0xe7, 0xf9, 0x81,
- 0x25, 0x1f, 0x0e, 0xca, 0x42, 0xd5, 0xc6, 0xd4, 0xaa, 0x36, 0x62, 0x19, 0x43, 0x85, 0xb4, 0x86,
- 0xc1, 0xba, 0x2a, 0x74, 0x0f, 0x16, 0xfc, 0x7b, 0x1e, 0xa1, 0x98, 0x1c, 0x12, 0x4a, 0xbc, 0x16,
- 0x61, 0xd5, 0x8a, 0xd0, 0xfe, 0x4c, 0x4a, 0xed, 0x09, 0xe6, 0xd8, 0xa5, 0x93, 0x70, 0x86, 0x87,
- 0xb5, 0xa0, 0x3a, 0x8f, 0xad, 0x9e, 0xe5, 0x3a, 0xdf, 0x27, 0x94, 0x55, 0xe7, 0xe3, 0xb7, 0xe6,
- 0xad, 0x08, 0x8a, 0x35, 0x0a, 0xd4, 0x83, 0x4a, 0x47, 0x4f, 0x19, 0xd5, 0x25, 0x61, 0xe6, 0xb5,
- 0x74, 0x66, 0x8e, 0x26, 0xb5, 0xb8, 0x82, 0x49, 0xe0, 0x70, 0x52, 0xcb, 0xca, 0x73, 0x50, 0xfa,
- 0x94, 0xc5, 0x3d, 0x6f, 0x0e, 0x86, 0x0f, 0x64, 0xaa, 0xe6, 0xe0, 0x4f, 0x19, 0x98, 0x4f, 0x6e,
- 0xe3, 0x50, 0x3a, 0xcc, 0xa7, 0x4a, 0x87, 0x61, 0x1b, 0x6a, 0x4c, 0x1c, 0x3a, 0x84, 0xf1, 0x39,
- 0x3b, 0x31, 0x3e, 0xab, 0x30, 0x98, 0x7b, 0x90, 0x30, 0x58, 0x07, 0xe0, 0x75, 0x06, 0xf5, 0x5d,
- 0x97, 0x50, 0x11, 0x01, 0x0b, 0x6a, 0xb8, 0x10, 0x41, 0xb1, 0x46, 0xc1, 0xab, 0xe1, 0x03, 0xd7,
- 0x6f, 0x1d, 0x8b, 0x2d, 0x08, 0x6f, 0xaf, 0x88, 0x7d, 0x05, 0x59, 0x0d, 0x37, 0x46, 0xb0, 0x78,
- 0x0c, 0x87, 0xd9, 0x87, 0x8b, 0x7b, 0x16, 0x0d, 0x1c, 0xcb, 0x8d, 0x6f, 0x8a, 0x68, 0x37, 0xde,
- 0x18, 0x69, 0x66, 0x9e, 0x9e, 0xf6, 0xc6, 0xc5, 0x9b, 0x1f, 0xc3, 0xe2, 0x86, 0xc6, 0xfc, 0x9b,
- 0x01, 0x97, 0xc6, 0xea, 0xfe, 0x0c, 0x9a, 0xa9, 0x37, 0x92, 0xcd, 0xd4, 0xf3, 0x29, 0x5f, 0x21,
- 0xc7, 0x59, 0x3b, 0xa1, 0xb5, 0x9a, 0x83, 0xfc, 0x1e, 0x2f, 0x62, 0xcd, 0x0f, 0x0d, 0x28, 0x8b,
- 0x5f, 0xd3, 0x3c, 0x02, 0xd7, 0x92, 0xb3, 0x81, 0xe2, 0xc3, 0x9b, 0x0b, 0x3c, 0x8c, 0x57, 0xe2,
- 0x77, 0x0c, 0x48, 0x3e, 0xbf, 0xa2, 0x17, 0xe5, 0x15, 0x30, 0xa2, 0xf7, 0xd1, 0x29, 0xdd, 0xff,
- 0x85, 0x49, 0xdd, 0xe4, 0x85, 0x54, 0x0f, 0x8d, 0x4f, 0x42, 0x11, 0xfb, 0x7e, 0xb0, 0x67, 0x05,
- 0x47, 0x8c, 0xef, 0x5d, 0x97, 0xff, 0x50, 0xdb, 0x2b, 0xf6, 0x4e, 0x60, 0xb0, 0x84, 0x9b, 0x3f,
- 0x37, 0xe0, 0xd2, 0xc4, 0x91, 0x0f, 0x8f, 0x22, 0xad, 0xe8, 0x4b, 0xad, 0x28, 0x72, 0xe4, 0x98,
- 0x0e, 0x6b, 0x54, 0xbc, 0x0d, 0x4c, 0xcc, 0x89, 0x86, 0xdb, 0xc0, 0x84, 0x36, 0x9c, 0xa4, 0x35,
- 0xff, 0x95, 0x01, 0x35, 0x63, 0xf9, 0x1f, 0x3b, 0xfd, 0xe3, 0x43, 0x13, 0x9e, 0xf9, 0xe4, 0x84,
- 0x27, 0x1a, 0xe7, 0x68, 0x23, 0x8e, 0xec, 0xfd, 0x47, 0x1c, 0xe8, 0xd9, 0x68, 0x6a, 0x22, 0x7d,
- 0x68, 0x35, 0x39, 0x35, 0x39, 0x1b, 0xd4, 0xca, 0x4a, 0x78, 0x72, 0x8a, 0xf2, 0x1a, 0xcc, 0xd9,
- 0x24, 0xb0, 0x1c, 0x57, 0xb6, 0x74, 0xa9, 0xe7, 0x00, 0x52, 0x58, 0x53, 0xb2, 0x36, 0x4a, 0xdc,
- 0x26, 0xf5, 0x81, 0x43, 0x81, 0x3c, 0x60, 0xb7, 0x7c, 0x5b, 0x76, 0x24, 0xf9, 0x38, 0x60, 0x6f,
- 0xfa, 0x36, 0xc1, 0x02, 0x63, 0xbe, 0x6b, 0x40, 0x49, 0x4a, 0xda, 0xb4, 0x7a, 0x8c, 0xa0, 0x2b,
- 0xd1, 0x2a, 0xe4, 0x71, 0x5f, 0xd2, 0xc7, 0x63, 0x67, 0x83, 0x5a, 0x51, 0x90, 0x89, 0x66, 0x66,
- 0xcc, 0x18, 0x28, 0x73, 0xce, 0x1e, 0x3d, 0x0a, 0x79, 0x71, 0x81, 0xd4, 0x66, 0xc6, 0x73, 0x3e,
- 0x0e, 0xc4, 0x12, 0x67, 0x7e, 0x9c, 0x81, 0x4a, 0x62, 0x71, 0x29, 0xfa, 0x82, 0xe8, 0xf5, 0x33,
- 0x93, 0xe2, 0x45, 0x7d, 0xf2, 0x54, 0x5d, 0xa5, 0xaf, 0xd9, 0x07, 0x49, 0x5f, 0xdf, 0x86, 0xd9,
- 0x16, 0xdf, 0xa3, 0xf0, 0x4f, 0x1a, 0x57, 0xa6, 0x39, 0x4e, 0xb1, 0xbb, 0xb1, 0x37, 0x8a, 0x4f,
- 0x86, 0x95, 0x40, 0x74, 0x13, 0x96, 0x28, 0x09, 0x68, 0x7f, 0xe3, 0x30, 0x20, 0x54, 0x7f, 0x07,
- 0xc8, 0xc7, 0xd5, 0x37, 0x1e, 0x26, 0xc0, 0xa3, 0x3c, 0xe6, 0x01, 0x94, 0x6f, 0x5b, 0x07, 0x6e,
- 0x34, 0xd9, 0xc2, 0x50, 0x71, 0xbc, 0x96, 0xdb, 0xb3, 0x89, 0x0c, 0xe8, 0x61, 0xf4, 0x0a, 0x2f,
- 0xed, 0xb6, 0x8e, 0x3c, 0x1b, 0xd4, 0x2e, 0x24, 0x00, 0x72, 0x94, 0x83, 0x93, 0x22, 0x4c, 0x17,
- 0x72, 0x9f, 0x61, 0x27, 0xf9, 0x1d, 0x28, 0xc6, 0xb5, 0xfe, 0x43, 0x56, 0x69, 0xbe, 0x01, 0x05,
- 0xee, 0xf1, 0x61, 0x8f, 0x7a, 0x4e, 0x95, 0x94, 0xac, 0xbd, 0x32, 0x69, 0x6a, 0x2f, 0x31, 0x1f,
- 0xbd, 0xd3, 0xb5, 0x1f, 0x70, 0x3e, 0x9a, 0x79, 0x90, 0xcc, 0x97, 0x9d, 0x32, 0xf3, 0x5d, 0x05,
- 0xf9, 0x1f, 0x12, 0x9e, 0x64, 0x64, 0x01, 0xa1, 0x25, 0x19, 0x3d, 0xff, 0x6b, 0xc3, 0x81, 0x1f,
- 0x1b, 0x00, 0xe2, 0x15, 0xee, 0xc6, 0x09, 0xf1, 0x82, 0x14, 0x93, 0xf8, 0x3b, 0x30, 0xeb, 0x4b,
- 0x8f, 0x94, 0x33, 0xd2, 0x29, 0x9f, 0x7a, 0xa3, 0x8b, 0x24, 0x7d, 0x12, 0x2b, 0x61, 0x8d, 0x97,
- 0x3f, 0xf8, 0x64, 0x75, 0xe6, 0xc3, 0x4f, 0x56, 0x67, 0x3e, 0xfa, 0x64, 0x75, 0xe6, 0xed, 0xd3,
- 0x55, 0xe3, 0x83, 0xd3, 0x55, 0xe3, 0xc3, 0xd3, 0x55, 0xe3, 0xa3, 0xd3, 0x55, 0xe3, 0xe3, 0xd3,
- 0x55, 0xe3, 0xdd, 0x7f, 0xac, 0xce, 0xbc, 0xf6, 0x58, 0x9a, 0xff, 0xe6, 0xfd, 0x37, 0x00, 0x00,
- 0xff, 0xff, 0x0b, 0x4d, 0x51, 0xc5, 0xdb, 0x27, 0x00, 0x00,
+ proto.RegisterFile("k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto", fileDescriptor_a8431b6e0aeeb761)
+}
+
+var fileDescriptor_a8431b6e0aeeb761 = []byte{
+ // 2928 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x3a, 0x4d, 0x6c, 0x24, 0x47,
+ 0xd5, 0xee, 0xf9, 0xb1, 0x67, 0xde, 0x78, 0xfc, 0x53, 0xeb, 0xfd, 0xbe, 0x59, 0x23, 0x3c, 0x4e,
+ 0x27, 0x8a, 0x36, 0x90, 0x8c, 0x77, 0x97, 0x25, 0xda, 0x6c, 0x48, 0xc0, 0xe3, 0x59, 0x6f, 0x9c,
+ 0xac, 0x63, 0xab, 0xbc, 0xbb, 0x81, 0x10, 0xa1, 0x94, 0xa7, 0xcb, 0xe3, 0xc6, 0x3d, 0xdd, 0x93,
+ 0xaa, 0x1e, 0x6f, 0x06, 0x0e, 0xe4, 0x00, 0x12, 0x48, 0x28, 0x0a, 0x37, 0x4e, 0x28, 0x11, 0x9c,
+ 0x38, 0x21, 0x4e, 0xdc, 0x41, 0x22, 0xc7, 0x20, 0x2e, 0x91, 0x40, 0xa3, 0xac, 0x39, 0x70, 0x44,
+ 0x5c, 0x2d, 0x24, 0x50, 0xfd, 0xf4, 0xdf, 0xfc, 0xac, 0x7b, 0x76, 0x97, 0x88, 0xdb, 0xf4, 0xfb,
+ 0xaf, 0xaa, 0xf7, 0x5e, 0xbd, 0xf7, 0x6a, 0xe0, 0xea, 0xd1, 0x35, 0x5e, 0xb3, 0xbd, 0x35, 0xd2,
+ 0xb1, 0xdb, 0xa4, 0x79, 0x68, 0xbb, 0x94, 0xf5, 0xd6, 0x3a, 0x47, 0x2d, 0x01, 0xe0, 0x6b, 0x6d,
+ 0xea, 0x93, 0xb5, 0xe3, 0xcb, 0x6b, 0x2d, 0xea, 0x52, 0x46, 0x7c, 0x6a, 0xd5, 0x3a, 0xcc, 0xf3,
+ 0x3d, 0xf4, 0x94, 0xe2, 0xaa, 0xc5, 0xb9, 0x6a, 0x9d, 0xa3, 0x96, 0x00, 0xf0, 0x9a, 0xe0, 0xaa,
+ 0x1d, 0x5f, 0x5e, 0x7e, 0xae, 0x65, 0xfb, 0x87, 0xdd, 0xfd, 0x5a, 0xd3, 0x6b, 0xaf, 0xb5, 0xbc,
+ 0x96, 0xb7, 0x26, 0x99, 0xf7, 0xbb, 0x07, 0xf2, 0x4b, 0x7e, 0xc8, 0x5f, 0x4a, 0xe8, 0xf2, 0xda,
+ 0x38, 0x53, 0x58, 0xd7, 0xf5, 0xed, 0x36, 0x1d, 0xb4, 0x62, 0xf9, 0xf9, 0xb3, 0x18, 0x78, 0xf3,
+ 0x90, 0xb6, 0xc9, 0x20, 0x9f, 0xf9, 0xc7, 0x2c, 0x14, 0xd6, 0x77, 0xb7, 0x6e, 0x32, 0xaf, 0xdb,
+ 0x41, 0xab, 0x90, 0x73, 0x49, 0x9b, 0x56, 0x8c, 0x55, 0xe3, 0x62, 0xb1, 0x3e, 0xfb, 0x71, 0xbf,
+ 0x3a, 0x75, 0xd2, 0xaf, 0xe6, 0x5e, 0x27, 0x6d, 0x8a, 0x25, 0x06, 0x39, 0x50, 0x38, 0xa6, 0x8c,
+ 0xdb, 0x9e, 0xcb, 0x2b, 0x99, 0xd5, 0xec, 0xc5, 0xd2, 0x95, 0x97, 0x6b, 0x69, 0xd6, 0x5f, 0x93,
+ 0x0a, 0xee, 0x2a, 0xd6, 0x4d, 0x8f, 0x35, 0x6c, 0xde, 0xf4, 0x8e, 0x29, 0xeb, 0xd5, 0x17, 0xb4,
+ 0x96, 0x82, 0x46, 0x72, 0x1c, 0x6a, 0x40, 0x3f, 0x34, 0x60, 0xa1, 0xc3, 0xe8, 0x01, 0x65, 0x8c,
+ 0x5a, 0x1a, 0x5f, 0xc9, 0xae, 0x1a, 0x8f, 0x41, 0x6d, 0x45, 0xab, 0x5d, 0xd8, 0x1d, 0x90, 0x8f,
+ 0x87, 0x34, 0xa2, 0x5f, 0x1a, 0xb0, 0xcc, 0x29, 0x3b, 0xa6, 0x6c, 0xdd, 0xb2, 0x18, 0xe5, 0xbc,
+ 0xde, 0xdb, 0x70, 0x6c, 0xea, 0xfa, 0x1b, 0x5b, 0x0d, 0xcc, 0x2b, 0x39, 0xb9, 0x0f, 0x5f, 0x4f,
+ 0x67, 0xd0, 0xde, 0x38, 0x39, 0x75, 0x53, 0x5b, 0xb4, 0x3c, 0x96, 0x84, 0xe3, 0x07, 0x98, 0x61,
+ 0x1e, 0xc0, 0x6c, 0x70, 0x90, 0xb7, 0x6c, 0xee, 0xa3, 0xbb, 0x30, 0xdd, 0x12, 0x1f, 0xbc, 0x62,
+ 0x48, 0x03, 0x6b, 0xe9, 0x0c, 0x0c, 0x64, 0xd4, 0xe7, 0xb4, 0x3d, 0xd3, 0xf2, 0x93, 0x63, 0x2d,
+ 0xcd, 0xfc, 0x49, 0x0e, 0x4a, 0xeb, 0xbb, 0x5b, 0x98, 0x72, 0xaf, 0xcb, 0x9a, 0x34, 0x85, 0xd3,
+ 0x5c, 0x83, 0x59, 0x6e, 0xbb, 0xad, 0xae, 0x43, 0x98, 0x80, 0x56, 0xa6, 0x25, 0xe5, 0x92, 0xa6,
+ 0x9c, 0xdd, 0x8b, 0xe1, 0x70, 0x82, 0x12, 0x5d, 0x01, 0x10, 0x12, 0x78, 0x87, 0x34, 0xa9, 0x55,
+ 0xc9, 0xac, 0x1a, 0x17, 0x0b, 0x75, 0xa4, 0xf9, 0xe0, 0xf5, 0x10, 0x83, 0x63, 0x54, 0xe8, 0x49,
+ 0xc8, 0x4b, 0x4b, 0x2b, 0x05, 0xa9, 0xa6, 0xac, 0xc9, 0xf3, 0x72, 0x19, 0x58, 0xe1, 0xd0, 0x33,
+ 0x30, 0xa3, 0xbd, 0xac, 0x52, 0x94, 0x64, 0xf3, 0x9a, 0x6c, 0x26, 0x70, 0x83, 0x00, 0x2f, 0xd6,
+ 0x77, 0x64, 0xbb, 0x96, 0xf4, 0xbb, 0xd8, 0xfa, 0x5e, 0xb3, 0x5d, 0x0b, 0x4b, 0x0c, 0xba, 0x05,
+ 0xf9, 0x63, 0xca, 0xf6, 0x85, 0x27, 0x08, 0xd7, 0xfc, 0x72, 0xba, 0x8d, 0xbe, 0x2b, 0x58, 0xea,
+ 0x45, 0x61, 0x9a, 0xfc, 0x89, 0x95, 0x10, 0x54, 0x03, 0xe0, 0x87, 0x1e, 0xf3, 0xe5, 0xf2, 0x2a,
+ 0xf9, 0xd5, 0xec, 0xc5, 0x62, 0x7d, 0x4e, 0xac, 0x77, 0x2f, 0x84, 0xe2, 0x18, 0x85, 0xa0, 0x6f,
+ 0x12, 0x9f, 0xb6, 0x3c, 0x66, 0x53, 0x5e, 0x99, 0x89, 0xe8, 0x37, 0x42, 0x28, 0x8e, 0x51, 0xa0,
+ 0x57, 0x01, 0x71, 0xdf, 0x63, 0xa4, 0x45, 0xf5, 0x52, 0x5f, 0x21, 0xfc, 0xb0, 0x02, 0x72, 0x75,
+ 0xcb, 0x7a, 0x75, 0x68, 0x6f, 0x88, 0x02, 0x8f, 0xe0, 0x32, 0x7f, 0x6b, 0xc0, 0x7c, 0xcc, 0x17,
+ 0xa4, 0xdf, 0x5d, 0x83, 0xd9, 0x56, 0x2c, 0xea, 0xb4, 0x5f, 0x84, 0xa7, 0x1d, 0x8f, 0x48, 0x9c,
+ 0xa0, 0x44, 0x14, 0x8a, 0x4c, 0x4b, 0x0a, 0xb2, 0xcb, 0xe5, 0xd4, 0x4e, 0x1b, 0xd8, 0x10, 0x69,
+ 0x8a, 0x01, 0x39, 0x8e, 0x24, 0x9b, 0x7f, 0x37, 0xa4, 0x03, 0x07, 0xf9, 0x06, 0x5d, 0x8c, 0xe5,
+ 0x34, 0x43, 0x6e, 0xdf, 0xec, 0x98, 0x7c, 0x74, 0x46, 0x22, 0xc8, 0xfc, 0x4f, 0x24, 0x82, 0xeb,
+ 0x85, 0x9f, 0x7f, 0x58, 0x9d, 0x7a, 0xef, 0xaf, 0xab, 0x53, 0xe6, 0xcf, 0x0c, 0x98, 0x5d, 0xef,
+ 0x74, 0x9c, 0xde, 0x4e, 0xc7, 0x97, 0x0b, 0x30, 0x61, 0xda, 0x62, 0x3d, 0xdc, 0x75, 0xf5, 0x42,
+ 0x41, 0xc4, 0x77, 0x43, 0x42, 0xb0, 0xc6, 0x88, 0xf8, 0x39, 0xf0, 0x58, 0x93, 0xea, 0x70, 0x0b,
+ 0xe3, 0x67, 0x53, 0x00, 0xb1, 0xc2, 0x89, 0x43, 0x3e, 0xb0, 0xa9, 0x63, 0x6d, 0x13, 0x97, 0xb4,
+ 0x28, 0xd3, 0xc1, 0x11, 0x6e, 0xfd, 0x66, 0x0c, 0x87, 0x13, 0x94, 0xe6, 0xbf, 0x33, 0x50, 0xdc,
+ 0xf0, 0x5c, 0xcb, 0xf6, 0x75, 0x70, 0xf9, 0xbd, 0xce, 0x50, 0xf2, 0xb8, 0xdd, 0xeb, 0x50, 0x2c,
+ 0x31, 0xe8, 0x05, 0x98, 0xe6, 0x3e, 0xf1, 0xbb, 0x5c, 0xda, 0x53, 0xac, 0x3f, 0x11, 0xa4, 0xa5,
+ 0x3d, 0x09, 0x3d, 0xed, 0x57, 0xe7, 0x43, 0x71, 0x0a, 0x84, 0x35, 0x83, 0xf0, 0x74, 0x6f, 0x5f,
+ 0x6e, 0x94, 0x75, 0x53, 0x5d, 0x7b, 0xc1, 0xfd, 0x91, 0x8d, 0x3c, 0x7d, 0x67, 0x88, 0x02, 0x8f,
+ 0xe0, 0x42, 0xc7, 0x80, 0x1c, 0xc2, 0xfd, 0xdb, 0x8c, 0xb8, 0x5c, 0xea, 0xba, 0x6d, 0xb7, 0xa9,
+ 0x0e, 0xf8, 0x2f, 0xa5, 0x3b, 0x71, 0xc1, 0x11, 0xe9, 0xbd, 0x35, 0x24, 0x0d, 0x8f, 0xd0, 0x80,
+ 0x9e, 0x86, 0x69, 0x46, 0x09, 0xf7, 0xdc, 0x4a, 0x5e, 0x2e, 0x3f, 0xcc, 0xca, 0x58, 0x42, 0xb1,
+ 0xc6, 0x8a, 0x84, 0xd6, 0xa6, 0x9c, 0x93, 0x56, 0x90, 0x5e, 0xc3, 0x84, 0xb6, 0xad, 0xc0, 0x38,
+ 0xc0, 0x9b, 0xbf, 0x31, 0xa0, 0xbc, 0xc1, 0x28, 0xf1, 0xe9, 0x24, 0x6e, 0xf1, 0xd0, 0x27, 0x8e,
+ 0xd6, 0x61, 0x5e, 0x7e, 0xdf, 0x25, 0x8e, 0x6d, 0xa9, 0x33, 0xc8, 0x49, 0xe6, 0xff, 0xd7, 0xcc,
+ 0xf3, 0x9b, 0x49, 0x34, 0x1e, 0xa4, 0x37, 0x7f, 0x9d, 0x83, 0x72, 0x83, 0x3a, 0x34, 0x32, 0x79,
+ 0x13, 0x50, 0x8b, 0x91, 0x26, 0xdd, 0xa5, 0xcc, 0xf6, 0xac, 0x3d, 0xda, 0xf4, 0x5c, 0x8b, 0x4b,
+ 0x37, 0xca, 0xd6, 0xff, 0x4f, 0xec, 0xef, 0xcd, 0x21, 0x2c, 0x1e, 0xc1, 0x81, 0x1c, 0x28, 0x77,
+ 0x98, 0xfc, 0x2d, 0xf7, 0x5c, 0x79, 0x59, 0xe9, 0xca, 0x57, 0xd2, 0x1d, 0xe9, 0x6e, 0x9c, 0xb5,
+ 0xbe, 0x78, 0xd2, 0xaf, 0x96, 0x13, 0x20, 0x9c, 0x14, 0x8e, 0xbe, 0x01, 0x0b, 0x1e, 0xeb, 0x1c,
+ 0x12, 0xb7, 0x41, 0x3b, 0xd4, 0xb5, 0xa8, 0xeb, 0x73, 0xb9, 0x91, 0x85, 0xfa, 0x92, 0xa8, 0x45,
+ 0x76, 0x06, 0x70, 0x78, 0x88, 0x1a, 0xbd, 0x09, 0x8b, 0x1d, 0xe6, 0x75, 0x48, 0x4b, 0x6e, 0xcc,
+ 0xae, 0xe7, 0xd8, 0xcd, 0x9e, 0xde, 0xce, 0x67, 0x4f, 0xfa, 0xd5, 0xc5, 0xdd, 0x41, 0xe4, 0x69,
+ 0xbf, 0x7a, 0x4e, 0x6e, 0x9d, 0x80, 0x44, 0x48, 0x3c, 0x2c, 0x26, 0xe6, 0x06, 0xf9, 0xb1, 0x6e,
+ 0xf0, 0xa1, 0x01, 0x97, 0xec, 0x96, 0xeb, 0x31, 0x2a, 0xae, 0x08, 0x8a, 0x29, 0xb1, 0x6e, 0x30,
+ 0xe6, 0xb1, 0x37, 0x6c, 0xff, 0x70, 0xc3, 0xe9, 0x72, 0x9f, 0xb2, 0x3a, 0xa3, 0xe4, 0xc8, 0x76,
+ 0x5b, 0xbb, 0x9e, 0x4f, 0x5d, 0xdf, 0x26, 0x8e, 0xf4, 0xc8, 0x42, 0xfd, 0xea, 0x49, 0xbf, 0x7a,
+ 0x69, 0x6b, 0x42, 0x5e, 0x3c, 0xb1, 0x36, 0x73, 0x0b, 0x0a, 0x8d, 0xae, 0x0e, 0xdb, 0x97, 0xa0,
+ 0x60, 0xe9, 0xdf, 0xda, 0x39, 0x82, 0xfc, 0x11, 0xd2, 0x9c, 0xf6, 0xab, 0x65, 0x51, 0x21, 0xd7,
+ 0x02, 0x00, 0x0e, 0x59, 0xcc, 0x5f, 0x19, 0x50, 0x91, 0xce, 0xb9, 0x47, 0x1d, 0xda, 0xf4, 0x3d,
+ 0x86, 0xe9, 0x3b, 0x5d, 0x9b, 0xd1, 0x36, 0x75, 0x7d, 0xf4, 0x45, 0xc8, 0x1e, 0xd1, 0x9e, 0x4e,
+ 0x5d, 0x25, 0x2d, 0x36, 0xfb, 0x1a, 0xed, 0x61, 0x01, 0x47, 0x37, 0xa0, 0xe0, 0x75, 0x44, 0xfa,
+ 0xf0, 0x98, 0x4e, 0x5d, 0xcf, 0x04, 0xaa, 0x77, 0x34, 0xfc, 0xb4, 0x5f, 0x3d, 0x9f, 0x10, 0x1f,
+ 0x20, 0x70, 0xc8, 0x2a, 0x0e, 0xe5, 0x98, 0x38, 0x5d, 0x2a, 0x1c, 0x25, 0x3c, 0x94, 0xbb, 0x12,
+ 0x82, 0x35, 0xc6, 0x7c, 0x1a, 0x0a, 0x52, 0x0c, 0xbf, 0x7b, 0x19, 0x2d, 0x40, 0x16, 0x93, 0x7b,
+ 0xd2, 0xaa, 0x59, 0x2c, 0x7e, 0xc6, 0xee, 0x83, 0x1d, 0x80, 0x9b, 0xd4, 0x0f, 0x42, 0x68, 0x1d,
+ 0xe6, 0x83, 0x4b, 0x31, 0x79, 0x57, 0x87, 0x71, 0x89, 0x93, 0x68, 0x3c, 0x48, 0x6f, 0xbe, 0x05,
+ 0x45, 0x79, 0x9f, 0x8b, 0x62, 0x28, 0x2a, 0xbc, 0x8c, 0x07, 0x14, 0x5e, 0x41, 0x35, 0x95, 0x19,
+ 0x57, 0x4d, 0xc5, 0xcc, 0x75, 0xa0, 0xac, 0x78, 0x83, 0x52, 0x33, 0x95, 0x86, 0x67, 0xa1, 0x10,
+ 0x98, 0xa9, 0xb5, 0x84, 0x2d, 0x46, 0x20, 0x08, 0x87, 0x14, 0x31, 0x6d, 0x87, 0x90, 0xa8, 0x4d,
+ 0xd2, 0x29, 0x8b, 0xd5, 0x91, 0x99, 0x07, 0xd7, 0x91, 0x31, 0x4d, 0x3f, 0x80, 0xca, 0xb8, 0xbe,
+ 0xe4, 0x11, 0xaa, 0xa7, 0xf4, 0xa6, 0x98, 0xef, 0x1b, 0xb0, 0x10, 0x97, 0x94, 0xfe, 0xf8, 0xd2,
+ 0x2b, 0x39, 0xbb, 0x6e, 0x8e, 0xed, 0xc8, 0x2f, 0x0c, 0x58, 0x4a, 0x2c, 0x6d, 0xa2, 0x13, 0x9f,
+ 0xc0, 0xa8, 0xb8, 0x73, 0x64, 0x27, 0x70, 0x8e, 0x3f, 0x67, 0xa0, 0x7c, 0x8b, 0xec, 0x53, 0x27,
+ 0x88, 0x54, 0xf4, 0x7d, 0x28, 0xb5, 0x89, 0xdf, 0x3c, 0x94, 0xd0, 0xa0, 0xc7, 0x6a, 0xa4, 0xbb,
+ 0x36, 0x12, 0x92, 0x6a, 0xdb, 0x91, 0x98, 0x1b, 0xae, 0xcf, 0x7a, 0xf5, 0x73, 0xda, 0xa4, 0x52,
+ 0x0c, 0x83, 0xe3, 0xda, 0x64, 0x63, 0x2c, 0xbf, 0x6f, 0xbc, 0xdb, 0x11, 0x05, 0xe0, 0xe4, 0xfd,
+ 0x78, 0xc2, 0x84, 0x58, 0x56, 0x8b, 0x1a, 0xe3, 0xed, 0x01, 0xf9, 0x78, 0x48, 0xe3, 0xf2, 0xcb,
+ 0xb0, 0x30, 0x68, 0xbc, 0xc8, 0x3f, 0x61, 0x56, 0x54, 0x89, 0x70, 0x09, 0xf2, 0x32, 0x4f, 0xa9,
+ 0xc3, 0xc1, 0xea, 0xe3, 0x7a, 0xe6, 0x9a, 0x21, 0xd3, 0xeb, 0x38, 0x43, 0x1e, 0x53, 0x7a, 0x4d,
+ 0x88, 0x7f, 0xc8, 0xf4, 0xfa, 0x3b, 0x03, 0x72, 0xb2, 0xb5, 0x79, 0x0b, 0x0a, 0x62, 0xff, 0x2c,
+ 0xe2, 0x13, 0x69, 0x57, 0xea, 0xa6, 0x5a, 0x70, 0x6f, 0x53, 0x9f, 0x44, 0xde, 0x16, 0x40, 0x70,
+ 0x28, 0x11, 0x61, 0xc8, 0xdb, 0x3e, 0x6d, 0x07, 0x07, 0xf9, 0xdc, 0x58, 0xd1, 0x7a, 0xa4, 0x53,
+ 0xc3, 0xe4, 0xde, 0x8d, 0x77, 0x7d, 0xea, 0x8a, 0xc3, 0x88, 0x42, 0x63, 0x4b, 0xc8, 0xc0, 0x4a,
+ 0x94, 0xf9, 0x4f, 0x03, 0x42, 0x55, 0xc2, 0xf9, 0x39, 0x75, 0x0e, 0x6e, 0xd9, 0xee, 0x91, 0xde,
+ 0xd6, 0xd0, 0x9c, 0x3d, 0x0d, 0xc7, 0x21, 0xc5, 0xa8, 0xeb, 0x21, 0x33, 0xd9, 0xf5, 0x20, 0x14,
+ 0x36, 0x3d, 0xd7, 0xb7, 0xdd, 0xee, 0x50, 0xb4, 0x6d, 0x68, 0x38, 0x0e, 0x29, 0x44, 0x49, 0xc7,
+ 0x68, 0x9b, 0xd8, 0xae, 0xed, 0xb6, 0xc4, 0x22, 0x36, 0xbc, 0xae, 0xeb, 0xcb, 0xda, 0x46, 0x97,
+ 0x74, 0x78, 0x08, 0x8b, 0x47, 0x70, 0x98, 0xff, 0xca, 0x41, 0x49, 0xac, 0x39, 0xb8, 0xe7, 0x5e,
+ 0x84, 0xb2, 0x13, 0xf7, 0x02, 0xbd, 0xf6, 0xf3, 0xda, 0x94, 0x64, 0x5c, 0xe3, 0x24, 0xad, 0x60,
+ 0x3e, 0x88, 0xdf, 0xd0, 0x7a, 0x0f, 0x42, 0xe6, 0x64, 0x75, 0x90, 0xa4, 0x15, 0xd9, 0xeb, 0x9e,
+ 0x88, 0x0f, 0x5d, 0xe3, 0x85, 0x47, 0xf4, 0x86, 0x00, 0x62, 0x85, 0x43, 0xdb, 0x70, 0x8e, 0x38,
+ 0x8e, 0x77, 0x4f, 0x02, 0xeb, 0x9e, 0x77, 0xd4, 0x26, 0xec, 0x88, 0xcb, 0xb1, 0x44, 0xa1, 0xfe,
+ 0x05, 0xcd, 0x72, 0x6e, 0x7d, 0x98, 0x04, 0x8f, 0xe2, 0x1b, 0x75, 0x6c, 0xb9, 0x09, 0x8f, 0xed,
+ 0x10, 0x96, 0x06, 0x40, 0x32, 0xca, 0xf5, 0x8c, 0xe0, 0xaa, 0x96, 0xb3, 0x84, 0x47, 0xd0, 0x9c,
+ 0x8e, 0x81, 0xe3, 0x91, 0x12, 0xd1, 0x75, 0x98, 0x13, 0x9e, 0xec, 0x75, 0xfd, 0xa0, 0x82, 0xcf,
+ 0xcb, 0xe3, 0x46, 0x27, 0xfd, 0xea, 0xdc, 0xed, 0x04, 0x06, 0x0f, 0x50, 0x8a, 0xcd, 0x75, 0xec,
+ 0xb6, 0xed, 0x57, 0x66, 0x24, 0x4b, 0xb8, 0xb9, 0xb7, 0x04, 0x10, 0x2b, 0x5c, 0xc2, 0x03, 0x0b,
+ 0x67, 0x7a, 0xe0, 0x06, 0x2c, 0x72, 0xea, 0x5a, 0x5b, 0xae, 0x2d, 0x0a, 0xc9, 0x1b, 0xc7, 0xb2,
+ 0x3e, 0x2f, 0xc9, 0x83, 0x38, 0x2f, 0x8a, 0xeb, 0xbd, 0x41, 0x24, 0x1e, 0xa6, 0x37, 0xff, 0x94,
+ 0x05, 0xa4, 0x5a, 0x1f, 0x4b, 0x15, 0x65, 0x2a, 0x2f, 0x8a, 0x06, 0x4d, 0xb7, 0x4e, 0xc6, 0x40,
+ 0x83, 0xa6, 0xbb, 0xa6, 0x00, 0x8f, 0xb6, 0xa1, 0xa8, 0xf2, 0x53, 0x14, 0x73, 0x6b, 0x9a, 0xb8,
+ 0xb8, 0x13, 0x20, 0x4e, 0xfb, 0xd5, 0xe5, 0x84, 0x9a, 0x10, 0x23, 0x9b, 0xe7, 0x48, 0x02, 0xba,
+ 0x02, 0x40, 0x3a, 0x76, 0x7c, 0x7c, 0x5a, 0x8c, 0x86, 0x68, 0xd1, 0x20, 0x04, 0xc7, 0xa8, 0xd0,
+ 0x2b, 0x90, 0xf3, 0x1f, 0xae, 0xc1, 0x2d, 0xc8, 0xfe, 0x5d, 0xb4, 0xb3, 0x52, 0x82, 0xd0, 0x2e,
+ 0x83, 0x82, 0x0b, 0xb3, 0x74, 0x6f, 0x1a, 0x6a, 0xdf, 0x0c, 0x31, 0x38, 0x46, 0x85, 0xbe, 0x09,
+ 0x85, 0x03, 0x5d, 0xcf, 0xca, 0xd3, 0x4d, 0x9d, 0x67, 0x83, 0x2a, 0x58, 0x4d, 0x70, 0x82, 0x2f,
+ 0x1c, 0x4a, 0x43, 0x5f, 0x85, 0x12, 0xef, 0xee, 0x87, 0x25, 0x80, 0x72, 0x89, 0xf0, 0xbe, 0xdd,
+ 0x8b, 0x50, 0x38, 0x4e, 0x67, 0xbe, 0x03, 0xc5, 0x6d, 0xbb, 0xc9, 0x3c, 0xd9, 0x92, 0x3f, 0x03,
+ 0x33, 0x3c, 0xd1, 0x6f, 0x86, 0x27, 0x19, 0xb8, 0x6a, 0x80, 0x17, 0x3e, 0xea, 0x12, 0xd7, 0x53,
+ 0x5d, 0x65, 0x3e, 0xf2, 0xd1, 0xd7, 0x05, 0x10, 0x2b, 0xdc, 0xf5, 0x25, 0x51, 0x65, 0xfc, 0xf8,
+ 0xa3, 0xea, 0xd4, 0x07, 0x1f, 0x55, 0xa7, 0x3e, 0xfc, 0x48, 0x57, 0x1c, 0xbf, 0x07, 0x80, 0x9d,
+ 0xfd, 0xef, 0xd2, 0xa6, 0xca, 0xdd, 0xa9, 0xa6, 0xac, 0xc1, 0x70, 0x5f, 0x4e, 0x59, 0x33, 0x03,
+ 0x95, 0x63, 0x0c, 0x87, 0x13, 0x94, 0x68, 0x0d, 0x8a, 0xe1, 0xfc, 0x54, 0xfb, 0xc7, 0x62, 0xe0,
+ 0x6f, 0xe1, 0x90, 0x15, 0x47, 0x34, 0x89, 0x8b, 0x24, 0x77, 0xe6, 0x45, 0x52, 0x87, 0x6c, 0xd7,
+ 0xb6, 0xf4, 0xfc, 0xe2, 0x52, 0x70, 0x91, 0xdf, 0xd9, 0x6a, 0x9c, 0xf6, 0xab, 0x4f, 0x8c, 0x7b,
+ 0xb6, 0xf0, 0x7b, 0x1d, 0xca, 0x6b, 0x77, 0xb6, 0x1a, 0x58, 0x30, 0x8f, 0xca, 0x6a, 0xd3, 0x13,
+ 0x66, 0xb5, 0x2b, 0x00, 0xad, 0x68, 0x0a, 0xa4, 0x92, 0x46, 0xe8, 0x88, 0xb1, 0xe9, 0x4f, 0x8c,
+ 0x0a, 0x71, 0x58, 0x6c, 0x32, 0x4a, 0x82, 0x69, 0x0c, 0xf7, 0x49, 0x5b, 0xcd, 0x95, 0x27, 0x8b,
+ 0x89, 0x0b, 0x5a, 0xcd, 0xe2, 0xc6, 0xa0, 0x30, 0x3c, 0x2c, 0x1f, 0x79, 0xb0, 0x68, 0xe9, 0x86,
+ 0x3d, 0x52, 0x5a, 0x9c, 0x58, 0xa9, 0xcc, 0x58, 0x8d, 0x41, 0x41, 0x78, 0x58, 0x36, 0xfa, 0x0e,
+ 0x2c, 0x07, 0xc0, 0xe1, 0xa9, 0x89, 0xcc, 0xfa, 0xd9, 0xfa, 0xca, 0x49, 0xbf, 0xba, 0xdc, 0x18,
+ 0x4b, 0x85, 0x1f, 0x20, 0x01, 0x59, 0x30, 0xed, 0xa8, 0x2a, 0xb9, 0x24, 0x2b, 0x9b, 0xaf, 0xa5,
+ 0x5b, 0x45, 0xe4, 0xfd, 0xb5, 0x78, 0x75, 0x1c, 0x4e, 0xc0, 0x74, 0x61, 0xac, 0x65, 0xa3, 0x77,
+ 0xa1, 0x44, 0x5c, 0xd7, 0xf3, 0x89, 0x9a, 0xe3, 0xcc, 0x4a, 0x55, 0xeb, 0x13, 0xab, 0x5a, 0x8f,
+ 0x64, 0x0c, 0x54, 0xe3, 0x31, 0x0c, 0x8e, 0xab, 0x42, 0xf7, 0x60, 0xde, 0xbb, 0xe7, 0x52, 0x86,
+ 0xe9, 0x01, 0x65, 0xd4, 0x6d, 0x52, 0x5e, 0x29, 0x4b, 0xed, 0x57, 0x53, 0x6a, 0x4f, 0x30, 0x47,
+ 0x2e, 0x9d, 0x84, 0x73, 0x3c, 0xa8, 0x05, 0xd5, 0x44, 0x6e, 0x75, 0x89, 0x63, 0x7f, 0x8f, 0x32,
+ 0x5e, 0x99, 0x8b, 0x46, 0xff, 0x9b, 0x21, 0x14, 0xc7, 0x28, 0x50, 0x17, 0xca, 0xed, 0xf8, 0x95,
+ 0x51, 0x59, 0x94, 0x66, 0x5e, 0x4b, 0x67, 0xe6, 0xf0, 0xa5, 0x16, 0x95, 0x41, 0x09, 0x1c, 0x4e,
+ 0x6a, 0x59, 0x7e, 0x01, 0x4a, 0x0f, 0xd9, 0x21, 0x88, 0x0e, 0x63, 0xf0, 0x40, 0x26, 0xea, 0x30,
+ 0xfe, 0x90, 0x81, 0xb9, 0xe4, 0x36, 0x0e, 0x5c, 0x87, 0xf9, 0x54, 0xd7, 0x61, 0xd0, 0xcb, 0x1a,
+ 0x63, 0xdf, 0x80, 0x82, 0xfc, 0x9c, 0x1d, 0x9b, 0x9f, 0x75, 0x1a, 0xcc, 0x3d, 0x4a, 0x1a, 0xac,
+ 0x01, 0x88, 0x62, 0x85, 0x79, 0x8e, 0x43, 0x99, 0x1e, 0xab, 0xa9, 0xb7, 0x9e, 0x10, 0x8a, 0x63,
+ 0x14, 0xa2, 0xa4, 0xde, 0x77, 0xbc, 0xe6, 0x91, 0xdc, 0x82, 0x20, 0x7a, 0x65, 0xee, 0x2b, 0xa8,
+ 0x92, 0xba, 0x3e, 0x84, 0xc5, 0x23, 0x38, 0xcc, 0x1e, 0x9c, 0xdf, 0x25, 0x4c, 0x14, 0x39, 0x51,
+ 0xa4, 0xc8, 0x9e, 0xe5, 0xed, 0xa1, 0x8e, 0xe8, 0xd2, 0xa4, 0x11, 0x17, 0x6d, 0x7e, 0x04, 0x8b,
+ 0xba, 0x22, 0xf3, 0x2f, 0x06, 0x5c, 0x18, 0xa9, 0xfb, 0x73, 0xe8, 0xc8, 0xde, 0x4e, 0x76, 0x64,
+ 0x2f, 0xa6, 0x1c, 0x0a, 0x8f, 0xb2, 0x76, 0x4c, 0x7f, 0x36, 0x03, 0xf9, 0x5d, 0x51, 0x09, 0x9b,
+ 0x9f, 0x18, 0x30, 0x2b, 0x7f, 0x4d, 0x32, 0x93, 0xaf, 0x26, 0x9f, 0x6a, 0x8a, 0x8f, 0xef, 0x99,
+ 0xe6, 0x71, 0x0c, 0xed, 0xdf, 0x37, 0x20, 0x39, 0x0d, 0x47, 0x2f, 0xab, 0x10, 0x30, 0xc2, 0x71,
+ 0xf5, 0x84, 0xee, 0xff, 0xd2, 0xb8, 0x96, 0xf4, 0x5c, 0xaa, 0x69, 0xe5, 0xb3, 0x50, 0xc4, 0x9e,
+ 0xe7, 0xef, 0x12, 0xff, 0x90, 0x8b, 0xbd, 0xeb, 0x88, 0x1f, 0x7a, 0x7b, 0xe5, 0xde, 0x49, 0x0c,
+ 0x56, 0x70, 0xf3, 0xa7, 0x06, 0x5c, 0x18, 0xfb, 0x02, 0x27, 0xb2, 0x48, 0x33, 0xfc, 0xd2, 0x2b,
+ 0x0a, 0x1d, 0x39, 0xa2, 0xc3, 0x31, 0x2a, 0xd1, 0x4b, 0x26, 0x9e, 0xed, 0x06, 0x7b, 0xc9, 0x84,
+ 0x36, 0x9c, 0xa4, 0x35, 0xff, 0x91, 0x01, 0xfd, 0xe4, 0xf5, 0x5f, 0x76, 0xfa, 0xa7, 0x07, 0x1e,
+ 0xdc, 0xe6, 0x92, 0x0f, 0x6e, 0xe1, 0xeb, 0x5a, 0xec, 0xc5, 0x29, 0xfb, 0xe0, 0x17, 0x27, 0xf4,
+ 0x7c, 0xf8, 0x88, 0xa5, 0x7c, 0x68, 0x25, 0xf9, 0x88, 0x75, 0xda, 0xaf, 0xce, 0x6a, 0xe1, 0xc9,
+ 0x47, 0xad, 0x37, 0x61, 0xc6, 0xa2, 0x3e, 0xb1, 0x1d, 0xd5, 0x17, 0xa6, 0x7e, 0x96, 0x51, 0xc2,
+ 0x1a, 0x8a, 0xb5, 0x5e, 0x12, 0x36, 0xe9, 0x0f, 0x1c, 0x08, 0x14, 0x09, 0xbb, 0xe9, 0x59, 0xaa,
+ 0x23, 0xc9, 0x47, 0x09, 0x7b, 0xc3, 0xb3, 0x28, 0x96, 0x18, 0xf3, 0x03, 0x03, 0x4a, 0x4a, 0xd2,
+ 0x06, 0xe9, 0x72, 0x8a, 0x2e, 0x87, 0xab, 0x50, 0xc7, 0x7d, 0x21, 0xfe, 0x5a, 0x79, 0xda, 0xaf,
+ 0x16, 0x25, 0x99, 0x6c, 0x66, 0x46, 0xbc, 0xca, 0x65, 0xce, 0xd8, 0xa3, 0x27, 0x21, 0x2f, 0x03,
+ 0x48, 0x6f, 0x66, 0xf4, 0xec, 0x2a, 0x80, 0x58, 0xe1, 0xcc, 0xcf, 0x32, 0x50, 0x4e, 0x2c, 0x2e,
+ 0x45, 0x5f, 0x10, 0x8e, 0x50, 0x33, 0x29, 0xc6, 0xf2, 0xe3, 0xff, 0xe4, 0xa0, 0xaf, 0xaf, 0xe9,
+ 0x47, 0xb9, 0xbe, 0xbe, 0x05, 0xd3, 0x4d, 0xb1, 0x47, 0xc1, 0x7f, 0x66, 0x2e, 0x4f, 0x72, 0x9c,
+ 0x72, 0x77, 0x23, 0x6f, 0x94, 0x9f, 0x1c, 0x6b, 0x81, 0xe8, 0x26, 0x2c, 0x32, 0xea, 0xb3, 0xde,
+ 0xfa, 0x81, 0x4f, 0x59, 0x7c, 0x98, 0x90, 0x8f, 0xaa, 0x6f, 0x3c, 0x48, 0x80, 0x87, 0x79, 0xcc,
+ 0x7d, 0x98, 0xbd, 0x4d, 0xf6, 0x9d, 0xf0, 0xa1, 0x11, 0x43, 0xd9, 0x76, 0x9b, 0x4e, 0xd7, 0xa2,
+ 0x2a, 0xa1, 0x07, 0xd9, 0x2b, 0x08, 0xda, 0xad, 0x38, 0xf2, 0xb4, 0x5f, 0x3d, 0x97, 0x00, 0xa8,
+ 0x97, 0x35, 0x9c, 0x14, 0x61, 0x3a, 0x90, 0xfb, 0x1c, 0x3b, 0xc9, 0x6f, 0x43, 0x31, 0xaa, 0xf5,
+ 0x1f, 0xb3, 0x4a, 0xf3, 0x6d, 0x28, 0x08, 0x8f, 0x0f, 0x7a, 0xd4, 0x33, 0xaa, 0xa4, 0x64, 0xed,
+ 0x95, 0x49, 0x53, 0x7b, 0xc9, 0xe7, 0xea, 0x3b, 0x1d, 0xeb, 0x11, 0x9f, 0xab, 0x33, 0x8f, 0x72,
+ 0xf3, 0x65, 0x27, 0xbc, 0xf9, 0xae, 0x80, 0xfa, 0x4b, 0x8f, 0xb8, 0x64, 0x54, 0x01, 0x11, 0xbb,
+ 0x64, 0xe2, 0xf7, 0x7f, 0xec, 0x85, 0xe1, 0x47, 0x06, 0x80, 0x1c, 0xe5, 0xc9, 0x31, 0x52, 0x8a,
+ 0x3f, 0x46, 0xdc, 0x81, 0x69, 0x4f, 0x79, 0xa4, 0x7a, 0xb2, 0x9e, 0x70, 0x5e, 0x1c, 0x06, 0x92,
+ 0xf2, 0x49, 0xac, 0x85, 0xd5, 0x5f, 0xfd, 0xf8, 0xfe, 0xca, 0xd4, 0x27, 0xf7, 0x57, 0xa6, 0x3e,
+ 0xbd, 0xbf, 0x32, 0xf5, 0xde, 0xc9, 0x8a, 0xf1, 0xf1, 0xc9, 0x8a, 0xf1, 0xc9, 0xc9, 0x8a, 0xf1,
+ 0xe9, 0xc9, 0x8a, 0xf1, 0xd9, 0xc9, 0x8a, 0xf1, 0xc1, 0xdf, 0x56, 0xa6, 0xde, 0x7c, 0x2a, 0xcd,
+ 0x5f, 0x25, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xf8, 0xda, 0x63, 0x4c, 0x51, 0x29, 0x00, 0x00,
}
func (m *APIGroup) Marshal() (dAtA []byte, err error) {
@@ -1952,6 +1986,16 @@ func (m *DeleteOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if m.IgnoreStoreReadErrorWithClusterBreakingPotential != nil {
+ i--
+ if *m.IgnoreStoreReadErrorWithClusterBreakingPotential {
+ dAtA[i] = 1
+ } else {
+ dAtA[i] = 0
+ }
+ i--
+ dAtA[i] = 0x30
+ }
if len(m.DryRun) > 0 {
for iNdEx := len(m.DryRun) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.DryRun[iNdEx])
@@ -2024,6 +2068,48 @@ func (m *Duration) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
+func (m *FieldSelectorRequirement) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *FieldSelectorRequirement) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *FieldSelectorRequirement) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Values) > 0 {
+ for iNdEx := len(m.Values) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.Values[iNdEx])
+ copy(dAtA[i:], m.Values[iNdEx])
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Values[iNdEx])))
+ i--
+ dAtA[i] = 0x1a
+ }
+ }
+ i -= len(m.Operator)
+ copy(dAtA[i:], m.Operator)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Operator)))
+ i--
+ dAtA[i] = 0x12
+ i -= len(m.Key)
+ copy(dAtA[i:], m.Key)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Key)))
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
+}
+
func (m *FieldsV1) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -2503,6 +2589,16 @@ func (m *ListOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if m.SendInitialEvents != nil {
+ i--
+ if *m.SendInitialEvents {
+ dAtA[i] = 1
+ } else {
+ dAtA[i] = 0
+ }
+ i--
+ dAtA[i] = 0x58
+ }
i -= len(m.ResourceVersionMatch)
copy(dAtA[i:], m.ResourceVersionMatch)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceVersionMatch)))
@@ -3690,6 +3786,9 @@ func (m *DeleteOptions) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
}
}
+ if m.IgnoreStoreReadErrorWithClusterBreakingPotential != nil {
+ n += 2
+ }
return n
}
@@ -3703,6 +3802,25 @@ func (m *Duration) Size() (n int) {
return n
}
+func (m *FieldSelectorRequirement) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Key)
+ n += 1 + l + sovGenerated(uint64(l))
+ l = len(m.Operator)
+ n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Values) > 0 {
+ for _, s := range m.Values {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
+ return n
+}
+
func (m *FieldsV1) Size() (n int) {
if m == nil {
return 0
@@ -3908,6 +4026,9 @@ func (m *ListOptions) Size() (n int) {
n += 2
l = len(m.ResourceVersionMatch)
n += 1 + l + sovGenerated(uint64(l))
+ if m.SendInitialEvents != nil {
+ n += 2
+ }
return n
}
@@ -4401,6 +4522,7 @@ func (this *DeleteOptions) String() string {
`OrphanDependents:` + valueToStringGenerated(this.OrphanDependents) + `,`,
`PropagationPolicy:` + valueToStringGenerated(this.PropagationPolicy) + `,`,
`DryRun:` + fmt.Sprintf("%v", this.DryRun) + `,`,
+ `IgnoreStoreReadErrorWithClusterBreakingPotential:` + valueToStringGenerated(this.IgnoreStoreReadErrorWithClusterBreakingPotential) + `,`,
`}`,
}, "")
return s
@@ -4415,6 +4537,18 @@ func (this *Duration) String() string {
}, "")
return s
}
+func (this *FieldSelectorRequirement) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&FieldSelectorRequirement{`,
+ `Key:` + fmt.Sprintf("%v", this.Key) + `,`,
+ `Operator:` + fmt.Sprintf("%v", this.Operator) + `,`,
+ `Values:` + fmt.Sprintf("%v", this.Values) + `,`,
+ `}`,
+ }, "")
+ return s
+}
func (this *GetOptions) String() string {
if this == nil {
return "nil"
@@ -4517,6 +4651,7 @@ func (this *ListOptions) String() string {
`Continue:` + fmt.Sprintf("%v", this.Continue) + `,`,
`AllowWatchBookmarks:` + fmt.Sprintf("%v", this.AllowWatchBookmarks) + `,`,
`ResourceVersionMatch:` + fmt.Sprintf("%v", this.ResourceVersionMatch) + `,`,
+ `SendInitialEvents:` + valueToStringGenerated(this.SendInitialEvents) + `,`,
`}`,
}, "")
return s
@@ -6338,6 +6473,27 @@ func (m *DeleteOptions) Unmarshal(dAtA []byte) error {
}
m.DryRun = append(m.DryRun, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
+ case 6:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field IgnoreStoreReadErrorWithClusterBreakingPotential", wireType)
+ }
+ var v int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ v |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ b := bool(v != 0)
+ m.IgnoreStoreReadErrorWithClusterBreakingPotential = &b
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -6428,6 +6584,152 @@ func (m *Duration) Unmarshal(dAtA []byte) error {
}
return nil
}
+func (m *FieldSelectorRequirement) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: FieldSelectorRequirement: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: FieldSelectorRequirement: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Key = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Operator", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Operator = FieldSelectorOperator(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Values = append(m.Values, string(dAtA[iNdEx:postIndex]))
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenerated(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
func (m *FieldsV1) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@@ -8250,6 +8552,27 @@ func (m *ListOptions) Unmarshal(dAtA []byte) error {
}
m.ResourceVersionMatch = ResourceVersionMatch(dAtA[iNdEx:postIndex])
iNdEx = postIndex
+ case 11:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SendInitialEvents", wireType)
+ }
+ var v int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ v |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ b := bool(v != 0)
+ m.SendInitialEvents = &b
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto
index 2be188a6a..865d3e7ca 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto
@@ -34,6 +34,7 @@ message APIGroup {
optional string name = 1;
// versions are the versions supported in this group.
+ // +listType=atomic
repeated GroupVersionForDiscovery versions = 2;
// preferredVersion is the version preferred by the API server, which
@@ -49,6 +50,7 @@ message APIGroup {
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
// +optional
+ // +listType=atomic
repeated ServerAddressByClientCIDR serverAddressByClientCIDRs = 4;
}
@@ -56,6 +58,7 @@ message APIGroup {
// /apis.
message APIGroupList {
// groups is a list of APIGroup.
+ // +listType=atomic
repeated APIGroup groups = 1;
}
@@ -88,9 +91,11 @@ message APIResource {
optional Verbs verbs = 4;
// shortNames is a list of suggested short names of the resource.
+ // +listType=atomic
repeated string shortNames = 5;
// categories is a list of the grouped resources this resource belongs to (e.g. 'all')
+ // +listType=atomic
repeated string categories = 7;
// The hash value of the storage version, the version this resource is
@@ -112,6 +117,7 @@ message APIResourceList {
optional string groupVersion = 1;
// resources contains the name of the resources and if they are namespaced.
+ // +listType=atomic
repeated APIResource resources = 2;
}
@@ -122,6 +128,7 @@ message APIResourceList {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
message APIVersions {
// versions are the api versions that are available.
+ // +listType=atomic
repeated string versions = 1;
// a map of client CIDR to server address that is serving this group.
@@ -131,6 +138,7 @@ message APIVersions {
// The server returns only those CIDRs that it thinks that the client can match.
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
+ // +listType=atomic
repeated ServerAddressByClientCIDR serverAddressByClientCIDRs = 2;
}
@@ -145,6 +153,7 @@ message ApplyOptions {
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
+ // +listType=atomic
repeated string dryRun = 1;
// Force is going to "force" Apply requests. It means user will
@@ -235,6 +244,7 @@ message CreateOptions {
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
+ // +listType=atomic
repeated string dryRun = 1;
// fieldManager is a name associated with the actor or entity
@@ -246,19 +256,16 @@ message CreateOptions {
// fieldValidation instructs the server on how to handle
// objects in the request (POST/PUT/PATCH) containing unknown
- // or duplicate fields, provided that the `ServerSideFieldValidation`
- // feature gate is also enabled. Valid values are:
+ // or duplicate fields. Valid values are:
// - Ignore: This will ignore any unknown fields that are silently
// dropped from the object, and will ignore all but the last duplicate
// field that the decoder encounters. This is the default behavior
- // prior to v1.23 and is the default behavior when the
- // `ServerSideFieldValidation` feature gate is disabled.
+ // prior to v1.23.
// - Warn: This will send a warning via the standard warning response
// header for each unknown field that is dropped from the object, and
// for each duplicate field that is encountered. The request will
// still succeed if there are no other errors, and will only persist
- // the last of any duplicate fields. This is the default when the
- // `ServerSideFieldValidation` feature gate is enabled.
+ // the last of any duplicate fields. This is the default in v1.23+
// - Strict: This will fail the request with a BadRequest error if
// any unknown fields would be dropped from the object, or if any
// duplicate fields are present. The error returned from the server
@@ -306,7 +313,23 @@ message DeleteOptions {
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
+ // +listType=atomic
repeated string dryRun = 5;
+
+ // if set to true, it will trigger an unsafe deletion of the resource in
+ // case the normal deletion flow fails with a corrupt object error.
+ // A resource is considered corrupt if it can not be retrieved from
+ // the underlying storage successfully because of a) its data can
+ // not be transformed e.g. decryption failure, or b) it fails
+ // to decode into an object.
+ // NOTE: unsafe deletion ignores finalizer constraints, skips
+ // precondition checks, and removes the object from the storage.
+ // WARNING: This may potentially break the cluster if the workload
+ // associated with the resource being unsafe-deleted relies on normal
+ // deletion flow. Use only if you REALLY know what you are doing.
+ // The default value is false, and the user must opt in to enable it
+ // +optional
+ optional bool ignoreStoreReadErrorWithClusterBreakingPotential = 6;
}
// Duration is a wrapper around time.Duration which supports correct
@@ -316,6 +339,25 @@ message Duration {
optional int64 duration = 1;
}
+// FieldSelectorRequirement is a selector that contains values, a key, and an operator that
+// relates the key and values.
+message FieldSelectorRequirement {
+ // key is the field selector key that the requirement applies to.
+ optional string key = 1;
+
+ // operator represents a key's relationship to a set of values.
+ // Valid operators are In, NotIn, Exists, DoesNotExist.
+ // The list of operators may grow in the future.
+ optional string operator = 2;
+
+ // values is an array of string values.
+ // If the operator is In or NotIn, the values array must be non-empty.
+ // If the operator is Exists or DoesNotExist, the values array must be empty.
+ // +optional
+ // +listType=atomic
+ repeated string values = 3;
+}
+
// FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.
//
// Each key is either a '.' representing the field itself, and will always map to an empty set,
@@ -421,6 +463,7 @@ message LabelSelector {
// matchExpressions is a list of label selector requirements. The requirements are ANDed.
// +optional
+ // +listType=atomic
repeated LabelSelectorRequirement matchExpressions = 2;
}
@@ -428,8 +471,6 @@ message LabelSelector {
// relates the key and values.
message LabelSelectorRequirement {
// key is the label key that the selector applies to.
- // +patchMergeKey=key
- // +patchStrategy=merge
optional string key = 1;
// operator represents a key's relationship to a set of values.
@@ -441,6 +482,7 @@ message LabelSelectorRequirement {
// the values array must be empty. This array is replaced during a strategic
// merge patch.
// +optional
+ // +listType=atomic
repeated string values = 3;
}
@@ -452,7 +494,7 @@ message List {
optional ListMeta metadata = 1;
// List of objects
- repeated k8s.io.apimachinery.pkg.runtime.RawExtension items = 2;
+ repeated .k8s.io.apimachinery.pkg.runtime.RawExtension items = 2;
}
// ListMeta describes metadata that synthetic resources must have, including lists and
@@ -575,6 +617,32 @@ message ListOptions {
// This field is not supported when watch is true. Clients may start a watch from the last
// resourceVersion value returned by the server and not miss any modifications.
optional string continue = 8;
+
+ // `sendInitialEvents=true` may be set together with `watch=true`.
+ // In that case, the watch stream will begin with synthetic events to
+ // produce the current state of objects in the collection. Once all such
+ // events have been sent, a synthetic "Bookmark" event will be sent.
+ // The bookmark will report the ResourceVersion (RV) corresponding to the
+ // set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation.
+ // Afterwards, the watch stream will proceed as usual, sending watch events
+ // corresponding to changes (subsequent to the RV) to objects watched.
+ //
+ // When `sendInitialEvents` option is set, we require `resourceVersionMatch`
+ // option to also be set. The semantic of the watch request is as following:
+ // - `resourceVersionMatch` = NotOlderThan
+ // is interpreted as "data at least as new as the provided `resourceVersion`"
+ // and the bookmark event is send when the state is synced
+ // to a `resourceVersion` at least as fresh as the one provided by the ListOptions.
+ // If `resourceVersion` is unset, this is interpreted as "consistent read" and the
+ // bookmark event is send when the state is synced at least to the moment
+ // when request started being processed.
+ // - `resourceVersionMatch` set to any other value or unset
+ // Invalid error is returned.
+ //
+ // Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward
+ // compatibility reasons) and to false otherwise.
+ // +optional
+ optional bool sendInitialEvents = 11;
}
// ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource
@@ -645,7 +713,7 @@ message ObjectMeta {
// automatically. Name is primarily intended for creation idempotence and configuration
// definition.
// Cannot be updated.
- // More info: http://kubernetes.io/docs/user-guide/identifiers#names
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names
// +optional
optional string name = 1;
@@ -671,7 +739,7 @@ message ObjectMeta {
//
// Must be a DNS_LABEL.
// Cannot be updated.
- // More info: http://kubernetes.io/docs/user-guide/namespaces
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces
// +optional
optional string namespace = 3;
@@ -685,7 +753,7 @@ message ObjectMeta {
//
// Populated by the system.
// Read-only.
- // More info: http://kubernetes.io/docs/user-guide/identifiers#uids
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids
// +optional
optional string uid = 5;
@@ -749,14 +817,14 @@ message ObjectMeta {
// Map of string keys and values that can be used to organize and categorize
// (scope and select) objects. May match selectors of replication controllers
// and services.
- // More info: http://kubernetes.io/docs/user-guide/labels
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
// +optional
map labels = 11;
// Annotations is an unstructured key value map stored with a resource that may be
// set by external tools to store and retrieve arbitrary metadata. They are not
// queryable and should be preserved when modifying objects.
- // More info: http://kubernetes.io/docs/user-guide/annotations
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations
// +optional
map annotations = 12;
@@ -767,6 +835,8 @@ message ObjectMeta {
// +optional
// +patchMergeKey=uid
// +patchStrategy=merge
+ // +listType=map
+ // +listMapKey=uid
repeated OwnerReference ownerReferences = 13;
// Must be empty before the object is deleted from the registry. Each entry
@@ -784,6 +854,7 @@ message ObjectMeta {
// are not vulnerable to ordering changes in the list.
// +optional
// +patchStrategy=merge
+ // +listType=set
repeated string finalizers = 14;
// ManagedFields maps workflow-id and version to the set of fields
@@ -795,6 +866,7 @@ message ObjectMeta {
// workflow used when modifying the object.
//
// +optional
+ // +listType=atomic
repeated ManagedFieldsEntry managedFields = 17;
}
@@ -811,11 +883,11 @@ message OwnerReference {
optional string kind = 1;
// Name of the referent.
- // More info: http://kubernetes.io/docs/user-guide/identifiers#names
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names
optional string name = 3;
// UID of the referent.
- // More info: http://kubernetes.io/docs/user-guide/identifiers#uids
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids
optional string uid = 4;
// If true, this reference points to the managing controller.
@@ -869,6 +941,7 @@ message PatchOptions {
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
+ // +listType=atomic
repeated string dryRun = 1;
// Force is going to "force" Apply requests. It means user will
@@ -889,19 +962,16 @@ message PatchOptions {
// fieldValidation instructs the server on how to handle
// objects in the request (POST/PUT/PATCH) containing unknown
- // or duplicate fields, provided that the `ServerSideFieldValidation`
- // feature gate is also enabled. Valid values are:
+ // or duplicate fields. Valid values are:
// - Ignore: This will ignore any unknown fields that are silently
// dropped from the object, and will ignore all but the last duplicate
// field that the decoder encounters. This is the default behavior
- // prior to v1.23 and is the default behavior when the
- // `ServerSideFieldValidation` feature gate is disabled.
+ // prior to v1.23.
// - Warn: This will send a warning via the standard warning response
// header for each unknown field that is dropped from the object, and
// for each duplicate field that is encountered. The request will
// still succeed if there are no other errors, and will only persist
- // the last of any duplicate fields. This is the default when the
- // `ServerSideFieldValidation` feature gate is enabled.
+ // the last of any duplicate fields. This is the default in v1.23+
// - Strict: This will fail the request with a BadRequest error if
// any unknown fields would be dropped from the object, or if any
// duplicate fields are present. The error returned from the server
@@ -925,6 +995,7 @@ message Preconditions {
// For example: "/healthz", "/apis".
message RootPaths {
// paths are the paths available at root.
+ // +listType=atomic
repeated string paths = 1;
}
@@ -967,6 +1038,7 @@ message Status {
// is not guaranteed to conform to any schema except that defined by
// the reason type.
// +optional
+ // +listType=atomic
optional StatusDetails details = 5;
// Suggested HTTP return code for this status, 0 if not set.
@@ -1024,13 +1096,14 @@ message StatusDetails {
// UID of the resource.
// (when there is a single resource which can be described).
- // More info: http://kubernetes.io/docs/user-guide/identifiers#uids
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids
// +optional
optional string uid = 6;
// The Causes array includes more details associated with the StatusReason
// failure. Not all StatusReasons may provide detailed causes.
// +optional
+ // +listType=atomic
repeated StatusCause causes = 4;
// If specified, the time in seconds before the operation should be retried. Some errors may indicate
@@ -1117,6 +1190,7 @@ message UpdateOptions {
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
+ // +listType=atomic
repeated string dryRun = 1;
// fieldManager is a name associated with the actor or entity
@@ -1128,19 +1202,16 @@ message UpdateOptions {
// fieldValidation instructs the server on how to handle
// objects in the request (POST/PUT/PATCH) containing unknown
- // or duplicate fields, provided that the `ServerSideFieldValidation`
- // feature gate is also enabled. Valid values are:
+ // or duplicate fields. Valid values are:
// - Ignore: This will ignore any unknown fields that are silently
// dropped from the object, and will ignore all but the last duplicate
// field that the decoder encounters. This is the default behavior
- // prior to v1.23 and is the default behavior when the
- // `ServerSideFieldValidation` feature gate is disabled.
+ // prior to v1.23.
// - Warn: This will send a warning via the standard warning response
// header for each unknown field that is dropped from the object, and
// for each duplicate field that is encountered. The request will
// still succeed if there are no other errors, and will only persist
- // the last of any duplicate fields. This is the default when the
- // `ServerSideFieldValidation` feature gate is enabled.
+ // the last of any duplicate fields. This is the default in v1.23+
// - Strict: This will fail the request with a BadRequest error if
// any unknown fields would be dropped from the object, or if any
// duplicate fields are present. The error returned from the server
@@ -1172,6 +1243,6 @@ message WatchEvent {
// * If Type is Deleted: the state of the object immediately before deletion.
// * If Type is Error: *Status is recommended; other types may make sense
// depending on context.
- optional k8s.io.apimachinery.pkg.runtime.RawExtension object = 2;
+ optional .k8s.io.apimachinery.pkg.runtime.RawExtension object = 2;
}
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go
index 592dcb8a7..c748071ed 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go
@@ -24,8 +24,10 @@ import (
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
+ cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/types"
+ utiljson "k8s.io/apimachinery/pkg/util/json"
)
// LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements
@@ -280,13 +282,20 @@ func (f FieldsV1) MarshalJSON() ([]byte, error) {
if f.Raw == nil {
return []byte("null"), nil
}
+ if f.getContentType() == fieldsV1InvalidOrValidCBORObject {
+ var u map[string]interface{}
+ if err := cbor.Unmarshal(f.Raw, &u); err != nil {
+ return nil, fmt.Errorf("metav1.FieldsV1 cbor invalid: %w", err)
+ }
+ return utiljson.Marshal(u)
+ }
return f.Raw, nil
}
// UnmarshalJSON implements json.Unmarshaler
func (f *FieldsV1) UnmarshalJSON(b []byte) error {
if f == nil {
- return errors.New("metav1.Fields: UnmarshalJSON on nil pointer")
+ return errors.New("metav1.FieldsV1: UnmarshalJSON on nil pointer")
}
if !bytes.Equal(b, []byte("null")) {
f.Raw = append(f.Raw[0:0], b...)
@@ -296,3 +305,75 @@ func (f *FieldsV1) UnmarshalJSON(b []byte) error {
var _ json.Marshaler = FieldsV1{}
var _ json.Unmarshaler = &FieldsV1{}
+
+func (f FieldsV1) MarshalCBOR() ([]byte, error) {
+ if f.Raw == nil {
+ return cbor.Marshal(nil)
+ }
+ if f.getContentType() == fieldsV1InvalidOrValidJSONObject {
+ var u map[string]interface{}
+ if err := utiljson.Unmarshal(f.Raw, &u); err != nil {
+ return nil, fmt.Errorf("metav1.FieldsV1 json invalid: %w", err)
+ }
+ return cbor.Marshal(u)
+ }
+ return f.Raw, nil
+}
+
+var cborNull = []byte{0xf6}
+
+func (f *FieldsV1) UnmarshalCBOR(b []byte) error {
+ if f == nil {
+ return errors.New("metav1.FieldsV1: UnmarshalCBOR on nil pointer")
+ }
+ if !bytes.Equal(b, cborNull) {
+ f.Raw = append(f.Raw[0:0], b...)
+ }
+ return nil
+}
+
+const (
+ // fieldsV1InvalidOrEmpty indicates that a FieldsV1 either contains no raw bytes or its raw
+ // bytes don't represent an allowable value in any supported encoding.
+ fieldsV1InvalidOrEmpty = iota
+
+ // fieldsV1InvalidOrValidJSONObject indicates that a FieldV1 either contains raw bytes that
+ // are a valid JSON encoding of an allowable value or don't represent an allowable value in
+ // any supported encoding.
+ fieldsV1InvalidOrValidJSONObject
+
+ // fieldsV1InvalidOrValidCBORObject indicates that a FieldV1 either contains raw bytes that
+ // are a valid CBOR encoding of an allowable value or don't represent an allowable value in
+ // any supported encoding.
+ fieldsV1InvalidOrValidCBORObject
+)
+
+// getContentType returns one of fieldsV1InvalidOrEmpty, fieldsV1InvalidOrValidJSONObject,
+// fieldsV1InvalidOrValidCBORObject based on the value of Raw.
+//
+// Raw can be encoded in JSON or CBOR and is only valid if it is empty, null, or an object (map)
+// value. It is invalid if it contains a JSON string, number, boolean, or array. If Raw is nonempty
+// and represents an allowable value, then the initial byte unambiguously distinguishes a
+// JSON-encoded value from a CBOR-encoded value.
+//
+// A valid JSON-encoded value can begin with any of the four JSON whitespace characters, the first
+// character 'n' of null, or '{' (0x09, 0x0a, 0x0d, 0x20, 0x6e, or 0x7b, respectively). A valid
+// CBOR-encoded value can begin with the null simple value, an initial byte with major type "map",
+// or, if a tag-enclosed map, an initial byte with major type "tag" (0xf6, 0xa0...0xbf, or
+// 0xc6...0xdb). The two sets of valid initial bytes don't intersect.
+func (f FieldsV1) getContentType() int {
+ if len(f.Raw) > 0 {
+ p := f.Raw[0]
+ switch p {
+ case 'n', '{', '\t', '\r', '\n', ' ':
+ return fieldsV1InvalidOrValidJSONObject
+ case 0xf6: // null
+ return fieldsV1InvalidOrValidCBORObject
+ default:
+ if p >= 0xa0 && p <= 0xbf /* map */ || p >= 0xc6 && p <= 0xdb /* tag */ {
+ return fieldsV1InvalidOrValidCBORObject
+ }
+ }
+ }
+ return fieldsV1InvalidOrEmpty
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time.go
index 8eb37f436..9f302b3f3 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time.go
@@ -19,6 +19,8 @@ package v1
import (
"encoding/json"
"time"
+
+ cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
)
const RFC3339Micro = "2006-01-02T15:04:05.000000Z07:00"
@@ -129,6 +131,25 @@ func (t *MicroTime) UnmarshalJSON(b []byte) error {
return nil
}
+func (t *MicroTime) UnmarshalCBOR(b []byte) error {
+ var s *string
+ if err := cbor.Unmarshal(b, &s); err != nil {
+ return err
+ }
+ if s == nil {
+ t.Time = time.Time{}
+ return nil
+ }
+
+ parsed, err := time.Parse(RFC3339Micro, *s)
+ if err != nil {
+ return err
+ }
+
+ t.Time = parsed.Local()
+ return nil
+}
+
// UnmarshalQueryParameter converts from a URL query parameter value to an object
func (t *MicroTime) UnmarshalQueryParameter(str string) error {
if len(str) == 0 {
@@ -160,6 +181,13 @@ func (t MicroTime) MarshalJSON() ([]byte, error) {
return json.Marshal(t.UTC().Format(RFC3339Micro))
}
+func (t MicroTime) MarshalCBOR() ([]byte, error) {
+ if t.IsZero() {
+ return cbor.Marshal(nil)
+ }
+ return cbor.Marshal(t.UTC().Format(RFC3339Micro))
+}
+
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time.go
index 421770d43..0333cfdb3 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time.go
@@ -19,6 +19,8 @@ package v1
import (
"encoding/json"
"time"
+
+ cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
)
// Time is a wrapper around time.Time which supports correct
@@ -116,6 +118,25 @@ func (t *Time) UnmarshalJSON(b []byte) error {
return nil
}
+func (t *Time) UnmarshalCBOR(b []byte) error {
+ var s *string
+ if err := cbor.Unmarshal(b, &s); err != nil {
+ return err
+ }
+ if s == nil {
+ t.Time = time.Time{}
+ return nil
+ }
+
+ parsed, err := time.Parse(time.RFC3339, *s)
+ if err != nil {
+ return err
+ }
+
+ t.Time = parsed.Local()
+ return nil
+}
+
// UnmarshalQueryParameter converts from a URL query parameter value to an object
func (t *Time) UnmarshalQueryParameter(str string) error {
if len(str) == 0 {
@@ -151,6 +172,14 @@ func (t Time) MarshalJSON() ([]byte, error) {
return buf, nil
}
+func (t Time) MarshalCBOR() ([]byte, error) {
+ if t.IsZero() {
+ return cbor.Marshal(nil)
+ }
+
+ return cbor.Marshal(t.UTC().Format(time.RFC3339))
+}
+
// ToUnstructured implements the value.UnstructuredConverter interface.
func (t Time) ToUnstructured() interface{} {
if t.IsZero() {
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go
index 152f99296..4cf3f4795 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go
@@ -114,7 +114,7 @@ type ObjectMeta struct {
// automatically. Name is primarily intended for creation idempotence and configuration
// definition.
// Cannot be updated.
- // More info: http://kubernetes.io/docs/user-guide/identifiers#names
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names
// +optional
Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"`
@@ -140,7 +140,7 @@ type ObjectMeta struct {
//
// Must be a DNS_LABEL.
// Cannot be updated.
- // More info: http://kubernetes.io/docs/user-guide/namespaces
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces
// +optional
Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"`
@@ -154,7 +154,7 @@ type ObjectMeta struct {
//
// Populated by the system.
// Read-only.
- // More info: http://kubernetes.io/docs/user-guide/identifiers#uids
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids
// +optional
UID types.UID `json:"uid,omitempty" protobuf:"bytes,5,opt,name=uid,casttype=k8s.io/kubernetes/pkg/types.UID"`
@@ -218,14 +218,14 @@ type ObjectMeta struct {
// Map of string keys and values that can be used to organize and categorize
// (scope and select) objects. May match selectors of replication controllers
// and services.
- // More info: http://kubernetes.io/docs/user-guide/labels
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
// +optional
Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"`
// Annotations is an unstructured key value map stored with a resource that may be
// set by external tools to store and retrieve arbitrary metadata. They are not
// queryable and should be preserved when modifying objects.
- // More info: http://kubernetes.io/docs/user-guide/annotations
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations
// +optional
Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"`
@@ -236,6 +236,8 @@ type ObjectMeta struct {
// +optional
// +patchMergeKey=uid
// +patchStrategy=merge
+ // +listType=map
+ // +listMapKey=uid
OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" patchStrategy:"merge" patchMergeKey:"uid" protobuf:"bytes,13,rep,name=ownerReferences"`
// Must be empty before the object is deleted from the registry. Each entry
@@ -253,6 +255,7 @@ type ObjectMeta struct {
// are not vulnerable to ordering changes in the list.
// +optional
// +patchStrategy=merge
+ // +listType=set
Finalizers []string `json:"finalizers,omitempty" patchStrategy:"merge" protobuf:"bytes,14,rep,name=finalizers"`
// Tombstone: ClusterName was a legacy field that was always cleared by
@@ -268,6 +271,7 @@ type ObjectMeta struct {
// workflow used when modifying the object.
//
// +optional
+ // +listType=atomic
ManagedFields []ManagedFieldsEntry `json:"managedFields,omitempty" protobuf:"bytes,17,rep,name=managedFields"`
}
@@ -295,10 +299,10 @@ type OwnerReference struct {
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"`
// Name of the referent.
- // More info: http://kubernetes.io/docs/user-guide/identifiers#names
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names
Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
// UID of the referent.
- // More info: http://kubernetes.io/docs/user-guide/identifiers#uids
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids
UID types.UID `json:"uid" protobuf:"bytes,4,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"`
// If true, this reference points to the managing controller.
// +optional
@@ -400,8 +404,57 @@ type ListOptions struct {
// This field is not supported when watch is true. Clients may start a watch from the last
// resourceVersion value returned by the server and not miss any modifications.
Continue string `json:"continue,omitempty" protobuf:"bytes,8,opt,name=continue"`
+
+ // `sendInitialEvents=true` may be set together with `watch=true`.
+ // In that case, the watch stream will begin with synthetic events to
+ // produce the current state of objects in the collection. Once all such
+ // events have been sent, a synthetic "Bookmark" event will be sent.
+ // The bookmark will report the ResourceVersion (RV) corresponding to the
+ // set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation.
+ // Afterwards, the watch stream will proceed as usual, sending watch events
+ // corresponding to changes (subsequent to the RV) to objects watched.
+ //
+ // When `sendInitialEvents` option is set, we require `resourceVersionMatch`
+ // option to also be set. The semantic of the watch request is as following:
+ // - `resourceVersionMatch` = NotOlderThan
+ // is interpreted as "data at least as new as the provided `resourceVersion`"
+ // and the bookmark event is send when the state is synced
+ // to a `resourceVersion` at least as fresh as the one provided by the ListOptions.
+ // If `resourceVersion` is unset, this is interpreted as "consistent read" and the
+ // bookmark event is send when the state is synced at least to the moment
+ // when request started being processed.
+ // - `resourceVersionMatch` set to any other value or unset
+ // Invalid error is returned.
+ //
+ // Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward
+ // compatibility reasons) and to false otherwise.
+ // +optional
+ SendInitialEvents *bool `json:"sendInitialEvents,omitempty" protobuf:"varint,11,opt,name=sendInitialEvents"`
}
+const (
+ // InitialEventsAnnotationKey the name of the key
+ // under which an annotation marking the end of
+ // a watchlist stream is stored.
+ //
+ // The annotation is added to a "Bookmark" event.
+ InitialEventsAnnotationKey = "k8s.io/initial-events-end"
+
+ // InitialEventsListBlueprintAnnotationKey is the name of the key
+ // where an empty, versioned list is encoded in the requested format
+ // (e.g., protobuf, JSON, CBOR), then base64-encoded and stored as a string.
+ //
+ // This encoding matches the request encoding format, which may be
+ // protobuf, JSON, CBOR, or others, depending on what the client requested.
+ // This ensures that the reconstructed list can be processed through the
+ // same decoder chain that would handle a standard LIST call response.
+ //
+ // The annotation is added to a "Bookmark" event and is used by clients
+ // to guarantee the format consistency when reconstructing
+ // the list during WatchList processing.
+ InitialEventsListBlueprintAnnotationKey = "kubernetes.io/initial-events-list-blueprint"
+)
+
// resourceVersionMatch specifies how the resourceVersion parameter is applied. resourceVersionMatch
// may only be set if resourceVersion is also set.
//
@@ -505,7 +558,23 @@ type DeleteOptions struct {
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
+ // +listType=atomic
DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,5,rep,name=dryRun"`
+
+ // if set to true, it will trigger an unsafe deletion of the resource in
+ // case the normal deletion flow fails with a corrupt object error.
+ // A resource is considered corrupt if it can not be retrieved from
+ // the underlying storage successfully because of a) its data can
+ // not be transformed e.g. decryption failure, or b) it fails
+ // to decode into an object.
+ // NOTE: unsafe deletion ignores finalizer constraints, skips
+ // precondition checks, and removes the object from the storage.
+ // WARNING: This may potentially break the cluster if the workload
+ // associated with the resource being unsafe-deleted relies on normal
+ // deletion flow. Use only if you REALLY know what you are doing.
+ // The default value is false, and the user must opt in to enable it
+ // +optional
+ IgnoreStoreReadErrorWithClusterBreakingPotential *bool `json:"ignoreStoreReadErrorWithClusterBreakingPotential,omitempty" protobuf:"varint,6,opt,name=ignoreStoreReadErrorWithClusterBreakingPotential"`
}
const (
@@ -530,6 +599,7 @@ type CreateOptions struct {
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
+ // +listType=atomic
DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,1,rep,name=dryRun"`
// +k8s:deprecated=includeUninitialized,protobuf=2
@@ -542,19 +612,16 @@ type CreateOptions struct {
// fieldValidation instructs the server on how to handle
// objects in the request (POST/PUT/PATCH) containing unknown
- // or duplicate fields, provided that the `ServerSideFieldValidation`
- // feature gate is also enabled. Valid values are:
+ // or duplicate fields. Valid values are:
// - Ignore: This will ignore any unknown fields that are silently
// dropped from the object, and will ignore all but the last duplicate
// field that the decoder encounters. This is the default behavior
- // prior to v1.23 and is the default behavior when the
- // `ServerSideFieldValidation` feature gate is disabled.
+ // prior to v1.23.
// - Warn: This will send a warning via the standard warning response
// header for each unknown field that is dropped from the object, and
// for each duplicate field that is encountered. The request will
// still succeed if there are no other errors, and will only persist
- // the last of any duplicate fields. This is the default when the
- // `ServerSideFieldValidation` feature gate is enabled.
+ // the last of any duplicate fields. This is the default in v1.23+
// - Strict: This will fail the request with a BadRequest error if
// any unknown fields would be dropped from the object, or if any
// duplicate fields are present. The error returned from the server
@@ -577,6 +644,7 @@ type PatchOptions struct {
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
+ // +listType=atomic
DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,1,rep,name=dryRun"`
// Force is going to "force" Apply requests. It means user will
@@ -597,19 +665,16 @@ type PatchOptions struct {
// fieldValidation instructs the server on how to handle
// objects in the request (POST/PUT/PATCH) containing unknown
- // or duplicate fields, provided that the `ServerSideFieldValidation`
- // feature gate is also enabled. Valid values are:
+ // or duplicate fields. Valid values are:
// - Ignore: This will ignore any unknown fields that are silently
// dropped from the object, and will ignore all but the last duplicate
// field that the decoder encounters. This is the default behavior
- // prior to v1.23 and is the default behavior when the
- // `ServerSideFieldValidation` feature gate is disabled.
+ // prior to v1.23.
// - Warn: This will send a warning via the standard warning response
// header for each unknown field that is dropped from the object, and
// for each duplicate field that is encountered. The request will
// still succeed if there are no other errors, and will only persist
- // the last of any duplicate fields. This is the default when the
- // `ServerSideFieldValidation` feature gate is enabled.
+ // the last of any duplicate fields. This is the default in v1.23+
// - Strict: This will fail the request with a BadRequest error if
// any unknown fields would be dropped from the object, or if any
// duplicate fields are present. The error returned from the server
@@ -631,6 +696,7 @@ type ApplyOptions struct {
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
+ // +listType=atomic
DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,1,rep,name=dryRun"`
// Force is going to "force" Apply requests. It means user will
@@ -663,6 +729,7 @@ type UpdateOptions struct {
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
+ // +listType=atomic
DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,1,rep,name=dryRun"`
// fieldManager is a name associated with the actor or entity
@@ -674,19 +741,16 @@ type UpdateOptions struct {
// fieldValidation instructs the server on how to handle
// objects in the request (POST/PUT/PATCH) containing unknown
- // or duplicate fields, provided that the `ServerSideFieldValidation`
- // feature gate is also enabled. Valid values are:
+ // or duplicate fields. Valid values are:
// - Ignore: This will ignore any unknown fields that are silently
// dropped from the object, and will ignore all but the last duplicate
// field that the decoder encounters. This is the default behavior
- // prior to v1.23 and is the default behavior when the
- // `ServerSideFieldValidation` feature gate is disabled.
+ // prior to v1.23.
// - Warn: This will send a warning via the standard warning response
// header for each unknown field that is dropped from the object, and
// for each duplicate field that is encountered. The request will
// still succeed if there are no other errors, and will only persist
- // the last of any duplicate fields. This is the default when the
- // `ServerSideFieldValidation` feature gate is enabled.
+ // the last of any duplicate fields. This is the default in v1.23+
// - Strict: This will fail the request with a BadRequest error if
// any unknown fields would be dropped from the object, or if any
// duplicate fields are present. The error returned from the server
@@ -734,6 +798,7 @@ type Status struct {
// is not guaranteed to conform to any schema except that defined by
// the reason type.
// +optional
+ // +listType=atomic
Details *StatusDetails `json:"details,omitempty" protobuf:"bytes,5,opt,name=details"`
// Suggested HTTP return code for this status, 0 if not set.
// +optional
@@ -761,12 +826,13 @@ type StatusDetails struct {
Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"`
// UID of the resource.
// (when there is a single resource which can be described).
- // More info: http://kubernetes.io/docs/user-guide/identifiers#uids
+ // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids
// +optional
UID types.UID `json:"uid,omitempty" protobuf:"bytes,6,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"`
// The Causes array includes more details associated with the StatusReason
// failure. Not all StatusReasons may provide detailed causes.
// +optional
+ // +listType=atomic
Causes []StatusCause `json:"causes,omitempty" protobuf:"bytes,4,rep,name=causes"`
// If specified, the time in seconds before the operation should be retried. Some errors may indicate
// the client must take an alternate action - for those errors this field may indicate how long to wait
@@ -865,6 +931,22 @@ const (
// Status code 500
StatusReasonServerTimeout StatusReason = "ServerTimeout"
+ // StatusReasonStoreReadError means that the server encountered an error while
+ // retrieving resources from the backend object store.
+ // This may be due to backend database error, or because processing of the read
+ // resource failed.
+ // Details:
+ // "kind" string - the kind attribute of the resource being acted on.
+ // "name" string - the prefix where the reading error(s) occurred
+ // "causes" []StatusCause
+ // - (optional):
+ // - "type" CauseType - CauseTypeUnexpectedServerResponse
+ // - "message" string - the error message from the store backend
+ // - "field" string - the full path with the key of the resource that failed reading
+ //
+ // Status code 500
+ StatusReasonStoreReadError StatusReason = "StorageReadError"
+
// StatusReasonTimeout means that the request could not be completed within the given time.
// Clients can get this response only when they specified a timeout param in the request,
// or if the server cannot complete the operation within a reasonable amount of time.
@@ -978,6 +1060,24 @@ const (
// CauseTypeFieldValueNotSupported is used to report valid (as per formatting rules)
// values that can not be handled (e.g. an enumerated string).
CauseTypeFieldValueNotSupported CauseType = "FieldValueNotSupported"
+ // CauseTypeForbidden is used to report valid (as per formatting rules)
+ // values which would be accepted under some conditions, but which are not
+ // permitted by the current conditions (such as security policy). See
+ // Forbidden().
+ CauseTypeForbidden CauseType = "FieldValueForbidden"
+ // CauseTypeTooLong is used to report that the given value is too long.
+ // This is similar to ErrorTypeInvalid, but the error will not include the
+ // too-long value. See TooLong().
+ CauseTypeTooLong CauseType = "FieldValueTooLong"
+ // CauseTypeTooMany is used to report "too many". This is used to
+ // report that a given list has too many items. This is similar to FieldValueTooLong,
+ // but the error indicates quantity instead of length.
+ CauseTypeTooMany CauseType = "FieldValueTooMany"
+ // CauseTypeInternal is used to report other errors that are not related
+ // to user input. See InternalError().
+ CauseTypeInternal CauseType = "InternalError"
+ // CauseTypeTypeInvalid is for the value did not match the schema type for that field
+ CauseTypeTypeInvalid CauseType = "FieldValueTypeInvalid"
// CauseTypeUnexpectedServerResponse is used to report when the server responded to the client
// without the expected return type. The presence of this cause indicates the error may be
// due to an intervening proxy or the server software malfunctioning.
@@ -1012,6 +1112,7 @@ type List struct {
type APIVersions struct {
TypeMeta `json:",inline"`
// versions are the api versions that are available.
+ // +listType=atomic
Versions []string `json:"versions" protobuf:"bytes,1,rep,name=versions"`
// a map of client CIDR to server address that is serving this group.
// This is to help clients reach servers in the most network-efficient way possible.
@@ -1020,6 +1121,7 @@ type APIVersions struct {
// The server returns only those CIDRs that it thinks that the client can match.
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
+ // +listType=atomic
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs" protobuf:"bytes,2,rep,name=serverAddressByClientCIDRs"`
}
@@ -1030,6 +1132,7 @@ type APIVersions struct {
type APIGroupList struct {
TypeMeta `json:",inline"`
// groups is a list of APIGroup.
+ // +listType=atomic
Groups []APIGroup `json:"groups" protobuf:"bytes,1,rep,name=groups"`
}
@@ -1042,6 +1145,7 @@ type APIGroup struct {
// name is the name of the group.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// versions are the versions supported in this group.
+ // +listType=atomic
Versions []GroupVersionForDiscovery `json:"versions" protobuf:"bytes,2,rep,name=versions"`
// preferredVersion is the version preferred by the API server, which
// probably is the storage version.
@@ -1055,6 +1159,7 @@ type APIGroup struct {
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
// +optional
+ // +listType=atomic
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs,omitempty" protobuf:"bytes,4,rep,name=serverAddressByClientCIDRs"`
}
@@ -1099,8 +1204,10 @@ type APIResource struct {
// update, patch, delete, deletecollection, and proxy)
Verbs Verbs `json:"verbs" protobuf:"bytes,4,opt,name=verbs"`
// shortNames is a list of suggested short names of the resource.
+ // +listType=atomic
ShortNames []string `json:"shortNames,omitempty" protobuf:"bytes,5,rep,name=shortNames"`
// categories is a list of the grouped resources this resource belongs to (e.g. 'all')
+ // +listType=atomic
Categories []string `json:"categories,omitempty" protobuf:"bytes,7,rep,name=categories"`
// The hash value of the storage version, the version this resource is
// converted to when written to the data store. Value must be treated
@@ -1133,6 +1240,7 @@ type APIResourceList struct {
// groupVersion is the group and version this APIResourceList is for.
GroupVersion string `json:"groupVersion" protobuf:"bytes,1,opt,name=groupVersion"`
// resources contains the name of the resources and if they are namespaced.
+ // +listType=atomic
APIResources []APIResource `json:"resources" protobuf:"bytes,2,rep,name=resources"`
}
@@ -1140,6 +1248,7 @@ type APIResourceList struct {
// For example: "/healthz", "/apis".
type RootPaths struct {
// paths are the paths available at root.
+ // +listType=atomic
Paths []string `json:"paths" protobuf:"bytes,1,rep,name=paths"`
}
@@ -1183,6 +1292,7 @@ type LabelSelector struct {
MatchLabels map[string]string `json:"matchLabels,omitempty" protobuf:"bytes,1,rep,name=matchLabels"`
// matchExpressions is a list of label selector requirements. The requirements are ANDed.
// +optional
+ // +listType=atomic
MatchExpressions []LabelSelectorRequirement `json:"matchExpressions,omitempty" protobuf:"bytes,2,rep,name=matchExpressions"`
}
@@ -1190,9 +1300,7 @@ type LabelSelector struct {
// relates the key and values.
type LabelSelectorRequirement struct {
// key is the label key that the selector applies to.
- // +patchMergeKey=key
- // +patchStrategy=merge
- Key string `json:"key" patchStrategy:"merge" patchMergeKey:"key" protobuf:"bytes,1,opt,name=key"`
+ Key string `json:"key" protobuf:"bytes,1,opt,name=key"`
// operator represents a key's relationship to a set of values.
// Valid operators are In, NotIn, Exists and DoesNotExist.
Operator LabelSelectorOperator `json:"operator" protobuf:"bytes,2,opt,name=operator,casttype=LabelSelectorOperator"`
@@ -1201,6 +1309,7 @@ type LabelSelectorRequirement struct {
// the values array must be empty. This array is replaced during a strategic
// merge patch.
// +optional
+ // +listType=atomic
Values []string `json:"values,omitempty" protobuf:"bytes,3,rep,name=values"`
}
@@ -1214,6 +1323,33 @@ const (
LabelSelectorOpDoesNotExist LabelSelectorOperator = "DoesNotExist"
)
+// FieldSelectorRequirement is a selector that contains values, a key, and an operator that
+// relates the key and values.
+type FieldSelectorRequirement struct {
+ // key is the field selector key that the requirement applies to.
+ Key string `json:"key" protobuf:"bytes,1,opt,name=key"`
+ // operator represents a key's relationship to a set of values.
+ // Valid operators are In, NotIn, Exists, DoesNotExist.
+ // The list of operators may grow in the future.
+ Operator FieldSelectorOperator `json:"operator" protobuf:"bytes,2,opt,name=operator,casttype=FieldSelectorOperator"`
+ // values is an array of string values.
+ // If the operator is In or NotIn, the values array must be non-empty.
+ // If the operator is Exists or DoesNotExist, the values array must be empty.
+ // +optional
+ // +listType=atomic
+ Values []string `json:"values,omitempty" protobuf:"bytes,3,rep,name=values"`
+}
+
+// A field selector operator is the set of operators that can be used in a selector requirement.
+type FieldSelectorOperator string
+
+const (
+ FieldSelectorOpIn FieldSelectorOperator = "In"
+ FieldSelectorOpNotIn FieldSelectorOperator = "NotIn"
+ FieldSelectorOpExists FieldSelectorOperator = "Exists"
+ FieldSelectorOpDoesNotExist FieldSelectorOperator = "DoesNotExist"
+)
+
// ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource
// that the fieldset applies to.
type ManagedFieldsEntry struct {
@@ -1302,8 +1438,10 @@ type Table struct {
// columnDefinitions describes each column in the returned items array. The number of cells per row
// will always match the number of column definitions.
+ // +listType=atomic
ColumnDefinitions []TableColumnDefinition `json:"columnDefinitions"`
// rows is the list of items in the table.
+ // +listType=atomic
Rows []TableRow `json:"rows"`
}
@@ -1336,12 +1474,14 @@ type TableRow struct {
// cells will be as wide as the column definitions array and may contain strings, numbers (float64 or
// int64), booleans, simple maps, lists, or null. See the type field of the column definition for a
// more detailed description.
+ // +listType=atomic
Cells []interface{} `json:"cells"`
// conditions describe additional status of a row that are relevant for a human user. These conditions
// apply to the row, not to the object, and will be specific to table output. The only defined
// condition type is 'Completed', for a row that indicates a resource that has run to completion and
// can be given less visual priority.
// +optional
+ // +listType=atomic
Conditions []TableRowCondition `json:"conditions,omitempty"`
// This field contains the requested additional information about each object based on the includeObject
// policy when requesting the Table. If "None", this field is empty, if "Object" this will be the
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go
index 9570726a0..405496d3d 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go
@@ -24,7 +24,7 @@ package v1
// they are on one line! For multiple line or blocks that you want to ignore use ---.
// Any context after a --- is ignored.
//
-// Those methods can be generated by using hack/update-generated-swagger-docs.sh
+// Those methods can be generated by using hack/update-codegen.sh
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
var map_APIGroup = map[string]string{
@@ -115,7 +115,7 @@ var map_CreateOptions = map[string]string{
"": "CreateOptions may be provided when creating an API object.",
"dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
"fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.",
- "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.",
+ "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.",
}
func (CreateOptions) SwaggerDoc() map[string]string {
@@ -129,12 +129,24 @@ var map_DeleteOptions = map[string]string{
"orphanDependents": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.",
"propagationPolicy": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.",
"dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
+ "ignoreStoreReadErrorWithClusterBreakingPotential": "if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it",
}
func (DeleteOptions) SwaggerDoc() map[string]string {
return map_DeleteOptions
}
+var map_FieldSelectorRequirement = map[string]string{
+ "": "FieldSelectorRequirement is a selector that contains values, a key, and an operator that relates the key and values.",
+ "key": "key is the field selector key that the requirement applies to.",
+ "operator": "operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. The list of operators may grow in the future.",
+ "values": "values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty.",
+}
+
+func (FieldSelectorRequirement) SwaggerDoc() map[string]string {
+ return map_FieldSelectorRequirement
+}
+
var map_FieldsV1 = map[string]string{
"": "FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:', where is the name of a field in a struct, or key in a map 'v:', where is the exact json formatted value of a list item 'i:', where is position of a item in a list 'k:', where is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in sigs.k8s.io/structured-merge-diff",
}
@@ -216,6 +228,7 @@ var map_ListOptions = map[string]string{
"timeoutSeconds": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.",
"limit": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.",
"continue": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.",
+ "sendInitialEvents": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.",
}
func (ListOptions) SwaggerDoc() map[string]string {
@@ -239,18 +252,18 @@ func (ManagedFieldsEntry) SwaggerDoc() map[string]string {
var map_ObjectMeta = map[string]string{
"": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.",
- "name": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
+ "name": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names",
"generateName": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will return a 409.\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency",
- "namespace": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces",
+ "namespace": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces",
"selfLink": "Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.",
- "uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids",
+ "uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids",
"resourceVersion": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency",
"generation": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.",
"creationTimestamp": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
"deletionTimestamp": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
"deletionGracePeriodSeconds": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.",
- "labels": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels",
- "annotations": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations",
+ "labels": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels",
+ "annotations": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations",
"ownerReferences": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.",
"finalizers": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.",
"managedFields": "ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like \"ci-cd\". The set of fields is always in the version that the workflow used when modifying the object.",
@@ -264,8 +277,8 @@ var map_OwnerReference = map[string]string{
"": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.",
"apiVersion": "API version of the referent.",
"kind": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
- "name": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
- "uid": "UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids",
+ "name": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names",
+ "uid": "UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids",
"controller": "If true, this reference points to the managing controller.",
"blockOwnerDeletion": "If true, AND if the owner has the \"foregroundDeletion\" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs \"delete\" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.",
}
@@ -306,7 +319,7 @@ var map_PatchOptions = map[string]string{
"dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
"force": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.",
"fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).",
- "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.",
+ "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.",
}
func (PatchOptions) SwaggerDoc() map[string]string {
@@ -372,7 +385,7 @@ var map_StatusDetails = map[string]string{
"name": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).",
"group": "The group attribute of the resource associated with the status StatusReason.",
"kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
- "uid": "UID of the resource. (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids",
+ "uid": "UID of the resource. (when there is a single resource which can be described). More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids",
"causes": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.",
"retryAfterSeconds": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.",
}
@@ -451,7 +464,7 @@ var map_UpdateOptions = map[string]string{
"": "UpdateOptions may be provided when updating an API object. All fields in UpdateOptions should also be present in PatchOptions.",
"dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
"fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.",
- "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.",
+ "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.",
}
func (UpdateOptions) SwaggerDoc() map[string]string {
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go
index 2e33283ef..71f7b163a 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go
@@ -20,6 +20,7 @@ import (
gojson "encoding/json"
"fmt"
"io"
+ "math/big"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -125,6 +126,29 @@ func NestedInt64(obj map[string]interface{}, fields ...string) (int64, bool, err
return i, true, nil
}
+// NestedNumberAsFloat64 returns the float64 value of a nested field. If the field's value is a
+// float64, it is returned. If the field's value is an int64 that can be losslessly converted to
+// float64, it will be converted and returned. Returns false if value is not found and an error if
+// not a float64 or an int64 that can be accurately represented as a float64.
+func NestedNumberAsFloat64(obj map[string]interface{}, fields ...string) (float64, bool, error) {
+ val, found, err := NestedFieldNoCopy(obj, fields...)
+ if !found || err != nil {
+ return 0, found, err
+ }
+ switch x := val.(type) {
+ case int64:
+ f, accuracy := big.NewInt(x).Float64()
+ if accuracy != big.Exact {
+ return 0, false, fmt.Errorf("%v accessor error: int64 value %v cannot be losslessly converted to float64", jsonPath(fields), x)
+ }
+ return f, true, nil
+ case float64:
+ return x, true, nil
+ default:
+ return 0, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected float64 or int64", jsonPath(fields), val, val)
+ }
+}
+
// NestedStringSlice returns a copy of []string value of a nested field.
// Returns false if value is not found and an error if not a []interface{} or contains non-string items in the slice.
func NestedStringSlice(obj map[string]interface{}, fields ...string) ([]string, bool, error) {
@@ -173,7 +197,7 @@ func NestedStringMap(obj map[string]interface{}, fields ...string) (map[string]s
if str, ok := v.(string); ok {
strMap[k] = str
} else {
- return nil, false, fmt.Errorf("%v accessor error: contains non-string key in the map: %v is of the type %T, expected string", jsonPath(fields), v, v)
+ return nil, false, fmt.Errorf("%v accessor error: contains non-string value in the map under key %q: %v is of the type %T, expected string", jsonPath(fields), k, v, v)
}
}
return strMap, true, nil
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go
index a499eee8e..5e36a91ee 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go
@@ -101,6 +101,11 @@ func (obj *Unstructured) EachListItem(fn func(runtime.Object) error) error {
return nil
}
+func (obj *Unstructured) EachListItemWithAlloc(fn func(runtime.Object) error) error {
+ // EachListItem has allocated a new Object for the user, we can use it directly.
+ return obj.EachListItem(fn)
+}
+
func (obj *Unstructured) UnstructuredContent() map[string]interface{} {
if obj.Object == nil {
return make(map[string]interface{})
@@ -445,10 +450,14 @@ func (u *Unstructured) SetFinalizers(finalizers []string) {
}
func (u *Unstructured) GetManagedFields() []metav1.ManagedFieldsEntry {
- items, found, err := NestedSlice(u.Object, "metadata", "managedFields")
+ v, found, err := NestedFieldNoCopy(u.Object, "metadata", "managedFields")
if !found || err != nil {
return nil
}
+ items, ok := v.([]interface{})
+ if !ok {
+ return nil
+ }
managedFields := []metav1.ManagedFieldsEntry{}
for _, item := range items {
m, ok := item.(map[string]interface{})
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list.go
index 5028f5fb5..82beda2a2 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list.go
@@ -52,6 +52,15 @@ func (u *UnstructuredList) EachListItem(fn func(runtime.Object) error) error {
return nil
}
+func (u *UnstructuredList) EachListItemWithAlloc(fn func(runtime.Object) error) error {
+ for i := range u.Items {
+ if err := fn(&Unstructured{Object: u.Items[i].Object}); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
// NewEmptyInstance returns a new instance of the concrete type containing only kind/apiVersion and no other data.
// This should be called instead of reflect.New() for unstructured types because the go type alone does not preserve kind/apiVersion info.
func (u *UnstructuredList) NewEmptyInstance() runtime.Unstructured {
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go
new file mode 100644
index 000000000..b1eb1bbfc
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go
@@ -0,0 +1,391 @@
+/*
+Copyright 2015 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 validation
+
+import (
+ "fmt"
+ "regexp"
+ "unicode"
+
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/types"
+ "k8s.io/apimachinery/pkg/util/sets"
+ "k8s.io/apimachinery/pkg/util/validation"
+ "k8s.io/apimachinery/pkg/util/validation/field"
+
+ "k8s.io/utils/ptr"
+)
+
+// LabelSelectorValidationOptions is a struct that can be passed to ValidateLabelSelector to record the validate options
+type LabelSelectorValidationOptions struct {
+ // Allow invalid label value in selector
+ AllowInvalidLabelValueInSelector bool
+
+ // Allows an operator that is not interpretable to pass validation. This is useful for cases where a broader check
+ // can be performed, as in a *SubjectAccessReview
+ AllowUnknownOperatorInRequirement bool
+}
+
+// LabelSelectorHasInvalidLabelValue returns true if the given selector contains an invalid label value in a match expression.
+// This is useful for determining whether AllowInvalidLabelValueInSelector should be set to true when validating an update
+// based on existing persisted invalid values.
+func LabelSelectorHasInvalidLabelValue(ps *metav1.LabelSelector) bool {
+ if ps == nil {
+ return false
+ }
+ for _, e := range ps.MatchExpressions {
+ for _, v := range e.Values {
+ if len(validation.IsValidLabelValue(v)) > 0 {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// ValidateLabelSelector validate the LabelSelector according to the opts and returns any validation errors.
+// opts.AllowInvalidLabelValueInSelector is only expected to be set to true when required for backwards compatibility with existing invalid data.
+func ValidateLabelSelector(ps *metav1.LabelSelector, opts LabelSelectorValidationOptions, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ if ps == nil {
+ return allErrs
+ }
+ allErrs = append(allErrs, ValidateLabels(ps.MatchLabels, fldPath.Child("matchLabels"))...)
+ for i, expr := range ps.MatchExpressions {
+ allErrs = append(allErrs, ValidateLabelSelectorRequirement(expr, opts, fldPath.Child("matchExpressions").Index(i))...)
+ }
+ return allErrs
+}
+
+// ValidateLabelSelectorRequirement validate the requirement according to the opts and returns any validation errors.
+// opts.AllowInvalidLabelValueInSelector is only expected to be set to true when required for backwards compatibility with existing invalid data.
+func ValidateLabelSelectorRequirement(sr metav1.LabelSelectorRequirement, opts LabelSelectorValidationOptions, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ switch sr.Operator {
+ case metav1.LabelSelectorOpIn, metav1.LabelSelectorOpNotIn:
+ if len(sr.Values) == 0 {
+ allErrs = append(allErrs, field.Required(fldPath.Child("values"), "must be specified when `operator` is 'In' or 'NotIn'"))
+ }
+ case metav1.LabelSelectorOpExists, metav1.LabelSelectorOpDoesNotExist:
+ if len(sr.Values) > 0 {
+ allErrs = append(allErrs, field.Forbidden(fldPath.Child("values"), "may not be specified when `operator` is 'Exists' or 'DoesNotExist'"))
+ }
+ default:
+ if !opts.AllowUnknownOperatorInRequirement {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("operator"), sr.Operator, "not a valid selector operator"))
+ }
+ }
+ allErrs = append(allErrs, ValidateLabelName(sr.Key, fldPath.Child("key"))...)
+ if !opts.AllowInvalidLabelValueInSelector {
+ for valueIndex, value := range sr.Values {
+ for _, msg := range validation.IsValidLabelValue(value) {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("values").Index(valueIndex), value, msg))
+ }
+ }
+ }
+ return allErrs
+}
+
+// ValidateLabelName validates that the label name is correctly defined.
+func ValidateLabelName(labelName string, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ for _, msg := range validation.IsQualifiedName(labelName) {
+ allErrs = append(allErrs, field.Invalid(fldPath, labelName, msg))
+ }
+ return allErrs
+}
+
+// ValidateLabels validates that a set of labels are correctly defined.
+func ValidateLabels(labels map[string]string, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ for k, v := range labels {
+ allErrs = append(allErrs, ValidateLabelName(k, fldPath)...)
+ for _, msg := range validation.IsValidLabelValue(v) {
+ allErrs = append(allErrs, field.Invalid(fldPath, v, msg))
+ }
+ }
+ return allErrs
+}
+
+// FieldSelectorValidationOptions is a struct that can be passed to ValidateFieldSelectorRequirement to record the validate options
+type FieldSelectorValidationOptions struct {
+ // Allows an operator that is not interpretable to pass validation. This is useful for cases where a broader check
+ // can be performed, as in a *SubjectAccessReview
+ AllowUnknownOperatorInRequirement bool
+}
+
+// ValidateLabelSelectorRequirement validates the requirement according to the opts and returns any validation errors.
+func ValidateFieldSelectorRequirement(requirement metav1.FieldSelectorRequirement, opts FieldSelectorValidationOptions, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+
+ if len(requirement.Key) == 0 {
+ allErrs = append(allErrs, field.Required(fldPath.Child("key"), "must be specified"))
+ }
+
+ switch requirement.Operator {
+ case metav1.FieldSelectorOpIn, metav1.FieldSelectorOpNotIn:
+ if len(requirement.Values) == 0 {
+ allErrs = append(allErrs, field.Required(fldPath.Child("values"), "must be specified when `operator` is 'In' or 'NotIn'"))
+ }
+ case metav1.FieldSelectorOpExists, metav1.FieldSelectorOpDoesNotExist:
+ if len(requirement.Values) > 0 {
+ allErrs = append(allErrs, field.Forbidden(fldPath.Child("values"), "may not be specified when `operator` is 'Exists' or 'DoesNotExist'"))
+ }
+ default:
+ if !opts.AllowUnknownOperatorInRequirement {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("operator"), requirement.Operator, "not a valid selector operator"))
+ }
+ }
+
+ return allErrs
+}
+
+func ValidateDeleteOptions(options *metav1.DeleteOptions) field.ErrorList {
+ allErrs := field.ErrorList{}
+ //lint:file-ignore SA1019 Keep validation for deprecated OrphanDependents option until it's being removed
+ if options.OrphanDependents != nil && options.PropagationPolicy != nil {
+ allErrs = append(allErrs, field.Invalid(field.NewPath("propagationPolicy"), options.PropagationPolicy, "orphanDependents and deletionPropagation cannot be both set"))
+ }
+ if options.PropagationPolicy != nil &&
+ *options.PropagationPolicy != metav1.DeletePropagationForeground &&
+ *options.PropagationPolicy != metav1.DeletePropagationBackground &&
+ *options.PropagationPolicy != metav1.DeletePropagationOrphan {
+ allErrs = append(allErrs, field.NotSupported(field.NewPath("propagationPolicy"), options.PropagationPolicy, []string{string(metav1.DeletePropagationForeground), string(metav1.DeletePropagationBackground), string(metav1.DeletePropagationOrphan), "nil"}))
+ }
+ allErrs = append(allErrs, ValidateDryRun(field.NewPath("dryRun"), options.DryRun)...)
+ allErrs = append(allErrs, ValidateIgnoreStoreReadError(field.NewPath("ignoreStoreReadErrorWithClusterBreakingPotential"), options)...)
+ return allErrs
+}
+
+func ValidateCreateOptions(options *metav1.CreateOptions) field.ErrorList {
+ allErrs := field.ErrorList{}
+ allErrs = append(allErrs, ValidateFieldManager(options.FieldManager, field.NewPath("fieldManager"))...)
+ allErrs = append(allErrs, ValidateDryRun(field.NewPath("dryRun"), options.DryRun)...)
+ allErrs = append(allErrs, ValidateFieldValidation(field.NewPath("fieldValidation"), options.FieldValidation)...)
+ return allErrs
+}
+
+func ValidateUpdateOptions(options *metav1.UpdateOptions) field.ErrorList {
+ allErrs := field.ErrorList{}
+ allErrs = append(allErrs, ValidateFieldManager(options.FieldManager, field.NewPath("fieldManager"))...)
+ allErrs = append(allErrs, ValidateDryRun(field.NewPath("dryRun"), options.DryRun)...)
+ allErrs = append(allErrs, ValidateFieldValidation(field.NewPath("fieldValidation"), options.FieldValidation)...)
+ return allErrs
+}
+
+func ValidatePatchOptions(options *metav1.PatchOptions, patchType types.PatchType) field.ErrorList {
+ allErrs := field.ErrorList{}
+ switch patchType {
+ case types.ApplyYAMLPatchType, types.ApplyCBORPatchType:
+ if options.FieldManager == "" {
+ // This field is defaulted to "kubectl" by kubectl, but HAS TO be explicitly set by controllers.
+ allErrs = append(allErrs, field.Required(field.NewPath("fieldManager"), "is required for apply patch"))
+ }
+ default:
+ if options.Force != nil {
+ allErrs = append(allErrs, field.Forbidden(field.NewPath("force"), "may not be specified for non-apply patch"))
+ }
+ }
+ allErrs = append(allErrs, ValidateFieldManager(options.FieldManager, field.NewPath("fieldManager"))...)
+ allErrs = append(allErrs, ValidateDryRun(field.NewPath("dryRun"), options.DryRun)...)
+ allErrs = append(allErrs, ValidateFieldValidation(field.NewPath("fieldValidation"), options.FieldValidation)...)
+ return allErrs
+}
+
+var FieldManagerMaxLength = 128
+
+// ValidateFieldManager valides that the fieldManager is the proper length and
+// only has printable characters.
+func ValidateFieldManager(fieldManager string, fldPath *field.Path) field.ErrorList {
+ allErrs := field.ErrorList{}
+ // the field can not be set as a `*string`, so a empty string ("") is
+ // considered as not set and is defaulted by the rest of the process
+ // (unless apply is used, in which case it is required).
+ if len(fieldManager) > FieldManagerMaxLength {
+ allErrs = append(allErrs, field.TooLong(fldPath, "" /*unused*/, FieldManagerMaxLength))
+ }
+ // Verify that all characters are printable.
+ for i, r := range fieldManager {
+ if !unicode.IsPrint(r) {
+ allErrs = append(allErrs, field.Invalid(fldPath, fieldManager, fmt.Sprintf("invalid character %#U (at position %d)", r, i)))
+ }
+ }
+
+ return allErrs
+}
+
+var allowedDryRunValues = sets.NewString(metav1.DryRunAll)
+
+// ValidateDryRun validates that a dryRun query param only contains allowed values.
+func ValidateDryRun(fldPath *field.Path, dryRun []string) field.ErrorList {
+ allErrs := field.ErrorList{}
+ if !allowedDryRunValues.HasAll(dryRun...) {
+ allErrs = append(allErrs, field.NotSupported(fldPath, dryRun, allowedDryRunValues.List()))
+ }
+ return allErrs
+}
+
+var allowedFieldValidationValues = sets.NewString("", metav1.FieldValidationIgnore, metav1.FieldValidationWarn, metav1.FieldValidationStrict)
+
+// ValidateFieldValidation validates that a fieldValidation query param only contains allowed values.
+func ValidateFieldValidation(fldPath *field.Path, fieldValidation string) field.ErrorList {
+ allErrs := field.ErrorList{}
+ if !allowedFieldValidationValues.Has(fieldValidation) {
+ allErrs = append(allErrs, field.NotSupported(fldPath, fieldValidation, allowedFieldValidationValues.List()))
+ }
+ return allErrs
+
+}
+
+const UninitializedStatusUpdateErrorMsg string = `must not update status when the object is uninitialized`
+
+// ValidateTableOptions returns any invalid flags on TableOptions.
+func ValidateTableOptions(opts *metav1.TableOptions) field.ErrorList {
+ var allErrs field.ErrorList
+ switch opts.IncludeObject {
+ case metav1.IncludeMetadata, metav1.IncludeNone, metav1.IncludeObject, "":
+ default:
+ allErrs = append(allErrs, field.Invalid(field.NewPath("includeObject"), opts.IncludeObject, "must be 'Metadata', 'Object', 'None', or empty"))
+ }
+ return allErrs
+}
+
+const MaxSubresourceNameLength = 256
+
+func ValidateManagedFields(fieldsList []metav1.ManagedFieldsEntry, fldPath *field.Path) field.ErrorList {
+ var allErrs field.ErrorList
+ for i, fields := range fieldsList {
+ fldPath := fldPath.Index(i)
+ switch fields.Operation {
+ case metav1.ManagedFieldsOperationApply, metav1.ManagedFieldsOperationUpdate:
+ default:
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("operation"), fields.Operation, "must be `Apply` or `Update`"))
+ }
+ if len(fields.FieldsType) > 0 && fields.FieldsType != "FieldsV1" {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("fieldsType"), fields.FieldsType, "must be `FieldsV1`"))
+ }
+ allErrs = append(allErrs, ValidateFieldManager(fields.Manager, fldPath.Child("manager"))...)
+
+ if len(fields.Subresource) > MaxSubresourceNameLength {
+ allErrs = append(allErrs, field.TooLong(fldPath.Child("subresource"), "" /*unused*/, MaxSubresourceNameLength))
+ }
+ }
+ return allErrs
+}
+
+func ValidateConditions(conditions []metav1.Condition, fldPath *field.Path) field.ErrorList {
+ var allErrs field.ErrorList
+
+ conditionTypeToFirstIndex := map[string]int{}
+ for i, condition := range conditions {
+ if _, ok := conditionTypeToFirstIndex[condition.Type]; ok {
+ allErrs = append(allErrs, field.Duplicate(fldPath.Index(i).Child("type"), condition.Type))
+ } else {
+ conditionTypeToFirstIndex[condition.Type] = i
+ }
+
+ allErrs = append(allErrs, ValidateCondition(condition, fldPath.Index(i))...)
+ }
+
+ return allErrs
+}
+
+// validConditionStatuses is used internally to check validity and provide a good message
+var validConditionStatuses = sets.NewString(string(metav1.ConditionTrue), string(metav1.ConditionFalse), string(metav1.ConditionUnknown))
+
+const (
+ maxReasonLen = 1 * 1024
+ maxMessageLen = 32 * 1024
+)
+
+func ValidateCondition(condition metav1.Condition, fldPath *field.Path) field.ErrorList {
+ var allErrs field.ErrorList
+
+ // type is set and is a valid format
+ allErrs = append(allErrs, ValidateLabelName(condition.Type, fldPath.Child("type"))...)
+
+ // status is set and is an accepted value
+ if !validConditionStatuses.Has(string(condition.Status)) {
+ allErrs = append(allErrs, field.NotSupported(fldPath.Child("status"), condition.Status, validConditionStatuses.List()))
+ }
+
+ if condition.ObservedGeneration < 0 {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("observedGeneration"), condition.ObservedGeneration, "must be greater than or equal to zero"))
+ }
+
+ if condition.LastTransitionTime.IsZero() {
+ allErrs = append(allErrs, field.Required(fldPath.Child("lastTransitionTime"), "must be set"))
+ }
+
+ if len(condition.Reason) == 0 {
+ allErrs = append(allErrs, field.Required(fldPath.Child("reason"), "must be set"))
+ } else {
+ for _, currErr := range isValidConditionReason(condition.Reason) {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("reason"), condition.Reason, currErr))
+ }
+ if len(condition.Reason) > maxReasonLen {
+ allErrs = append(allErrs, field.TooLong(fldPath.Child("reason"), "" /*unused*/, maxReasonLen))
+ }
+ }
+
+ if len(condition.Message) > maxMessageLen {
+ allErrs = append(allErrs, field.TooLong(fldPath.Child("message"), "" /*unused*/, maxMessageLen))
+ }
+
+ return allErrs
+}
+
+const conditionReasonFmt string = "[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?"
+const conditionReasonErrMsg string = "a condition reason must start with alphabetic character, optionally followed by a string of alphanumeric characters or '_,:', and must end with an alphanumeric character or '_'"
+
+var conditionReasonRegexp = regexp.MustCompile("^" + conditionReasonFmt + "$")
+
+// isValidConditionReason tests for a string that conforms to rules for condition reasons. This checks the format, but not the length.
+func isValidConditionReason(value string) []string {
+ if !conditionReasonRegexp.MatchString(value) {
+ return []string{validation.RegexError(conditionReasonErrMsg, conditionReasonFmt, "my_name", "MY_NAME", "MyName", "ReasonA,ReasonB", "ReasonA:ReasonB")}
+ }
+ return nil
+}
+
+// ValidateIgnoreStoreReadError validates that delete options are valid when
+// ignoreStoreReadErrorWithClusterBreakingPotential is enabled
+func ValidateIgnoreStoreReadError(fldPath *field.Path, options *metav1.DeleteOptions) field.ErrorList {
+ allErrs := field.ErrorList{}
+ if enabled := ptr.Deref[bool](options.IgnoreStoreReadErrorWithClusterBreakingPotential, false); !enabled {
+ return allErrs
+ }
+
+ if len(options.DryRun) > 0 {
+ allErrs = append(allErrs, field.Invalid(fldPath, true, "cannot be set together with .dryRun"))
+ }
+ if options.PropagationPolicy != nil {
+ allErrs = append(allErrs, field.Invalid(fldPath, true, "cannot be set together with .propagationPolicy"))
+ }
+ //nolint:staticcheck // Keep validation for deprecated OrphanDependents option until it's being removed
+ if options.OrphanDependents != nil {
+ allErrs = append(allErrs, field.Invalid(fldPath, true, "cannot be set together with .orphanDependents"))
+ }
+ if options.GracePeriodSeconds != nil {
+ allErrs = append(allErrs, field.Invalid(fldPath, true, "cannot be set together with .gracePeriodSeconds"))
+ }
+ if options.Preconditions != nil {
+ allErrs = append(allErrs, field.Invalid(fldPath, true, "cannot be set together with .preconditions"))
+ }
+
+ return allErrs
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go
index b7590f0b3..82e272240 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go
@@ -339,6 +339,13 @@ func autoConvert_url_Values_To_v1_DeleteOptions(in *url.Values, out *DeleteOptio
} else {
out.DryRun = nil
}
+ if values, ok := map[string][]string(*in)["ignoreStoreReadErrorWithClusterBreakingPotential"]; ok && len(values) > 0 {
+ if err := runtime.Convert_Slice_string_To_Pointer_bool(&values, &out.IgnoreStoreReadErrorWithClusterBreakingPotential, s); err != nil {
+ return err
+ }
+ } else {
+ out.IgnoreStoreReadErrorWithClusterBreakingPotential = nil
+ }
return nil
}
@@ -426,6 +433,13 @@ func autoConvert_url_Values_To_v1_ListOptions(in *url.Values, out *ListOptions,
} else {
out.Continue = ""
}
+ if values, ok := map[string][]string(*in)["sendInitialEvents"]; ok && len(values) > 0 {
+ if err := runtime.Convert_Slice_string_To_Pointer_bool(&values, &out.SendInitialEvents, s); err != nil {
+ return err
+ }
+ } else {
+ out.SendInitialEvents = nil
+ }
return nil
}
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go
index 418e6099f..6b0d0dfee 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go
@@ -290,6 +290,11 @@ func (in *DeleteOptions) DeepCopyInto(out *DeleteOptions) {
*out = make([]string, len(*in))
copy(*out, *in)
}
+ if in.IgnoreStoreReadErrorWithClusterBreakingPotential != nil {
+ in, out := &in.IgnoreStoreReadErrorWithClusterBreakingPotential, &out.IgnoreStoreReadErrorWithClusterBreakingPotential
+ *out = new(bool)
+ **out = **in
+ }
return
}
@@ -327,6 +332,27 @@ func (in *Duration) DeepCopy() *Duration {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FieldSelectorRequirement) DeepCopyInto(out *FieldSelectorRequirement) {
+ *out = *in
+ if in.Values != nil {
+ in, out := &in.Values, &out.Values
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FieldSelectorRequirement.
+func (in *FieldSelectorRequirement) DeepCopy() *FieldSelectorRequirement {
+ if in == nil {
+ return nil
+ }
+ out := new(FieldSelectorRequirement)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FieldsV1) DeepCopyInto(out *FieldsV1) {
*out = *in
@@ -602,6 +628,11 @@ func (in *ListOptions) DeepCopyInto(out *ListOptions) {
*out = new(int64)
**out = **in
}
+ if in.SendInitialEvents != nil {
+ in, out := &in.SendInitialEvents, &out.SendInitialEvents
+ *out = new(bool)
+ **out = **in
+ }
return
}
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.pb.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.pb.go
index a2abc67c1..819d936fe 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.pb.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.pb.go
@@ -15,7 +15,7 @@ limitations under the License.
*/
// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto
+// source: k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto
package v1beta1
@@ -47,7 +47,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func (m *PartialObjectMetadataList) Reset() { *m = PartialObjectMetadataList{} }
func (*PartialObjectMetadataList) ProtoMessage() {}
func (*PartialObjectMetadataList) Descriptor() ([]byte, []int) {
- return fileDescriptor_90ec10f86b91f9a8, []int{0}
+ return fileDescriptor_39237a8d8061b52f, []int{0}
}
func (m *PartialObjectMetadataList) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -77,31 +77,30 @@ func init() {
}
func init() {
- proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto", fileDescriptor_90ec10f86b91f9a8)
+ proto.RegisterFile("k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto", fileDescriptor_39237a8d8061b52f)
}
-var fileDescriptor_90ec10f86b91f9a8 = []byte{
- // 317 bytes of a gzipped FileDescriptorProto
+var fileDescriptor_39237a8d8061b52f = []byte{
+ // 303 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x41, 0x4b, 0xf3, 0x30,
0x1c, 0xc6, 0x9b, 0xf7, 0x65, 0x30, 0x3a, 0x04, 0xd9, 0x69, 0xee, 0x90, 0x0d, 0x4f, 0xdb, 0xc1,
- 0x84, 0x0d, 0x11, 0xc1, 0xdb, 0x6e, 0x82, 0x32, 0xd9, 0x51, 0x3c, 0x98, 0x76, 0x7f, 0xbb, 0x58,
- 0xd3, 0x94, 0xe4, 0xdf, 0x81, 0x37, 0x3f, 0x82, 0x1f, 0x6b, 0xc7, 0x1d, 0x07, 0xc2, 0x70, 0xf5,
- 0x8b, 0x48, 0xda, 0x2a, 0x32, 0x14, 0x7a, 0xeb, 0xf3, 0x94, 0xdf, 0x2f, 0x4f, 0x20, 0xfe, 0x2c,
- 0x3e, 0xb7, 0x4c, 0x6a, 0x1e, 0x67, 0x01, 0x98, 0x04, 0x10, 0x2c, 0x5f, 0x42, 0x32, 0xd7, 0x86,
- 0x57, 0x3f, 0x44, 0x2a, 0x95, 0x08, 0x17, 0x32, 0x01, 0xf3, 0xcc, 0xd3, 0x38, 0x72, 0x85, 0xe5,
- 0x0a, 0x50, 0xf0, 0xe5, 0x28, 0x00, 0x14, 0x23, 0x1e, 0x41, 0x02, 0x46, 0x20, 0xcc, 0x59, 0x6a,
- 0x34, 0xea, 0xf6, 0xb0, 0x44, 0xd9, 0x4f, 0x94, 0xa5, 0x71, 0xe4, 0x0a, 0xcb, 0x1c, 0xca, 0x2a,
- 0xb4, 0x7b, 0x12, 0x49, 0x5c, 0x64, 0x01, 0x0b, 0xb5, 0xe2, 0x91, 0x8e, 0x34, 0x2f, 0x0c, 0x41,
- 0xf6, 0x50, 0xa4, 0x22, 0x14, 0x5f, 0xa5, 0xb9, 0x7b, 0x5a, 0x67, 0xd4, 0xfe, 0x9e, 0xee, 0xd9,
- 0x5f, 0x94, 0xc9, 0x12, 0x94, 0x0a, 0xb8, 0x0d, 0x17, 0xa0, 0xc4, 0x3e, 0x77, 0xfc, 0x46, 0xfc,
- 0xa3, 0x1b, 0x61, 0x50, 0x8a, 0xa7, 0x69, 0xf0, 0x08, 0x21, 0x5e, 0x03, 0x8a, 0xb9, 0x40, 0x71,
- 0x25, 0x2d, 0xb6, 0xef, 0xfc, 0xa6, 0xaa, 0x72, 0xe7, 0x5f, 0x9f, 0x0c, 0x5a, 0x63, 0xc6, 0xea,
- 0x5c, 0x9c, 0x39, 0xda, 0x99, 0x26, 0x87, 0xab, 0x6d, 0xcf, 0xcb, 0xb7, 0xbd, 0xe6, 0x57, 0x33,
- 0xfb, 0x36, 0xb6, 0xef, 0xfd, 0x86, 0x44, 0x50, 0xb6, 0x43, 0xfa, 0xff, 0x07, 0xad, 0xf1, 0x45,
- 0x3d, 0xf5, 0xaf, 0x6b, 0x27, 0x07, 0xd5, 0x39, 0x8d, 0x4b, 0x67, 0x9c, 0x95, 0xe2, 0xc9, 0x74,
- 0xb5, 0xa3, 0xde, 0x7a, 0x47, 0xbd, 0xcd, 0x8e, 0x7a, 0x2f, 0x39, 0x25, 0xab, 0x9c, 0x92, 0x75,
- 0x4e, 0xc9, 0x26, 0xa7, 0xe4, 0x3d, 0xa7, 0xe4, 0xf5, 0x83, 0x7a, 0xb7, 0xc3, 0xda, 0xcf, 0xe0,
- 0x33, 0x00, 0x00, 0xff, 0xff, 0x30, 0x97, 0x8b, 0x11, 0x4b, 0x02, 0x00, 0x00,
+ 0x84, 0x0d, 0x11, 0xc5, 0xdb, 0x6e, 0x82, 0x32, 0xd9, 0x51, 0x3c, 0x98, 0x76, 0x31, 0x8b, 0x35,
+ 0x4d, 0x69, 0xfe, 0x15, 0xbc, 0xf9, 0x11, 0xfc, 0x58, 0x3d, 0xee, 0x38, 0x10, 0x86, 0x8d, 0x5f,
+ 0x44, 0xd2, 0x56, 0x91, 0xa1, 0xd0, 0x5b, 0x9e, 0x07, 0x7e, 0xbf, 0x3c, 0x81, 0xf8, 0x67, 0xd1,
+ 0xa9, 0x21, 0x52, 0x53, 0x96, 0x48, 0xc5, 0xc2, 0x95, 0x8c, 0x79, 0xfa, 0x4c, 0x93, 0x48, 0xb8,
+ 0xc2, 0x50, 0xc5, 0x81, 0xd1, 0xa7, 0x49, 0xc0, 0x81, 0x4d, 0xa8, 0xe0, 0x31, 0x4f, 0x19, 0xf0,
+ 0x25, 0x49, 0x52, 0x0d, 0xba, 0x3b, 0xae, 0x50, 0xf2, 0x13, 0x25, 0x49, 0x24, 0x5c, 0x61, 0x88,
+ 0x43, 0x49, 0x8d, 0xf6, 0x8f, 0x84, 0x84, 0x55, 0x16, 0x90, 0x50, 0x2b, 0x2a, 0xb4, 0xd0, 0xb4,
+ 0x34, 0x04, 0xd9, 0x7d, 0x99, 0xca, 0x50, 0x9e, 0x2a, 0x73, 0xff, 0xb8, 0xc9, 0xa8, 0xdd, 0x3d,
+ 0xfd, 0x93, 0xbf, 0xa8, 0x34, 0x8b, 0x41, 0x2a, 0x4e, 0x4d, 0xb8, 0xe2, 0x8a, 0xed, 0x72, 0x87,
+ 0x6f, 0xc8, 0x3f, 0xb8, 0x66, 0x29, 0x48, 0xf6, 0x38, 0x0f, 0x1e, 0x78, 0x08, 0x57, 0x1c, 0xd8,
+ 0x92, 0x01, 0xbb, 0x94, 0x06, 0xba, 0xb7, 0x7e, 0x5b, 0xd5, 0xb9, 0xf7, 0x6f, 0x88, 0x46, 0x9d,
+ 0x29, 0x21, 0x4d, 0x1e, 0x4e, 0x1c, 0xed, 0x4c, 0xb3, 0xfd, 0x7c, 0x3b, 0xf0, 0xec, 0x76, 0xd0,
+ 0xfe, 0x6a, 0x16, 0xdf, 0xc6, 0xee, 0x9d, 0xdf, 0x92, 0xc0, 0x95, 0xe9, 0xa1, 0xe1, 0xff, 0x51,
+ 0x67, 0x7a, 0xde, 0x4c, 0xfd, 0xeb, 0xda, 0xd9, 0x5e, 0x7d, 0x4f, 0xeb, 0xc2, 0x19, 0x17, 0x95,
+ 0x78, 0x36, 0xcf, 0x0b, 0xec, 0xad, 0x0b, 0xec, 0x6d, 0x0a, 0xec, 0xbd, 0x58, 0x8c, 0x72, 0x8b,
+ 0xd1, 0xda, 0x62, 0xb4, 0xb1, 0x18, 0xbd, 0x5b, 0x8c, 0x5e, 0x3f, 0xb0, 0x77, 0x33, 0x6e, 0xfc,
+ 0x0d, 0x3e, 0x03, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x0f, 0xd7, 0x36, 0x32, 0x02, 0x00, 0x00,
}
func (m *PartialObjectMetadataList) Marshal() (dAtA []byte, err error) {
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto
index d14d42591..fcec55354 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto
@@ -33,9 +33,9 @@ message PartialObjectMetadataList {
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
- optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 2;
+ optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 2;
// items contains each of the included items.
- repeated k8s.io.apimachinery.pkg.apis.meta.v1.PartialObjectMetadata items = 1;
+ repeated .k8s.io.apimachinery.pkg.apis.meta.v1.PartialObjectMetadata items = 1;
}
diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go
index ef7e7c1e9..dff735dcf 100644
--- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go
+++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go
@@ -24,7 +24,7 @@ package v1beta1
// they are on one line! For multiple line or blocks that you want to ignore use ---.
// Any context after a --- is ignored.
//
-// Those methods can be generated by using hack/update-generated-swagger-docs.sh
+// Those methods can be generated by using hack/update-codegen.sh
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
var map_PartialObjectMetadataList = map[string]string{
diff --git a/vendor/k8s.io/apimachinery/pkg/labels/labels.go b/vendor/k8s.io/apimachinery/pkg/labels/labels.go
index 8360d842b..19d823cef 100644
--- a/vendor/k8s.io/apimachinery/pkg/labels/labels.go
+++ b/vendor/k8s.io/apimachinery/pkg/labels/labels.go
@@ -77,6 +77,8 @@ func (ls Set) AsValidatedSelector() (Selector, error) {
// perform any validation.
// According to our measurements this is significantly faster
// in codepaths that matter at high scale.
+// Note: this method copies the Set; if the Set is immutable, consider wrapping it with ValidatedSetSelector
+// instead, which does not copy.
func (ls Set) AsSelectorPreValidated() Selector {
return SelectorFromValidatedSet(ls)
}
diff --git a/vendor/k8s.io/apimachinery/pkg/labels/selector.go b/vendor/k8s.io/apimachinery/pkg/labels/selector.go
index 891004389..fafa81a3d 100644
--- a/vendor/k8s.io/apimachinery/pkg/labels/selector.go
+++ b/vendor/k8s.io/apimachinery/pkg/labels/selector.go
@@ -18,6 +18,7 @@ package labels
import (
"fmt"
+ "slices"
"sort"
"strconv"
"strings"
@@ -27,7 +28,6 @@ import (
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/klog/v2"
- stringslices "k8s.io/utils/strings/slices"
)
var (
@@ -45,6 +45,19 @@ var (
// Requirements is AND of all requirements.
type Requirements []Requirement
+func (r Requirements) String() string {
+ var sb strings.Builder
+
+ for i, requirement := range r {
+ if i > 0 {
+ sb.WriteString(", ")
+ }
+ sb.WriteString(requirement.String())
+ }
+
+ return sb.String()
+}
+
// Selector represents a label selector.
type Selector interface {
// Matches returns true if this selector matches the given set of labels.
@@ -149,14 +162,12 @@ type Requirement struct {
// NewRequirement is the constructor for a Requirement.
// If any of these rules is violated, an error is returned:
-// (1) The operator can only be In, NotIn, Equals, DoubleEquals, Gt, Lt, NotEquals, Exists, or DoesNotExist.
-// (2) If the operator is In or NotIn, the values set must be non-empty.
-// (3) If the operator is Equals, DoubleEquals, or NotEquals, the values set must contain one value.
-// (4) If the operator is Exists or DoesNotExist, the value set must be empty.
-// (5) If the operator is Gt or Lt, the values set must contain only one value, which will be interpreted as an integer.
-// (6) The key is invalid due to its length, or sequence
-//
-// of characters. See validateLabelKey for more details.
+// 1. The operator can only be In, NotIn, Equals, DoubleEquals, Gt, Lt, NotEquals, Exists, or DoesNotExist.
+// 2. If the operator is In or NotIn, the values set must be non-empty.
+// 3. If the operator is Equals, DoubleEquals, or NotEquals, the values set must contain one value.
+// 4. If the operator is Exists or DoesNotExist, the value set must be empty.
+// 5. If the operator is Gt or Lt, the values set must contain only one value, which will be interpreted as an integer.
+// 6. The key is invalid due to its length, or sequence of characters. See validateLabelKey for more details.
//
// The empty string is a valid value in the input values set.
// Returned error, if not nil, is guaranteed to be an aggregated field.ErrorList
@@ -213,22 +224,15 @@ func (r *Requirement) hasValue(value string) bool {
// Matches returns true if the Requirement matches the input Labels.
// There is a match in the following cases:
-// (1) The operator is Exists and Labels has the Requirement's key.
-// (2) The operator is In, Labels has the Requirement's key and Labels'
-//
-// value for that key is in Requirement's value set.
-//
-// (3) The operator is NotIn, Labels has the Requirement's key and
-//
-// Labels' value for that key is not in Requirement's value set.
-//
-// (4) The operator is DoesNotExist or NotIn and Labels does not have the
-//
-// Requirement's key.
-//
-// (5) The operator is GreaterThanOperator or LessThanOperator, and Labels has
-//
-// the Requirement's key and the corresponding value satisfies mathematical inequality.
+// 1. The operator is Exists and Labels has the Requirement's key.
+// 2. The operator is In, Labels has the Requirement's key and Labels'
+// value for that key is in Requirement's value set.
+// 3. The operator is NotIn, Labels has the Requirement's key and
+// Labels' value for that key is not in Requirement's value set.
+// 4. The operator is DoesNotExist or NotIn and Labels does not have the
+// Requirement's key.
+// 5. The operator is GreaterThanOperator or LessThanOperator, and Labels has
+// the Requirement's key and the corresponding value satisfies mathematical inequality.
func (r *Requirement) Matches(ls Labels) bool {
switch r.operator {
case selection.In, selection.Equals, selection.DoubleEquals:
@@ -294,6 +298,13 @@ func (r *Requirement) Values() sets.String {
return ret
}
+// ValuesUnsorted returns a copy of requirement values as passed to NewRequirement without sorting.
+func (r *Requirement) ValuesUnsorted() []string {
+ ret := make([]string, 0, len(r.strValues))
+ ret = append(ret, r.strValues...)
+ return ret
+}
+
// Equal checks the equality of requirement.
func (r Requirement) Equal(x Requirement) bool {
if r.key != x.key {
@@ -302,7 +313,7 @@ func (r Requirement) Equal(x Requirement) bool {
if r.operator != x.operator {
return false
}
- return stringslices.Equal(r.strValues, x.strValues)
+ return slices.Equal(r.strValues, x.strValues)
}
// Empty returns true if the internalSelector doesn't restrict selection space
@@ -872,15 +883,14 @@ func (p *Parser) parseExactValue() (sets.String, error) {
// "x in (foo,,baz),y,z notin ()"
//
// Note:
-//
-// (1) Inclusion - " in " - denotes that the KEY exists and is equal to any of the
-// VALUEs in its requirement
-// (2) Exclusion - " notin " - denotes that the KEY is not equal to any
-// of the VALUEs in its requirement or does not exist
-// (3) The empty string is a valid VALUE
-// (4) A requirement with just a KEY - as in "y" above - denotes that
-// the KEY exists and can be any VALUE.
-// (5) A requirement with just !KEY requires that the KEY not exist.
+// 1. Inclusion - " in " - denotes that the KEY exists and is equal to any of the
+// VALUEs in its requirement
+// 2. Exclusion - " notin " - denotes that the KEY is not equal to any
+// of the VALUEs in its requirement or does not exist
+// 3. The empty string is a valid VALUE
+// 4. A requirement with just a KEY - as in "y" above - denotes that
+// the KEY exists and can be any VALUE.
+// 5. A requirement with just !KEY requires that the KEY not exist.
func Parse(selector string, opts ...field.PathOption) (Selector, error) {
parsedSelector, err := parse(selector, field.ToPath(opts...))
if err == nil {
@@ -948,6 +958,8 @@ func ValidatedSelectorFromSet(ls Set) (Selector, error) {
// SelectorFromValidatedSet returns a Selector which will match exactly the given Set.
// A nil and empty Sets are considered equivalent to Everything().
// It assumes that Set is already validated and doesn't do any validation.
+// Note: this method copies the Set; if the Set is immutable, consider wrapping it with ValidatedSetSelector
+// instead, which does not copy.
func SelectorFromValidatedSet(ls Set) Selector {
if ls == nil || len(ls) == 0 {
return internalSelector{}
@@ -969,3 +981,76 @@ func SelectorFromValidatedSet(ls Set) Selector {
func ParseToRequirements(selector string, opts ...field.PathOption) ([]Requirement, error) {
return parse(selector, field.ToPath(opts...))
}
+
+// ValidatedSetSelector wraps a Set, allowing it to implement the Selector interface. Unlike
+// Set.AsSelectorPreValidated (which copies the input Set), this type simply wraps the underlying
+// Set. As a result, it is substantially more efficient. A nil and empty Sets are considered
+// equivalent to Everything().
+//
+// Callers MUST ensure the underlying Set is not mutated, and that it is already validated. If these
+// constraints are not met, Set.AsValidatedSelector should be preferred
+//
+// None of the Selector methods mutate the underlying Set, but Add() and Requirements() convert to
+// the less optimized version.
+type ValidatedSetSelector Set
+
+func (s ValidatedSetSelector) Matches(labels Labels) bool {
+ for k, v := range s {
+ if !labels.Has(k) || v != labels.Get(k) {
+ return false
+ }
+ }
+ return true
+}
+
+func (s ValidatedSetSelector) Empty() bool {
+ return len(s) == 0
+}
+
+func (s ValidatedSetSelector) String() string {
+ keys := make([]string, 0, len(s))
+ for k := range s {
+ keys = append(keys, k)
+ }
+ // Ensure deterministic output
+ sort.Strings(keys)
+ b := strings.Builder{}
+ for i, key := range keys {
+ v := s[key]
+ b.Grow(len(key) + 2 + len(v))
+ if i != 0 {
+ b.WriteString(",")
+ }
+ b.WriteString(key)
+ b.WriteString("=")
+ b.WriteString(v)
+ }
+ return b.String()
+}
+
+func (s ValidatedSetSelector) Add(r ...Requirement) Selector {
+ return s.toFullSelector().Add(r...)
+}
+
+func (s ValidatedSetSelector) Requirements() (requirements Requirements, selectable bool) {
+ return s.toFullSelector().Requirements()
+}
+
+func (s ValidatedSetSelector) DeepCopySelector() Selector {
+ res := make(ValidatedSetSelector, len(s))
+ for k, v := range s {
+ res[k] = v
+ }
+ return res
+}
+
+func (s ValidatedSetSelector) RequiresExactMatch(label string) (value string, found bool) {
+ v, f := s[label]
+ return v, f
+}
+
+func (s ValidatedSetSelector) toFullSelector() Selector {
+ return SelectorFromValidatedSet(Set(s))
+}
+
+var _ Selector = ValidatedSetSelector{}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/codec.go b/vendor/k8s.io/apimachinery/pkg/runtime/codec.go
index 7fc513dd0..73f85286c 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/codec.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/codec.go
@@ -45,7 +45,6 @@ func NewCodec(e Encoder, d Decoder) Codec {
// Encode is a convenience wrapper for encoding to a []byte from an Encoder
func Encode(e Encoder, obj Object) ([]byte, error) {
- // TODO: reuse buffer
buf := &bytes.Buffer{}
if err := e.Encode(obj, buf); err != nil {
return nil, err
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/converter.go b/vendor/k8s.io/apimachinery/pkg/runtime/converter.go
index 90bf487e3..62eb27afc 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/converter.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/converter.go
@@ -231,7 +231,7 @@ func (c *fromUnstructuredContext) pushKey(key string) {
}
-// FromUnstructuredWIthValidation converts an object from map[string]interface{} representation into a concrete type.
+// FromUnstructuredWithValidation converts an object from map[string]interface{} representation into a concrete type.
// It uses encoding/json/Unmarshaler if object implements it or reflection if not.
// It takes a validationDirective that indicates how to behave when it encounters unknown fields.
func (c *unstructuredConverter) FromUnstructuredWithValidation(u map[string]interface{}, obj interface{}, returnUnknownFields bool) error {
@@ -465,7 +465,7 @@ func sliceFromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) e
}
dv.SetBytes(data)
} else {
- dv.Set(reflect.Zero(dt))
+ dv.Set(reflect.MakeSlice(dt, 0, 0))
}
return nil
}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/extension.go b/vendor/k8s.io/apimachinery/pkg/runtime/extension.go
index 9056397fa..60c000bcb 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/extension.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/extension.go
@@ -18,16 +18,77 @@ package runtime
import (
"bytes"
- "encoding/json"
"errors"
+ "fmt"
+
+ cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
+ "k8s.io/apimachinery/pkg/util/json"
)
+// RawExtension intentionally avoids implementing value.UnstructuredConverter for now because the
+// signature of ToUnstructured does not allow returning an error value in cases where the conversion
+// is not possible (content type is unrecognized or bytes don't match content type).
+func rawToUnstructured(raw []byte, contentType string) (interface{}, error) {
+ switch contentType {
+ case ContentTypeJSON:
+ var u interface{}
+ if err := json.Unmarshal(raw, &u); err != nil {
+ return nil, fmt.Errorf("failed to parse RawExtension bytes as JSON: %w", err)
+ }
+ return u, nil
+ case ContentTypeCBOR:
+ var u interface{}
+ if err := cbor.Unmarshal(raw, &u); err != nil {
+ return nil, fmt.Errorf("failed to parse RawExtension bytes as CBOR: %w", err)
+ }
+ return u, nil
+ default:
+ return nil, fmt.Errorf("cannot convert RawExtension with unrecognized content type to unstructured")
+ }
+}
+
+func (re RawExtension) guessContentType() string {
+ switch {
+ case bytes.HasPrefix(re.Raw, cborSelfDescribed):
+ return ContentTypeCBOR
+ case len(re.Raw) > 0:
+ switch re.Raw[0] {
+ case '\t', '\r', '\n', ' ', '{', '[', 'n', 't', 'f', '"', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ // Prefixes for the four whitespace characters, objects, arrays, strings, numbers, true, false, and null.
+ return ContentTypeJSON
+ }
+ }
+ return ""
+}
+
func (re *RawExtension) UnmarshalJSON(in []byte) error {
if re == nil {
return errors.New("runtime.RawExtension: UnmarshalJSON on nil pointer")
}
- if !bytes.Equal(in, []byte("null")) {
- re.Raw = append(re.Raw[0:0], in...)
+ if bytes.Equal(in, []byte("null")) {
+ return nil
+ }
+ re.Raw = append(re.Raw[0:0], in...)
+ return nil
+}
+
+var (
+ cborNull = []byte{0xf6}
+ cborSelfDescribed = []byte{0xd9, 0xd9, 0xf7}
+)
+
+func (re *RawExtension) UnmarshalCBOR(in []byte) error {
+ if re == nil {
+ return errors.New("runtime.RawExtension: UnmarshalCBOR on nil pointer")
+ }
+ if !bytes.Equal(in, cborNull) {
+ if !bytes.HasPrefix(in, cborSelfDescribed) {
+ // The self-described CBOR tag doesn't change the interpretation of the data
+ // item it encloses, but it is useful as a magic number. Its encoding is
+ // also what is used to implement the CBOR RecognizingDecoder.
+ re.Raw = append(re.Raw[:0], cborSelfDescribed...)
+ }
+ re.Raw = append(re.Raw, in...)
}
return nil
}
@@ -46,6 +107,35 @@ func (re RawExtension) MarshalJSON() ([]byte, error) {
}
return []byte("null"), nil
}
- // TODO: Check whether ContentType is actually JSON before returning it.
- return re.Raw, nil
+
+ contentType := re.guessContentType()
+ if contentType == ContentTypeJSON {
+ return re.Raw, nil
+ }
+
+ u, err := rawToUnstructured(re.Raw, contentType)
+ if err != nil {
+ return nil, err
+ }
+ return json.Marshal(u)
+}
+
+func (re RawExtension) MarshalCBOR() ([]byte, error) {
+ if re.Raw == nil {
+ if re.Object != nil {
+ return cbor.Marshal(re.Object)
+ }
+ return cbor.Marshal(nil)
+ }
+
+ contentType := re.guessContentType()
+ if contentType == ContentTypeCBOR {
+ return re.Raw, nil
+ }
+
+ u, err := rawToUnstructured(re.Raw, contentType)
+ if err != nil {
+ return nil, err
+ }
+ return cbor.Marshal(u)
}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/generated.pb.go b/vendor/k8s.io/apimachinery/pkg/runtime/generated.pb.go
index ec677a7d9..2e40e140a 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/generated.pb.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/generated.pb.go
@@ -15,7 +15,7 @@ limitations under the License.
*/
// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto
+// source: k8s.io/apimachinery/pkg/runtime/generated.proto
package runtime
@@ -45,7 +45,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func (m *RawExtension) Reset() { *m = RawExtension{} }
func (*RawExtension) ProtoMessage() {}
func (*RawExtension) Descriptor() ([]byte, []int) {
- return fileDescriptor_9d3c45d7f546725c, []int{0}
+ return fileDescriptor_2e0e4b920403a48c, []int{0}
}
func (m *RawExtension) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -73,7 +73,7 @@ var xxx_messageInfo_RawExtension proto.InternalMessageInfo
func (m *TypeMeta) Reset() { *m = TypeMeta{} }
func (*TypeMeta) ProtoMessage() {}
func (*TypeMeta) Descriptor() ([]byte, []int) {
- return fileDescriptor_9d3c45d7f546725c, []int{1}
+ return fileDescriptor_2e0e4b920403a48c, []int{1}
}
func (m *TypeMeta) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -101,7 +101,7 @@ var xxx_messageInfo_TypeMeta proto.InternalMessageInfo
func (m *Unknown) Reset() { *m = Unknown{} }
func (*Unknown) ProtoMessage() {}
func (*Unknown) Descriptor() ([]byte, []int) {
- return fileDescriptor_9d3c45d7f546725c, []int{2}
+ return fileDescriptor_2e0e4b920403a48c, []int{2}
}
func (m *Unknown) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -133,35 +133,34 @@ func init() {
}
func init() {
- proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto", fileDescriptor_9d3c45d7f546725c)
-}
-
-var fileDescriptor_9d3c45d7f546725c = []byte{
- // 380 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xcf, 0xaa, 0x13, 0x31,
- 0x14, 0xc6, 0x27, 0xb7, 0x85, 0x7b, 0x4d, 0x0b, 0x57, 0xe2, 0xc2, 0xd1, 0x45, 0xe6, 0xd2, 0x95,
- 0x77, 0x61, 0x02, 0x17, 0x04, 0xb7, 0x9d, 0x52, 0x50, 0x44, 0x90, 0xe0, 0x1f, 0x70, 0x65, 0x3a,
- 0x13, 0xa7, 0x61, 0xe8, 0xc9, 0x90, 0x66, 0x1c, 0xbb, 0xf3, 0x11, 0x7c, 0xac, 0x2e, 0xbb, 0xec,
- 0xaa, 0xd8, 0xf1, 0x21, 0xdc, 0x4a, 0xd3, 0xb4, 0x56, 0x5d, 0x74, 0x97, 0x73, 0xbe, 0xef, 0xf7,
- 0x9d, 0x73, 0x20, 0xf8, 0x45, 0xf9, 0x7c, 0xce, 0xb4, 0xe1, 0x65, 0x3d, 0x51, 0x16, 0x94, 0x53,
- 0x73, 0xfe, 0x45, 0x41, 0x6e, 0x2c, 0x0f, 0x82, 0xac, 0xf4, 0x4c, 0x66, 0x53, 0x0d, 0xca, 0x2e,
- 0x78, 0x55, 0x16, 0xdc, 0xd6, 0xe0, 0xf4, 0x4c, 0xf1, 0x42, 0x81, 0xb2, 0xd2, 0xa9, 0x9c, 0x55,
- 0xd6, 0x38, 0x43, 0x92, 0x3d, 0xc0, 0x4e, 0x01, 0x56, 0x95, 0x05, 0x0b, 0xc0, 0xe3, 0xa7, 0x85,
- 0x76, 0xd3, 0x7a, 0xc2, 0x32, 0x33, 0xe3, 0x85, 0x29, 0x0c, 0xf7, 0xdc, 0xa4, 0xfe, 0xec, 0x2b,
- 0x5f, 0xf8, 0xd7, 0x3e, 0x6f, 0x70, 0x8b, 0xfb, 0x42, 0x36, 0xe3, 0xaf, 0x4e, 0xc1, 0x5c, 0x1b,
- 0x20, 0x8f, 0x70, 0xc7, 0xca, 0x26, 0x46, 0x37, 0xe8, 0x49, 0x3f, 0xbd, 0x6c, 0x37, 0x49, 0x47,
- 0xc8, 0x46, 0xec, 0x7a, 0x83, 0x4f, 0xf8, 0xea, 0xed, 0xa2, 0x52, 0xaf, 0x95, 0x93, 0xe4, 0x0e,
- 0x63, 0x59, 0xe9, 0xf7, 0xca, 0xee, 0x20, 0xef, 0xbe, 0x97, 0x92, 0xe5, 0x26, 0x89, 0xda, 0x4d,
- 0x82, 0x87, 0x6f, 0x5e, 0x06, 0x45, 0x9c, 0xb8, 0xc8, 0x0d, 0xee, 0x96, 0x1a, 0xf2, 0xf8, 0xc2,
- 0xbb, 0xfb, 0xc1, 0xdd, 0x7d, 0xa5, 0x21, 0x17, 0x5e, 0x19, 0xfc, 0x42, 0xf8, 0xf2, 0x1d, 0x94,
- 0x60, 0x1a, 0x20, 0x1f, 0xf0, 0x95, 0x0b, 0xd3, 0x7c, 0x7e, 0xef, 0xee, 0x96, 0x9d, 0xb9, 0x9d,
- 0x1d, 0xd6, 0x4b, 0xef, 0x87, 0xf0, 0xe3, 0xc2, 0xe2, 0x18, 0x76, 0xb8, 0xf0, 0xe2, 0xff, 0x0b,
- 0xc9, 0x10, 0x5f, 0x67, 0x06, 0x9c, 0x02, 0x37, 0x86, 0xcc, 0xe4, 0x1a, 0x8a, 0xb8, 0xe3, 0x97,
- 0x7d, 0x18, 0xf2, 0xae, 0x47, 0x7f, 0xcb, 0xe2, 0x5f, 0x3f, 0x79, 0x86, 0x7b, 0xa1, 0xb5, 0x1b,
- 0x1d, 0x77, 0x3d, 0xfe, 0x20, 0xe0, 0xbd, 0xd1, 0x1f, 0x49, 0x9c, 0xfa, 0xd2, 0xf1, 0x72, 0x4b,
- 0xa3, 0xd5, 0x96, 0x46, 0xeb, 0x2d, 0x8d, 0xbe, 0xb5, 0x14, 0x2d, 0x5b, 0x8a, 0x56, 0x2d, 0x45,
- 0xeb, 0x96, 0xa2, 0x1f, 0x2d, 0x45, 0xdf, 0x7f, 0xd2, 0xe8, 0x63, 0x72, 0xe6, 0xb7, 0xfc, 0x0e,
- 0x00, 0x00, 0xff, 0xff, 0x1f, 0x32, 0xd5, 0x68, 0x68, 0x02, 0x00, 0x00,
+ proto.RegisterFile("k8s.io/apimachinery/pkg/runtime/generated.proto", fileDescriptor_2e0e4b920403a48c)
+}
+
+var fileDescriptor_2e0e4b920403a48c = []byte{
+ // 365 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0x4f, 0x6b, 0x22, 0x31,
+ 0x18, 0xc6, 0x27, 0x2a, 0xe8, 0x46, 0xc1, 0x25, 0x7b, 0xd8, 0xd9, 0x3d, 0x64, 0xc4, 0xd3, 0x7a,
+ 0xd8, 0x0c, 0x08, 0x85, 0x5e, 0x1d, 0xf1, 0x50, 0x4a, 0xa1, 0x84, 0xfe, 0x81, 0x9e, 0x1a, 0x67,
+ 0xd2, 0x31, 0x0c, 0x26, 0xc3, 0x18, 0x99, 0x7a, 0xeb, 0x47, 0xe8, 0xc7, 0xf2, 0xe8, 0xd1, 0x93,
+ 0xd4, 0xe9, 0x87, 0xe8, 0xb5, 0x18, 0xa3, 0xb5, 0xed, 0xc1, 0x5b, 0xde, 0xf7, 0x79, 0x7e, 0xcf,
+ 0xfb, 0xbe, 0x10, 0xe8, 0x27, 0xa7, 0x13, 0x22, 0x94, 0xcf, 0x52, 0x31, 0x66, 0xe1, 0x48, 0x48,
+ 0x9e, 0xcd, 0xfc, 0x34, 0x89, 0xfd, 0x6c, 0x2a, 0xb5, 0x18, 0x73, 0x3f, 0xe6, 0x92, 0x67, 0x4c,
+ 0xf3, 0x88, 0xa4, 0x99, 0xd2, 0x0a, 0x79, 0x5b, 0x80, 0x1c, 0x02, 0x24, 0x4d, 0x62, 0x62, 0x81,
+ 0xbf, 0xff, 0x63, 0xa1, 0x47, 0xd3, 0x21, 0x09, 0xd5, 0xd8, 0x8f, 0x55, 0xac, 0x7c, 0xc3, 0x0d,
+ 0xa7, 0x0f, 0xa6, 0x32, 0x85, 0x79, 0x6d, 0xf3, 0xda, 0x1d, 0xd8, 0xa0, 0x2c, 0x1f, 0x3c, 0x6a,
+ 0x2e, 0x27, 0x42, 0x49, 0xf4, 0x07, 0x96, 0x33, 0x96, 0xbb, 0xa0, 0x05, 0xfe, 0x35, 0x82, 0x6a,
+ 0xb1, 0xf2, 0xca, 0x94, 0xe5, 0x74, 0xd3, 0x6b, 0xdf, 0xc3, 0xda, 0xd5, 0x2c, 0xe5, 0x17, 0x5c,
+ 0x33, 0xd4, 0x85, 0x90, 0xa5, 0xe2, 0x86, 0x67, 0x1b, 0xc8, 0xb8, 0x7f, 0x04, 0x68, 0xbe, 0xf2,
+ 0x9c, 0x62, 0xe5, 0xc1, 0xde, 0xe5, 0x99, 0x55, 0xe8, 0x81, 0x0b, 0xb5, 0x60, 0x25, 0x11, 0x32,
+ 0x72, 0x4b, 0xc6, 0xdd, 0xb0, 0xee, 0xca, 0xb9, 0x90, 0x11, 0x35, 0x4a, 0xfb, 0x0d, 0xc0, 0xea,
+ 0xb5, 0x4c, 0xa4, 0xca, 0x25, 0xba, 0x85, 0x35, 0x6d, 0xa7, 0x99, 0xfc, 0x7a, 0xb7, 0x43, 0x8e,
+ 0xdc, 0x4e, 0x76, 0xeb, 0x05, 0x3f, 0x6d, 0xf8, 0x7e, 0x61, 0xba, 0x0f, 0xdb, 0x5d, 0x58, 0xfa,
+ 0x7e, 0x21, 0xea, 0xc1, 0x66, 0xa8, 0xa4, 0xe6, 0x52, 0x0f, 0x64, 0xa8, 0x22, 0x21, 0x63, 0xb7,
+ 0x6c, 0x96, 0xfd, 0x6d, 0xf3, 0x9a, 0xfd, 0xcf, 0x32, 0xfd, 0xea, 0x47, 0x27, 0xb0, 0x6e, 0x5b,
+ 0x9b, 0xd1, 0x6e, 0xc5, 0xe0, 0xbf, 0x2c, 0x5e, 0xef, 0x7f, 0x48, 0xf4, 0xd0, 0x17, 0x0c, 0xe6,
+ 0x6b, 0xec, 0x2c, 0xd6, 0xd8, 0x59, 0xae, 0xb1, 0xf3, 0x54, 0x60, 0x30, 0x2f, 0x30, 0x58, 0x14,
+ 0x18, 0x2c, 0x0b, 0x0c, 0x5e, 0x0a, 0x0c, 0x9e, 0x5f, 0xb1, 0x73, 0xe7, 0x1d, 0xf9, 0x2d, 0xef,
+ 0x01, 0x00, 0x00, 0xff, 0xff, 0x2a, 0x9b, 0x09, 0xb3, 0x4f, 0x02, 0x00, 0x00,
}
func (m *RawExtension) Marshal() (dAtA []byte, err error) {
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/helper.go b/vendor/k8s.io/apimachinery/pkg/runtime/helper.go
index 7bd1a3a6a..395dfdbd0 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/helper.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/helper.go
@@ -236,10 +236,14 @@ func (e WithVersionEncoder) Encode(obj Object, stream io.Writer) error {
gvk = preferredGVK
}
}
- kind.SetGroupVersionKind(gvk)
- err = e.Encoder.Encode(obj, stream)
- kind.SetGroupVersionKind(oldGVK)
- return err
+
+ // The gvk only needs to be set if not already as desired.
+ if gvk != oldGVK {
+ kind.SetGroupVersionKind(gvk)
+ defer kind.SetGroupVersionKind(oldGVK)
+ }
+
+ return e.Encoder.Encode(obj, stream)
}
// WithoutVersionDecoder clears the group version kind of a deserialized object.
@@ -257,3 +261,44 @@ func (d WithoutVersionDecoder) Decode(data []byte, defaults *schema.GroupVersion
}
return obj, gvk, err
}
+
+type encoderWithAllocator struct {
+ encoder EncoderWithAllocator
+ memAllocator MemoryAllocator
+}
+
+// NewEncoderWithAllocator returns a new encoder
+func NewEncoderWithAllocator(e EncoderWithAllocator, a MemoryAllocator) Encoder {
+ return &encoderWithAllocator{
+ encoder: e,
+ memAllocator: a,
+ }
+}
+
+// Encode writes the provided object to the nested writer
+func (e *encoderWithAllocator) Encode(obj Object, w io.Writer) error {
+ return e.encoder.EncodeWithAllocator(obj, w, e.memAllocator)
+}
+
+// Identifier returns identifier of this encoder.
+func (e *encoderWithAllocator) Identifier() Identifier {
+ return e.encoder.Identifier()
+}
+
+type nondeterministicEncoderToEncoderAdapter struct {
+ NondeterministicEncoder
+}
+
+func (e nondeterministicEncoderToEncoderAdapter) Encode(obj Object, w io.Writer) error {
+ return e.EncodeNondeterministic(obj, w)
+}
+
+// UseNondeterministicEncoding returns an Encoder that encodes objects using the provided Encoder's
+// EncodeNondeterministic method if it implements NondeterministicEncoder, otherwise it returns the
+// provided Encoder as-is.
+func UseNondeterministicEncoding(encoder Encoder) Encoder {
+ if nondeterministic, ok := encoder.(NondeterministicEncoder); ok {
+ return nondeterministicEncoderToEncoderAdapter{nondeterministic}
+ }
+ return encoder
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/interfaces.go b/vendor/k8s.io/apimachinery/pkg/runtime/interfaces.go
index 710a97795..2703300cd 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/interfaces.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/interfaces.go
@@ -69,6 +69,19 @@ type Encoder interface {
Identifier() Identifier
}
+// NondeterministicEncoder is implemented by Encoders that can serialize objects more efficiently in
+// cases where the output does not need to be deterministic.
+type NondeterministicEncoder interface {
+ Encoder
+
+ // EncodeNondeterministic writes an object to the stream. Unlike the Encode method of
+ // Encoder, EncodeNondeterministic does not guarantee that any two invocations will write
+ // the same sequence of bytes to the io.Writer. Any differences will not be significant to a
+ // generic decoder. For example, map entries and struct fields might be encoded in any
+ // order.
+ EncodeNondeterministic(Object, io.Writer) error
+}
+
// MemoryAllocator is responsible for allocating memory.
// By encapsulating memory allocation into its own interface, we can reuse the memory
// across many operations in places we know it can significantly improve the performance.
@@ -365,4 +378,9 @@ type Unstructured interface {
// error should terminate the iteration. If IsList() returns false, this method should return an error
// instead of calling the provided function.
EachListItem(func(Object) error) error
+ // EachListItemWithAlloc works like EachListItem, but avoids retaining references to a slice of items.
+ // It does this by making a shallow copy of non-pointer items before passing them to fn.
+ //
+ // If the items passed to fn are not retained, or are retained for the same duration, use EachListItem instead for memory efficiency.
+ EachListItemWithAlloc(func(Object) error) error
}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.pb.go b/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.pb.go
index 46b1e787b..7a26d2798 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.pb.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.pb.go
@@ -15,7 +15,7 @@ limitations under the License.
*/
// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto
+// source: k8s.io/apimachinery/pkg/runtime/schema/generated.proto
package schema
@@ -39,21 +39,20 @@ var _ = math.Inf
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func init() {
- proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto", fileDescriptor_0462724132518e0d)
+ proto.RegisterFile("k8s.io/apimachinery/pkg/runtime/schema/generated.proto", fileDescriptor_25f8f0eed21c6089)
}
-var fileDescriptor_0462724132518e0d = []byte{
- // 186 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0xce, 0xad, 0x8e, 0xc3, 0x30,
- 0x0c, 0xc0, 0xf1, 0x84, 0x1e, 0x3c, 0x78, 0xc0, 0xb0, 0xec, 0x62, 0x7a, 0xf8, 0xf0, 0xa4, 0xf1,
- 0xb1, 0xb4, 0xf5, 0xd2, 0x28, 0xca, 0x87, 0xd2, 0x64, 0xd2, 0xd8, 0x1e, 0x61, 0x8f, 0x55, 0x58,
- 0x58, 0xb8, 0x66, 0x2f, 0x32, 0x29, 0x2d, 0x18, 0x1c, 0xf3, 0x5f, 0xd6, 0xcf, 0xf2, 0xd7, 0xd1,
- 0xfc, 0x8d, 0x42, 0x7b, 0x34, 0xb9, 0xa5, 0xe8, 0x28, 0xd1, 0x88, 0x17, 0x72, 0xbd, 0x8f, 0xb8,
- 0x2f, 0x64, 0xd0, 0x56, 0x76, 0x83, 0x76, 0x14, 0xaf, 0x18, 0x8c, 0xc2, 0x98, 0x5d, 0xd2, 0x96,
- 0x70, 0xec, 0x06, 0xb2, 0x12, 0x15, 0x39, 0x8a, 0x32, 0x51, 0x2f, 0x42, 0xf4, 0xc9, 0x7f, 0x37,
- 0x9b, 0x13, 0xef, 0x4e, 0x04, 0xa3, 0xc4, 0xee, 0xc4, 0xe6, 0x7e, 0x7e, 0x95, 0x4e, 0x43, 0x6e,
- 0x45, 0xe7, 0x2d, 0x2a, 0xaf, 0x3c, 0x56, 0xde, 0xe6, 0x73, 0xad, 0x1a, 0x75, 0xda, 0xce, 0xfe,
- 0x1f, 0xa6, 0x15, 0xd8, 0xbc, 0x02, 0x5b, 0x56, 0x60, 0xb7, 0x02, 0x7c, 0x2a, 0xc0, 0xe7, 0x02,
- 0x7c, 0x29, 0xc0, 0x1f, 0x05, 0xf8, 0xfd, 0x09, 0xec, 0xd4, 0x7c, 0xf6, 0xf4, 0x2b, 0x00, 0x00,
- 0xff, 0xff, 0x12, 0xb4, 0xae, 0x48, 0xf6, 0x00, 0x00, 0x00,
+var fileDescriptor_25f8f0eed21c6089 = []byte{
+ // 170 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0xce, 0xa1, 0x0e, 0xc2, 0x30,
+ 0x10, 0xc6, 0xf1, 0xd6, 0x22, 0x91, 0x88, 0x93, 0x73, 0xdc, 0x39, 0x82, 0x46, 0xf3, 0x04, 0xb8,
+ 0x6e, 0x94, 0xae, 0x59, 0xba, 0x6b, 0xba, 0x4e, 0xe0, 0x78, 0x04, 0x1e, 0x6b, 0x72, 0x72, 0x92,
+ 0x95, 0x17, 0x21, 0x69, 0x11, 0x48, 0xdc, 0xfd, 0xc5, 0xef, 0xf2, 0x6d, 0x0e, 0xdd, 0x71, 0x40,
+ 0xcb, 0xa4, 0xbc, 0x75, 0xaa, 0x69, 0x6d, 0xaf, 0xc3, 0x9d, 0x7c, 0x67, 0x28, 0x8c, 0x7d, 0xb4,
+ 0x4e, 0xd3, 0xd0, 0xb4, 0xda, 0x29, 0x32, 0xba, 0xd7, 0x41, 0x45, 0x7d, 0x45, 0x1f, 0x38, 0xf2,
+ 0xb6, 0x2a, 0x0e, 0x7f, 0x1d, 0xfa, 0xce, 0xe0, 0xd7, 0x61, 0x71, 0xbb, 0xbd, 0xb1, 0xb1, 0x1d,
+ 0x6b, 0x6c, 0xd8, 0x91, 0x61, 0xc3, 0x94, 0x79, 0x3d, 0xde, 0x72, 0xe5, 0xc8, 0x57, 0x79, 0x7b,
+ 0x3a, 0x4f, 0x2b, 0x88, 0x79, 0x05, 0xb1, 0xac, 0x20, 0x1e, 0x09, 0xe4, 0x94, 0x40, 0xce, 0x09,
+ 0xe4, 0x92, 0x40, 0xbe, 0x12, 0xc8, 0xe7, 0x1b, 0xc4, 0xa5, 0xfa, 0x6f, 0xf4, 0x27, 0x00, 0x00,
+ 0xff, 0xff, 0x97, 0xb8, 0x4d, 0x1f, 0xdd, 0x00, 0x00, 0x00,
}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go b/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go
index b21eb664e..d1c37c942 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go
@@ -39,7 +39,7 @@ func ParseResourceArg(arg string) (*GroupVersionResource, GroupResource) {
// ParseKindArg takes the common style of string which may be either `Kind.group.com` or `Kind.version.group.com`
// and parses it out into both possibilities. This code takes no responsibility for knowing which representation was intended
// but with a knowledge of all GroupKinds, calling code can take a very good guess. If there are only two segments, then
-// `*GroupVersionResource` is nil.
+// `*GroupVersionKind` is nil.
// `Kind.group.com` -> `group=com, version=group, kind=Kind` and `group=group.com, kind=Kind`
func ParseKindArg(arg string) (*GroupVersionKind, GroupKind) {
var gvk *GroupVersionKind
@@ -191,8 +191,7 @@ func (gv GroupVersion) Identifier() string {
// if none of the options match the group. It prefers a match to group and version over just group.
// TODO: Move GroupVersion to a package under pkg/runtime, since it's used by scheme.
// TODO: Introduce an adapter type between GroupVersion and runtime.GroupVersioner, and use LegacyCodec(GroupVersion)
-//
-// in fewer places.
+// in fewer places.
func (gv GroupVersion) KindForGroupVersionKinds(kinds []GroupVersionKind) (target GroupVersionKind, ok bool) {
for _, gvk := range kinds {
if gvk.Group == gv.Group && gvk.Version == gv.Version {
@@ -240,8 +239,7 @@ func (gv GroupVersion) WithResource(resource string) GroupVersionResource {
// GroupVersions can be used to represent a set of desired group versions.
// TODO: Move GroupVersions to a package under pkg/runtime, since it's used by scheme.
// TODO: Introduce an adapter type between GroupVersions and runtime.GroupVersioner, and use LegacyCodec(GroupVersion)
-//
-// in fewer places.
+// in fewer places.
type GroupVersions []GroupVersion
// Identifier implements runtime.GroupVersioner interface.
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go b/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
index 18b25a994..a5b116718 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
@@ -118,8 +118,7 @@ func (s *Scheme) Converter() *conversion.Converter {
// API group and version that would never be updated.
//
// TODO: there is discussion about removing unversioned and replacing it with objects that are manifest into
-//
-// every version with particular schemas. Resolve this method at that point.
+// every version with particular schemas. Resolve this method at that point.
func (s *Scheme) AddUnversionedTypes(version schema.GroupVersion, types ...Object) {
s.addObservedVersion(version)
s.AddKnownTypes(version, types...)
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct/direct.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct/direct.go
new file mode 100644
index 000000000..a71a487f9
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct/direct.go
@@ -0,0 +1,61 @@
+/*
+Copyright 2024 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 direct provides functions for marshaling and unmarshaling between arbitrary Go values and
+// CBOR data, with behavior that is compatible with that of the CBOR serializer. In particular,
+// types that implement cbor.Marshaler and cbor.Unmarshaler should use these functions.
+package direct
+
+import (
+ "k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes"
+)
+
+// Marshal serializes a value to CBOR. If there is more than one way to encode the value, it will
+// make the same choice as the CBOR implementation of runtime.Serializer.
+//
+// Note: Support for CBOR is at an alpha stage. If the value (or, for composite types, any of its
+// nested values) implement any of the interfaces encoding.TextMarshaler, encoding.TextUnmarshaler,
+// encoding/json.Marshaler, or encoding/json.Unmarshaler, a non-nil error will be returned unless
+// the value also implements the corresponding CBOR interfaces. This limitation will ultimately be
+// removed in favor of automatic transcoding to CBOR.
+func Marshal(src interface{}) ([]byte, error) {
+ if err := modes.RejectCustomMarshalers(src); err != nil {
+ return nil, err
+ }
+ return modes.Encode.Marshal(src)
+}
+
+// Unmarshal deserializes from CBOR into an addressable value. If there is more than one way to
+// unmarshal a value, it will make the same choice as the CBOR implementation of runtime.Serializer.
+//
+// Note: Support for CBOR is at an alpha stage. If the value (or, for composite types, any of its
+// nested values) implement any of the interfaces encoding.TextMarshaler, encoding.TextUnmarshaler,
+// encoding/json.Marshaler, or encoding/json.Unmarshaler, a non-nil error will be returned unless
+// the value also implements the corresponding CBOR interfaces. This limitation will ultimately be
+// removed in favor of automatic transcoding to CBOR.
+func Unmarshal(src []byte, dst interface{}) error {
+ if err := modes.RejectCustomMarshalers(dst); err != nil {
+ return err
+ }
+ return modes.Decode.Unmarshal(src, dst)
+}
+
+// Diagnose accepts well-formed CBOR bytes and returns a string representing the same data item in
+// human-readable diagnostic notation (RFC 8949 Section 8). The diagnostic notation is not meant to
+// be parsed.
+func Diagnose(src []byte) (string, error) {
+ return modes.Diagnostic.Diagnose(src)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/buffers.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/buffers.go
new file mode 100644
index 000000000..f14cbd6b5
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/buffers.go
@@ -0,0 +1,65 @@
+/*
+Copyright 2024 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 modes
+
+import (
+ "bytes"
+ "sync"
+)
+
+var buffers = BufferProvider{p: new(sync.Pool)}
+
+type buffer struct {
+ bytes.Buffer
+}
+
+type pool interface {
+ Get() interface{}
+ Put(interface{})
+}
+
+type BufferProvider struct {
+ p pool
+}
+
+func (b *BufferProvider) Get() *buffer {
+ if buf, ok := b.p.Get().(*buffer); ok {
+ return buf
+ }
+ return &buffer{}
+}
+
+func (b *BufferProvider) Put(buf *buffer) {
+ if buf.Cap() > 3*1024*1024 /* Default MaxRequestBodyBytes */ {
+ // Objects in a sync.Pool are assumed to be fungible. This is not a good assumption
+ // for pools of *bytes.Buffer because a *bytes.Buffer's underlying array grows as
+ // needed to accommodate writes. In Kubernetes, apiservers tend to encode "small"
+ // objects very frequently and much larger objects (especially large lists) only
+ // occasionally. Under steady load, pooled buffers tend to be borrowed frequently
+ // enough to prevent them from being released. Over time, each buffer is used to
+ // encode a large object and its capacity increases accordingly. The result is that
+ // practically all buffers in the pool retain much more capacity than needed to
+ // encode most objects.
+
+ // As a basic mitigation for the worst case, buffers with more capacity than the
+ // default max request body size are never returned to the pool.
+ // TODO: Optimize for higher buffer utilization.
+ return
+ }
+ buf.Reset()
+ b.p.Put(buf)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/custom.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/custom.go
new file mode 100644
index 000000000..858529e95
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/custom.go
@@ -0,0 +1,422 @@
+/*
+Copyright 2024 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 modes
+
+import (
+ "encoding"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "reflect"
+ "sync"
+
+ "github.com/fxamacker/cbor/v2"
+)
+
+// Returns a non-nil error if and only if the argument's type (or one of its component types, for
+// composite types) implements json.Marshaler or encoding.TextMarshaler without also implementing
+// cbor.Marshaler and likewise for the respective Unmarshaler interfaces.
+//
+// This is a temporary, graduation-blocking restriction and will be removed in favor of automatic
+// transcoding between CBOR and JSON/text for these types. This restriction allows CBOR to be
+// exercised for in-tree and unstructured types while mitigating the risk of mangling out-of-tree
+// types in client programs.
+func RejectCustomMarshalers(v interface{}) error {
+ if v == nil {
+ return nil
+ }
+ rv := reflect.ValueOf(v)
+ if err := marshalerCache.getChecker(rv.Type()).check(rv, maxDepth); err != nil {
+ return fmt.Errorf("unable to serialize %T: %w", v, err)
+ }
+ if err := unmarshalerCache.getChecker(rv.Type()).check(rv, maxDepth); err != nil {
+ return fmt.Errorf("unable to serialize %T: %w", v, err)
+ }
+ return nil
+}
+
+// Recursion depth is limited as a basic mitigation against cyclic objects. Objects created by the
+// decoder shouldn't be able to contain cycles, but practically any object can be passed to the
+// encoder.
+var errMaxDepthExceeded = errors.New("object depth exceeds limit (possible cycle?)")
+
+// The JSON encoder begins detecting cycles after depth 1000. Use a generous limit here, knowing
+// that it can might deeply nested acyclic objects. The limit will be removed along with the rest of
+// this mechanism.
+const maxDepth = 2048
+
+var marshalerCache = checkers{
+ cborInterface: reflect.TypeFor[cbor.Marshaler](),
+ nonCBORInterfaces: []reflect.Type{
+ reflect.TypeFor[json.Marshaler](),
+ reflect.TypeFor[encoding.TextMarshaler](),
+ },
+}
+
+var unmarshalerCache = checkers{
+ cborInterface: reflect.TypeFor[cbor.Unmarshaler](),
+ nonCBORInterfaces: []reflect.Type{
+ reflect.TypeFor[json.Unmarshaler](),
+ reflect.TypeFor[encoding.TextUnmarshaler](),
+ },
+ assumeAddressableValues: true,
+}
+
+// checker wraps a function for dynamically checking a value of a specific type for custom JSON
+// behaviors not matched by a custom CBOR behavior.
+type checker struct {
+ // check returns a non-nil error if the given value might be marshalled to or from CBOR
+ // using the default behavior for its kind, but marshalled to or from JSON using custom
+ // behavior.
+ check func(rv reflect.Value, depth int) error
+
+ // safe returns true if all values of this type are safe from mismatched custom marshalers.
+ safe func() bool
+}
+
+// TODO: stale
+// Having a single addressable checker for comparisons lets us prune and collapse parts of the
+// object traversal that are statically known to be safe. Depending on the type, it may be
+// unnecessary to inspect each value of that type. For example, no value of the built-in type bool
+// can implement json.Marshaler (a named type whose underlying type is bool could, but it is a
+// distinct type from bool).
+var noop = checker{
+ safe: func() bool {
+ return true
+ },
+ check: func(rv reflect.Value, depth int) error {
+ return nil
+ },
+}
+
+type checkers struct {
+ m sync.Map // reflect.Type => *checker
+
+ cborInterface reflect.Type
+ nonCBORInterfaces []reflect.Type
+
+ assumeAddressableValues bool
+}
+
+func (cache *checkers) getChecker(rt reflect.Type) checker {
+ if ptr, ok := cache.m.Load(rt); ok {
+ return *ptr.(*checker)
+ }
+
+ return cache.getCheckerInternal(rt, nil)
+}
+
+// linked list node representing the path from a composite type to an element type
+type path struct {
+ Type reflect.Type
+ Parent *path
+}
+
+func (p path) cyclic(rt reflect.Type) bool {
+ for ancestor := &p; ancestor != nil; ancestor = ancestor.Parent {
+ if ancestor.Type == rt {
+ return true
+ }
+ }
+ return false
+}
+
+func (cache *checkers) getCheckerInternal(rt reflect.Type, parent *path) (c checker) {
+ // Store a placeholder cache entry first to handle cyclic types.
+ var wg sync.WaitGroup
+ wg.Add(1)
+ defer wg.Done()
+ c = checker{
+ safe: func() bool {
+ wg.Wait()
+ return c.safe()
+ },
+ check: func(rv reflect.Value, depth int) error {
+ wg.Wait()
+ return c.check(rv, depth)
+ },
+ }
+ if actual, loaded := cache.m.LoadOrStore(rt, &c); loaded {
+ // Someone else stored an entry for this type, use it.
+ return *actual.(*checker)
+ }
+
+ // Take a nonreflective path for the unstructured container types. They're common and
+ // usually nested inside one another.
+ switch rt {
+ case reflect.TypeFor[map[string]interface{}](), reflect.TypeFor[[]interface{}]():
+ return checker{
+ safe: func() bool {
+ return false
+ },
+ check: func(rv reflect.Value, depth int) error {
+ return checkUnstructuredValue(cache, rv.Interface(), depth)
+ },
+ }
+ }
+
+ // It's possible that one of the relevant interfaces is implemented on a type with a pointer
+ // receiver, but that a particular value of that type is not addressable. For example:
+ //
+ // func (Foo) MarshalText() ([]byte, error) { ... }
+ // func (*Foo) MarshalCBOR() ([]byte, error) { ... }
+ //
+ // Both methods are in the method set of *Foo, but the method set of Foo contains only
+ // MarshalText.
+ //
+ // Both the unmarshaler and marshaler checks assume that methods implementing a JSON or text
+ // interface with a pointer receiver are always accessible. Only the unmarshaler check
+ // assumes that CBOR methods with pointer receivers are accessible.
+
+ if rt.Implements(cache.cborInterface) {
+ return noop
+ }
+ for _, unsafe := range cache.nonCBORInterfaces {
+ if rt.Implements(unsafe) {
+ err := fmt.Errorf("%v implements %v without corresponding cbor interface", rt, unsafe)
+ return checker{
+ safe: func() bool {
+ return false
+ },
+ check: func(reflect.Value, int) error {
+ return err
+ },
+ }
+ }
+ }
+
+ if cache.assumeAddressableValues && reflect.PointerTo(rt).Implements(cache.cborInterface) {
+ return noop
+ }
+ for _, unsafe := range cache.nonCBORInterfaces {
+ if reflect.PointerTo(rt).Implements(unsafe) {
+ err := fmt.Errorf("%v implements %v without corresponding cbor interface", reflect.PointerTo(rt), unsafe)
+ return checker{
+ safe: func() bool {
+ return false
+ },
+ check: func(reflect.Value, int) error {
+ return err
+ },
+ }
+ }
+ }
+
+ self := &path{Type: rt, Parent: parent}
+
+ switch rt.Kind() {
+ case reflect.Array:
+ ce := cache.getCheckerInternal(rt.Elem(), self)
+ rtlen := rt.Len()
+ if rtlen == 0 || (!self.cyclic(rt.Elem()) && ce.safe()) {
+ return noop
+ }
+ return checker{
+ safe: func() bool {
+ return false
+ },
+ check: func(rv reflect.Value, depth int) error {
+ if depth <= 0 {
+ return errMaxDepthExceeded
+ }
+ for i := 0; i < rtlen; i++ {
+ if err := ce.check(rv.Index(i), depth-1); err != nil {
+ return err
+ }
+ }
+ return nil
+ },
+ }
+
+ case reflect.Interface:
+ // All interface values have to be checked because their dynamic type might
+ // implement one of the interesting interfaces or be composed of another type that
+ // does.
+ return checker{
+ safe: func() bool {
+ return false
+ },
+ check: func(rv reflect.Value, depth int) error {
+ if rv.IsNil() {
+ return nil
+ }
+ // Unpacking interfaces must count against recursion depth,
+ // consider this cycle:
+ // > var i interface{}
+ // > var p *interface{} = &i
+ // > i = p
+ // > rv := reflect.ValueOf(i)
+ // > for {
+ // > rv = rv.Elem()
+ // > }
+ if depth <= 0 {
+ return errMaxDepthExceeded
+ }
+ rv = rv.Elem()
+ return cache.getChecker(rv.Type()).check(rv, depth-1)
+ },
+ }
+
+ case reflect.Map:
+ rtk := rt.Key()
+ ck := cache.getCheckerInternal(rtk, self)
+ rte := rt.Elem()
+ ce := cache.getCheckerInternal(rte, self)
+ if !self.cyclic(rtk) && !self.cyclic(rte) && ck.safe() && ce.safe() {
+ return noop
+ }
+ return checker{
+ safe: func() bool {
+ return false
+ },
+ check: func(rv reflect.Value, depth int) error {
+ if depth <= 0 {
+ return errMaxDepthExceeded
+ }
+ iter := rv.MapRange()
+ rvk := reflect.New(rtk).Elem()
+ rve := reflect.New(rte).Elem()
+ for iter.Next() {
+ rvk.SetIterKey(iter)
+ if err := ck.check(rvk, depth-1); err != nil {
+ return err
+ }
+ rve.SetIterValue(iter)
+ if err := ce.check(rve, depth-1); err != nil {
+ return err
+ }
+ }
+ return nil
+ },
+ }
+
+ case reflect.Pointer:
+ ce := cache.getCheckerInternal(rt.Elem(), self)
+ if !self.cyclic(rt.Elem()) && ce.safe() {
+ return noop
+ }
+ return checker{
+ safe: func() bool {
+ return false
+ },
+ check: func(rv reflect.Value, depth int) error {
+ if rv.IsNil() {
+ return nil
+ }
+ if depth <= 0 {
+ return errMaxDepthExceeded
+ }
+ return ce.check(rv.Elem(), depth-1)
+ },
+ }
+
+ case reflect.Slice:
+ ce := cache.getCheckerInternal(rt.Elem(), self)
+ if !self.cyclic(rt.Elem()) && ce.safe() {
+ return noop
+ }
+ return checker{
+ safe: func() bool {
+ return false
+ },
+ check: func(rv reflect.Value, depth int) error {
+ if depth <= 0 {
+ return errMaxDepthExceeded
+ }
+ for i := 0; i < rv.Len(); i++ {
+ if err := ce.check(rv.Index(i), depth-1); err != nil {
+ return err
+ }
+ }
+ return nil
+ },
+ }
+
+ case reflect.Struct:
+ type field struct {
+ Index int
+ Checker checker
+ }
+ var fields []field
+ for i := 0; i < rt.NumField(); i++ {
+ f := rt.Field(i)
+ cf := cache.getCheckerInternal(f.Type, self)
+ if !self.cyclic(f.Type) && cf.safe() {
+ continue
+ }
+ fields = append(fields, field{Index: i, Checker: cf})
+ }
+ if len(fields) == 0 {
+ return noop
+ }
+ return checker{
+ safe: func() bool {
+ return false
+ },
+ check: func(rv reflect.Value, depth int) error {
+ if depth <= 0 {
+ return errMaxDepthExceeded
+ }
+ for _, fi := range fields {
+ if err := fi.Checker.check(rv.Field(fi.Index), depth-1); err != nil {
+ return err
+ }
+ }
+ return nil
+ },
+ }
+
+ default:
+ // Not a serializable composite type (funcs and channels are composite types but are
+ // rejected by JSON and CBOR serialization).
+ return noop
+
+ }
+}
+
+func checkUnstructuredValue(cache *checkers, v interface{}, depth int) error {
+ switch v := v.(type) {
+ case nil, bool, int64, float64, string:
+ return nil
+ case []interface{}:
+ if depth <= 0 {
+ return errMaxDepthExceeded
+ }
+ for _, element := range v {
+ if err := checkUnstructuredValue(cache, element, depth-1); err != nil {
+ return err
+ }
+ }
+ return nil
+ case map[string]interface{}:
+ if depth <= 0 {
+ return errMaxDepthExceeded
+ }
+ for _, element := range v {
+ if err := checkUnstructuredValue(cache, element, depth-1); err != nil {
+ return err
+ }
+ }
+ return nil
+ default:
+ // Unmarshaling an unstructured doesn't use other dynamic types, but nothing
+ // prevents inserting values with arbitrary dynamic types into unstructured content,
+ // as long as they can be marshalled.
+ rv := reflect.ValueOf(v)
+ return cache.getChecker(rv.Type()).check(rv, depth)
+ }
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/decode.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/decode.go
new file mode 100644
index 000000000..895b0deff
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/decode.go
@@ -0,0 +1,158 @@
+/*
+Copyright 2024 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 modes
+
+import (
+ "reflect"
+
+ "github.com/fxamacker/cbor/v2"
+)
+
+var simpleValues *cbor.SimpleValueRegistry = func() *cbor.SimpleValueRegistry {
+ var opts []func(*cbor.SimpleValueRegistry) error
+ for sv := 0; sv <= 255; sv++ {
+ // Reject simple values 0-19, 23, and 32-255. The simple values 24-31 are reserved
+ // and considered ill-formed by the CBOR specification. We only accept false (20),
+ // true (21), and null (22).
+ switch sv {
+ case 20: // false
+ case 21: // true
+ case 22: // null
+ case 24, 25, 26, 27, 28, 29, 30, 31: // reserved
+ default:
+ opts = append(opts, cbor.WithRejectedSimpleValue(cbor.SimpleValue(sv)))
+ }
+ }
+ simpleValues, err := cbor.NewSimpleValueRegistryFromDefaults(opts...)
+ if err != nil {
+ panic(err)
+ }
+ return simpleValues
+}()
+
+var Decode cbor.DecMode = func() cbor.DecMode {
+ decode, err := cbor.DecOptions{
+ // Maps with duplicate keys are well-formed but invalid according to the CBOR spec
+ // and never acceptable. Unlike the JSON serializer, inputs containing duplicate map
+ // keys are rejected outright and not surfaced as a strict decoding error.
+ DupMapKey: cbor.DupMapKeyEnforcedAPF,
+
+ // For JSON parity, decoding an RFC3339 string into time.Time needs to be accepted
+ // with or without tagging. If a tag number is present, it must be valid.
+ TimeTag: cbor.DecTagOptional,
+
+ // Observed depth up to 16 in fuzzed batch/v1 CronJobList. JSON implementation limit
+ // is 10000.
+ MaxNestedLevels: 64,
+
+ MaxArrayElements: 1024,
+ MaxMapPairs: 1024,
+
+ // Indefinite-length sequences aren't produced by this serializer, but other
+ // implementations can.
+ IndefLength: cbor.IndefLengthAllowed,
+
+ // Accept inputs that contain CBOR tags.
+ TagsMd: cbor.TagsAllowed,
+
+ // Decode type 0 (unsigned integer) as int64.
+ // TODO: IntDecConvertSignedOrFail errors on overflow, JSON will try to fall back to float64.
+ IntDec: cbor.IntDecConvertSignedOrFail,
+
+ // Disable producing map[cbor.ByteString]interface{}, which is not acceptable for
+ // decodes into interface{}.
+ MapKeyByteString: cbor.MapKeyByteStringForbidden,
+
+ // Error on map keys that don't map to a field in the destination struct.
+ ExtraReturnErrors: cbor.ExtraDecErrorUnknownField,
+
+ // Decode maps into concrete type map[string]interface{} when the destination is an
+ // interface{}.
+ DefaultMapType: reflect.TypeOf(map[string]interface{}(nil)),
+
+ // A CBOR text string whose content is not a valid UTF-8 sequence is well-formed but
+ // invalid according to the CBOR spec. Reject invalid inputs. Encoders are
+ // responsible for ensuring that all text strings they produce contain valid UTF-8
+ // sequences and may use the byte string major type to encode strings that have not
+ // been validated.
+ UTF8: cbor.UTF8RejectInvalid,
+
+ // Never make a case-insensitive match between a map key and a struct field.
+ FieldNameMatching: cbor.FieldNameMatchingCaseSensitive,
+
+ // Produce string concrete values when decoding a CBOR byte string into interface{}.
+ DefaultByteStringType: reflect.TypeOf(""),
+
+ // Allow CBOR byte strings to be decoded into string destination values. If a byte
+ // string is enclosed in an "expected later encoding" tag
+ // (https://www.rfc-editor.org/rfc/rfc8949.html#section-3.4.5.2), then the text
+ // encoding indicated by that tag (e.g. base64) will be applied to the contents of
+ // the byte string.
+ ByteStringToString: cbor.ByteStringToStringAllowedWithExpectedLaterEncoding,
+
+ // Allow CBOR byte strings to match struct fields when appearing as a map key.
+ FieldNameByteString: cbor.FieldNameByteStringAllowed,
+
+ // When decoding an unrecognized tag to interface{}, return the decoded tag content
+ // instead of the default, a cbor.Tag representing a (number, content) pair.
+ UnrecognizedTagToAny: cbor.UnrecognizedTagContentToAny,
+
+ // Decode time tags to interface{} as strings containing RFC 3339 timestamps.
+ TimeTagToAny: cbor.TimeTagToRFC3339Nano,
+
+ // For parity with JSON, strings can be decoded into time.Time if they are RFC 3339
+ // timestamps.
+ ByteStringToTime: cbor.ByteStringToTimeAllowed,
+
+ // Reject NaN and infinite floating-point values since they don't have a JSON
+ // representation (RFC 8259 Section 6).
+ NaN: cbor.NaNDecodeForbidden,
+ Inf: cbor.InfDecodeForbidden,
+
+ // When unmarshaling a byte string into a []byte, assume that the byte string
+ // contains base64-encoded bytes, unless explicitly counterindicated by an "expected
+ // later encoding" tag. This is consistent with the because of unmarshaling a JSON
+ // text into a []byte.
+ ByteStringExpectedFormat: cbor.ByteStringExpectedBase64,
+
+ // Reject the arbitrary-precision integer tags because they can't be faithfully
+ // roundtripped through the allowable Unstructured types.
+ BignumTag: cbor.BignumTagForbidden,
+
+ // Reject anything other than the simple values true, false, and null.
+ SimpleValues: simpleValues,
+
+ // Disable default recognition of types implementing encoding.BinaryUnmarshaler,
+ // which is not recognized for JSON decoding.
+ BinaryUnmarshaler: cbor.BinaryUnmarshalerNone,
+ }.DecMode()
+ if err != nil {
+ panic(err)
+ }
+ return decode
+}()
+
+// DecodeLax is derived from Decode, but does not complain about unknown fields in the input.
+var DecodeLax cbor.DecMode = func() cbor.DecMode {
+ opts := Decode.DecOptions()
+ opts.ExtraReturnErrors &^= cbor.ExtraDecErrorUnknownField // clear bit
+ dm, err := opts.DecMode()
+ if err != nil {
+ panic(err)
+ }
+ return dm
+}()
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/diagnostic.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/diagnostic.go
new file mode 100644
index 000000000..61f3f145f
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/diagnostic.go
@@ -0,0 +1,36 @@
+/*
+Copyright 2024 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 modes
+
+import (
+ "github.com/fxamacker/cbor/v2"
+)
+
+var Diagnostic cbor.DiagMode = func() cbor.DiagMode {
+ opts := Decode.DecOptions()
+ diagnostic, err := cbor.DiagOptions{
+ ByteStringText: true,
+
+ MaxNestedLevels: opts.MaxNestedLevels,
+ MaxArrayElements: opts.MaxArrayElements,
+ MaxMapPairs: opts.MaxMapPairs,
+ }.DiagMode()
+ if err != nil {
+ panic(err)
+ }
+ return diagnostic
+}()
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go
new file mode 100644
index 000000000..5fae14151
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go
@@ -0,0 +1,155 @@
+/*
+Copyright 2024 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 modes
+
+import (
+ "io"
+
+ "github.com/fxamacker/cbor/v2"
+)
+
+var Encode = EncMode{
+ delegate: func() cbor.UserBufferEncMode {
+ encode, err := cbor.EncOptions{
+ // Map keys need to be sorted to have deterministic output, and this is the order
+ // defined in RFC 8949 4.2.1 "Core Deterministic Encoding Requirements".
+ Sort: cbor.SortBytewiseLexical,
+
+ // CBOR supports distinct types for IEEE-754 float16, float32, and float64. Store
+ // floats in the smallest width that preserves value so that equivalent float32 and
+ // float64 values encode to identical bytes, as they do in a JSON
+ // encoding. Satisfies one of the "Core Deterministic Encoding Requirements".
+ ShortestFloat: cbor.ShortestFloat16,
+
+ // Error on attempt to encode NaN and infinite values. This is what the JSON
+ // serializer does.
+ NaNConvert: cbor.NaNConvertReject,
+ InfConvert: cbor.InfConvertReject,
+
+ // Error on attempt to encode math/big.Int values, which can't be faithfully
+ // roundtripped through Unstructured in general (the dynamic numeric types allowed
+ // in Unstructured are limited to float64 and int64).
+ BigIntConvert: cbor.BigIntConvertReject,
+
+ // MarshalJSON for time.Time writes RFC3339 with nanos.
+ Time: cbor.TimeRFC3339Nano,
+
+ // The decoder must be able to accept RFC3339 strings with or without tag 0 (e.g. by
+ // the end of time.Time -> JSON -> Unstructured -> CBOR, the CBOR encoder has no
+ // reliable way of knowing that a particular string originated from serializing a
+ // time.Time), so producing tag 0 has little use.
+ TimeTag: cbor.EncTagNone,
+
+ // Indefinite-length items have multiple encodings and aren't being used anyway, so
+ // disable to avoid an opportunity for nondeterminism.
+ IndefLength: cbor.IndefLengthForbidden,
+
+ // Preserve distinction between nil and empty for slices and maps.
+ NilContainers: cbor.NilContainerAsNull,
+
+ // OK to produce tags.
+ TagsMd: cbor.TagsAllowed,
+
+ // Use the same definition of "empty" as encoding/json.
+ OmitEmpty: cbor.OmitEmptyGoValue,
+
+ // The CBOR types text string and byte string are structurally equivalent, with the
+ // semantic difference that a text string whose content is an invalid UTF-8 sequence
+ // is itself invalid. We reject all invalid text strings at decode time and do not
+ // validate or sanitize all Go strings at encode time. Encoding Go strings to the
+ // byte string type is comparable to the existing Protobuf behavior and cheaply
+ // ensures that the output is valid CBOR.
+ String: cbor.StringToByteString,
+
+ // Encode struct field names to the byte string type rather than the text string
+ // type.
+ FieldName: cbor.FieldNameToByteString,
+
+ // Marshal Go byte arrays to CBOR arrays of integers (as in JSON) instead of byte
+ // strings.
+ ByteArray: cbor.ByteArrayToArray,
+
+ // Marshal []byte to CBOR byte string enclosed in tag 22 (expected later base64
+ // encoding, https://www.rfc-editor.org/rfc/rfc8949.html#section-3.4.5.2), to
+ // interoperate with the existing JSON behavior. This indicates to the decoder that,
+ // when decoding into a string (or unstructured), the resulting value should be the
+ // base64 encoding of the original bytes. No base64 encoding or decoding needs to be
+ // performed for []byte-to-CBOR-to-[]byte roundtrips.
+ ByteSliceLaterFormat: cbor.ByteSliceLaterFormatBase64,
+
+ // Disable default recognition of types implementing encoding.BinaryMarshaler, which
+ // is not recognized for JSON encoding.
+ BinaryMarshaler: cbor.BinaryMarshalerNone,
+ }.UserBufferEncMode()
+ if err != nil {
+ panic(err)
+ }
+ return encode
+ }(),
+}
+
+var EncodeNondeterministic = EncMode{
+ delegate: func() cbor.UserBufferEncMode {
+ opts := Encode.options()
+ opts.Sort = cbor.SortFastShuffle
+ em, err := opts.UserBufferEncMode()
+ if err != nil {
+ panic(err)
+ }
+ return em
+ }(),
+}
+
+type EncMode struct {
+ delegate cbor.UserBufferEncMode
+}
+
+func (em EncMode) options() cbor.EncOptions {
+ return em.delegate.EncOptions()
+}
+
+func (em EncMode) MarshalTo(v interface{}, w io.Writer) error {
+ if buf, ok := w.(*buffer); ok {
+ return em.delegate.MarshalToBuffer(v, &buf.Buffer)
+ }
+
+ buf := buffers.Get()
+ defer buffers.Put(buf)
+ if err := em.delegate.MarshalToBuffer(v, &buf.Buffer); err != nil {
+ return err
+ }
+
+ if _, err := io.Copy(w, buf); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (em EncMode) Marshal(v interface{}) ([]byte, error) {
+ buf := buffers.Get()
+ defer buffers.Put(buf)
+
+ if err := em.MarshalTo(v, &buf.Buffer); err != nil {
+ return nil, err
+ }
+
+ clone := make([]byte, buf.Len())
+ copy(clone, buf.Bytes())
+
+ return clone, nil
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
index 21944f2d8..77bb30745 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
@@ -17,9 +17,6 @@ limitations under the License.
package serializer
import (
- "mime"
- "strings"
-
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
@@ -28,41 +25,26 @@ import (
"k8s.io/apimachinery/pkg/runtime/serializer/versioning"
)
-// serializerExtensions are for serializers that are conditionally compiled in
-var serializerExtensions = []func(*runtime.Scheme) (serializerType, bool){}
-
-type serializerType struct {
- AcceptContentTypes []string
- ContentType string
- FileExtensions []string
- // EncodesAsText should be true if this content type can be represented safely in UTF-8
- EncodesAsText bool
-
- Serializer runtime.Serializer
- PrettySerializer runtime.Serializer
- StrictSerializer runtime.Serializer
-
- AcceptStreamContentTypes []string
- StreamContentType string
-
- Framer runtime.Framer
- StreamSerializer runtime.Serializer
-}
-
-func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory, options CodecFactoryOptions) []serializerType {
+func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory, options CodecFactoryOptions) []runtime.SerializerInfo {
jsonSerializer := json.NewSerializerWithOptions(
mf, scheme, scheme,
json.SerializerOptions{Yaml: false, Pretty: false, Strict: options.Strict},
)
- jsonSerializerType := serializerType{
- AcceptContentTypes: []string{runtime.ContentTypeJSON},
- ContentType: runtime.ContentTypeJSON,
- FileExtensions: []string{"json"},
- EncodesAsText: true,
- Serializer: jsonSerializer,
-
- Framer: json.Framer,
- StreamSerializer: jsonSerializer,
+ jsonSerializerType := runtime.SerializerInfo{
+ MediaType: runtime.ContentTypeJSON,
+ MediaTypeType: "application",
+ MediaTypeSubType: "json",
+ EncodesAsText: true,
+ Serializer: jsonSerializer,
+ StrictSerializer: json.NewSerializerWithOptions(
+ mf, scheme, scheme,
+ json.SerializerOptions{Yaml: false, Pretty: false, Strict: true},
+ ),
+ StreamSerializer: &runtime.StreamSerializerInfo{
+ EncodesAsText: true,
+ Serializer: jsonSerializer,
+ Framer: json.Framer,
+ },
}
if options.Pretty {
jsonSerializerType.PrettySerializer = json.NewSerializerWithOptions(
@@ -71,12 +53,6 @@ func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory, option
)
}
- strictJSONSerializer := json.NewSerializerWithOptions(
- mf, scheme, scheme,
- json.SerializerOptions{Yaml: false, Pretty: false, Strict: true},
- )
- jsonSerializerType.StrictSerializer = strictJSONSerializer
-
yamlSerializer := json.NewSerializerWithOptions(
mf, scheme, scheme,
json.SerializerOptions{Yaml: true, Pretty: false, Strict: options.Strict},
@@ -88,35 +64,35 @@ func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory, option
protoSerializer := protobuf.NewSerializer(scheme, scheme)
protoRawSerializer := protobuf.NewRawSerializer(scheme, scheme)
- serializers := []serializerType{
+ serializers := []runtime.SerializerInfo{
jsonSerializerType,
{
- AcceptContentTypes: []string{runtime.ContentTypeYAML},
- ContentType: runtime.ContentTypeYAML,
- FileExtensions: []string{"yaml"},
- EncodesAsText: true,
- Serializer: yamlSerializer,
- StrictSerializer: strictYAMLSerializer,
+ MediaType: runtime.ContentTypeYAML,
+ MediaTypeType: "application",
+ MediaTypeSubType: "yaml",
+ EncodesAsText: true,
+ Serializer: yamlSerializer,
+ StrictSerializer: strictYAMLSerializer,
},
{
- AcceptContentTypes: []string{runtime.ContentTypeProtobuf},
- ContentType: runtime.ContentTypeProtobuf,
- FileExtensions: []string{"pb"},
- Serializer: protoSerializer,
+ MediaType: runtime.ContentTypeProtobuf,
+ MediaTypeType: "application",
+ MediaTypeSubType: "vnd.kubernetes.protobuf",
+ Serializer: protoSerializer,
// note, strict decoding is unsupported for protobuf,
// fall back to regular serializing
StrictSerializer: protoSerializer,
-
- Framer: protobuf.LengthDelimitedFramer,
- StreamSerializer: protoRawSerializer,
+ StreamSerializer: &runtime.StreamSerializerInfo{
+ Serializer: protoRawSerializer,
+ Framer: protobuf.LengthDelimitedFramer,
+ },
},
}
- for _, fn := range serializerExtensions {
- if serializer, ok := fn(scheme); ok {
- serializers = append(serializers, serializer)
- }
+ for _, f := range options.serializers {
+ serializers = append(serializers, f(scheme, scheme))
}
+
return serializers
}
@@ -136,6 +112,8 @@ type CodecFactoryOptions struct {
Strict bool
// Pretty includes a pretty serializer along with the non-pretty one
Pretty bool
+
+ serializers []func(runtime.ObjectCreater, runtime.ObjectTyper) runtime.SerializerInfo
}
// CodecFactoryOptionsMutator takes a pointer to an options struct and then modifies it.
@@ -162,6 +140,13 @@ func DisableStrict(options *CodecFactoryOptions) {
options.Strict = false
}
+// WithSerializer configures a serializer to be supported in addition to the default serializers.
+func WithSerializer(f func(runtime.ObjectCreater, runtime.ObjectTyper) runtime.SerializerInfo) CodecFactoryOptionsMutator {
+ return func(options *CodecFactoryOptions) {
+ options.serializers = append(options.serializers, f)
+ }
+}
+
// NewCodecFactory provides methods for retrieving serializers for the supported wire formats
// and conversion wrappers to define preferred internal and external versions. In the future,
// as the internal version is used less, callers may instead use a defaulting serializer and
@@ -184,7 +169,7 @@ func NewCodecFactory(scheme *runtime.Scheme, mutators ...CodecFactoryOptionsMuta
}
// newCodecFactory is a helper for testing that allows a different metafactory to be specified.
-func newCodecFactory(scheme *runtime.Scheme, serializers []serializerType) CodecFactory {
+func newCodecFactory(scheme *runtime.Scheme, serializers []runtime.SerializerInfo) CodecFactory {
decoders := make([]runtime.Decoder, 0, len(serializers))
var accepts []runtime.SerializerInfo
alreadyAccepted := make(map[string]struct{})
@@ -192,38 +177,20 @@ func newCodecFactory(scheme *runtime.Scheme, serializers []serializerType) Codec
var legacySerializer runtime.Serializer
for _, d := range serializers {
decoders = append(decoders, d.Serializer)
- for _, mediaType := range d.AcceptContentTypes {
- if _, ok := alreadyAccepted[mediaType]; ok {
- continue
- }
- alreadyAccepted[mediaType] = struct{}{}
- info := runtime.SerializerInfo{
- MediaType: d.ContentType,
- EncodesAsText: d.EncodesAsText,
- Serializer: d.Serializer,
- PrettySerializer: d.PrettySerializer,
- StrictSerializer: d.StrictSerializer,
- }
-
- mediaType, _, err := mime.ParseMediaType(info.MediaType)
- if err != nil {
- panic(err)
- }
- parts := strings.SplitN(mediaType, "/", 2)
- info.MediaTypeType = parts[0]
- info.MediaTypeSubType = parts[1]
-
- if d.StreamSerializer != nil {
- info.StreamSerializer = &runtime.StreamSerializerInfo{
- Serializer: d.StreamSerializer,
- EncodesAsText: d.EncodesAsText,
- Framer: d.Framer,
- }
- }
- accepts = append(accepts, info)
- if mediaType == runtime.ContentTypeJSON {
- legacySerializer = d.Serializer
- }
+ if _, ok := alreadyAccepted[d.MediaType]; ok {
+ continue
+ }
+ alreadyAccepted[d.MediaType] = struct{}{}
+
+ acceptedSerializerShallowCopy := d
+ if d.StreamSerializer != nil {
+ cloned := *d.StreamSerializer
+ acceptedSerializerShallowCopy.StreamSerializer = &cloned
+ }
+ accepts = append(accepts, acceptedSerializerShallowCopy)
+
+ if d.MediaType == runtime.ContentTypeJSON {
+ legacySerializer = d.Serializer
}
}
if legacySerializer == nil {
@@ -259,8 +226,7 @@ func (f CodecFactory) SupportedMediaTypes() []runtime.SerializerInfo {
// invoke CodecForVersions. Callers that need only to read data should use UniversalDecoder().
//
// TODO: make this call exist only in pkg/api, and initialize it with the set of default versions.
-//
-// All other callers will be forced to request a Codec directly.
+// All other callers will be forced to request a Codec directly.
func (f CodecFactory) LegacyCodec(version ...schema.GroupVersion) runtime.Codec {
return versioning.NewDefaultingCodecForScheme(f.scheme, f.legacySerializer, f.universal, schema.GroupVersions(version), runtime.InternalGroupVersioner)
}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go
index 87b3fec3f..971c46d49 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go
@@ -134,23 +134,3 @@ func (e *encoder) Encode(obj runtime.Object) error {
e.buf.Reset()
return err
}
-
-type encoderWithAllocator struct {
- writer io.Writer
- encoder runtime.EncoderWithAllocator
- memAllocator runtime.MemoryAllocator
-}
-
-// NewEncoderWithAllocator returns a new streaming encoder
-func NewEncoderWithAllocator(w io.Writer, e runtime.EncoderWithAllocator, a runtime.MemoryAllocator) Encoder {
- return &encoderWithAllocator{
- writer: w,
- encoder: e,
- memAllocator: a,
- }
-}
-
-// Encode writes the provided object to the nested writer
-func (e *encoderWithAllocator) Encode(obj runtime.Object) error {
- return e.encoder.EncodeWithAllocator(obj, e.writer, e.memAllocator)
-}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
index 446633182..25f955ed7 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
@@ -147,7 +147,7 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru
}
if d, ok := obj.(runtime.NestedObjectDecoder); ok {
- if err := d.DecodeNestedObjects(runtime.WithoutVersionDecoder{c.decoder}); err != nil {
+ if err := d.DecodeNestedObjects(runtime.WithoutVersionDecoder{Decoder: c.decoder}); err != nil {
if strictErr, ok := runtime.AsStrictDecodingError(err); ok {
// save the strictDecodingError let and the caller decide what to do with it
strictDecodingErrs = append(strictDecodingErrs, strictErr.Errors()...)
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/splice.go b/vendor/k8s.io/apimachinery/pkg/runtime/splice.go
new file mode 100644
index 000000000..2badb7b97
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/splice.go
@@ -0,0 +1,76 @@
+/*
+Copyright 2023 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 runtime
+
+import (
+ "bytes"
+ "io"
+)
+
+// Splice is the interface that wraps the Splice method.
+//
+// Splice moves data from given slice without copying the underlying data for
+// efficiency purpose. Therefore, the caller should make sure the underlying
+// data is not changed later.
+type Splice interface {
+ Splice([]byte)
+ io.Writer
+ Reset()
+ Bytes() []byte
+}
+
+// A spliceBuffer implements Splice and io.Writer interfaces.
+type spliceBuffer struct {
+ raw []byte
+ buf *bytes.Buffer
+}
+
+func NewSpliceBuffer() Splice {
+ return &spliceBuffer{}
+}
+
+// Splice implements the Splice interface.
+func (sb *spliceBuffer) Splice(raw []byte) {
+ sb.raw = raw
+}
+
+// Write implements the io.Writer interface.
+func (sb *spliceBuffer) Write(p []byte) (n int, err error) {
+ if sb.buf == nil {
+ sb.buf = &bytes.Buffer{}
+ }
+ return sb.buf.Write(p)
+}
+
+// Reset resets the buffer to be empty.
+func (sb *spliceBuffer) Reset() {
+ if sb.buf != nil {
+ sb.buf.Reset()
+ }
+ sb.raw = nil
+}
+
+// Bytes returns the data held by the buffer.
+func (sb *spliceBuffer) Bytes() []byte {
+ if sb.buf != nil && len(sb.buf.Bytes()) > 0 {
+ return sb.buf.Bytes()
+ }
+ if sb.raw != nil {
+ return sb.raw
+ }
+ return []byte{}
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/types.go b/vendor/k8s.io/apimachinery/pkg/runtime/types.go
index 3dc9a5a2f..ca7b7cc2d 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/types.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/types.go
@@ -43,9 +43,11 @@ type TypeMeta struct {
}
const (
- ContentTypeJSON string = "application/json"
- ContentTypeYAML string = "application/yaml"
- ContentTypeProtobuf string = "application/vnd.kubernetes.protobuf"
+ ContentTypeJSON string = "application/json"
+ ContentTypeYAML string = "application/yaml"
+ ContentTypeProtobuf string = "application/vnd.kubernetes.protobuf"
+ ContentTypeCBOR string = "application/cbor" // RFC 8949
+ ContentTypeCBORSequence string = "application/cbor-seq" // RFC 8742
)
// RawExtension is used to hold extensions in external versions.
@@ -123,7 +125,7 @@ type Unknown struct {
// Raw will hold the complete serialized object which couldn't be matched
// with a registered type. Most likely, nothing should be done with this
// except for passing it through the system.
- Raw []byte `protobuf:"bytes,2,opt,name=raw"`
+ Raw []byte `json:"-" protobuf:"bytes,2,opt,name=raw"`
// ContentEncoding is encoding used to encode 'Raw' data.
// Unspecified means no encoding.
ContentEncoding string `protobuf:"bytes,3,opt,name=contentEncoding"`
diff --git a/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go b/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go
index b19750f3a..db18ce1ce 100644
--- a/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go
+++ b/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go
@@ -37,3 +37,14 @@ const (
func (n NamespacedName) String() string {
return n.Namespace + string(Separator) + n.Name
}
+
+// MarshalLog emits a struct containing required key/value pair
+func (n NamespacedName) MarshalLog() interface{} {
+ return struct {
+ Name string `json:"name"`
+ Namespace string `json:"namespace,omitempty"`
+ }{
+ Name: n.Name,
+ Namespace: n.Namespace,
+ }
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/types/patch.go b/vendor/k8s.io/apimachinery/pkg/types/patch.go
index fe8ecaaff..d338cf213 100644
--- a/vendor/k8s.io/apimachinery/pkg/types/patch.go
+++ b/vendor/k8s.io/apimachinery/pkg/types/patch.go
@@ -25,5 +25,7 @@ const (
JSONPatchType PatchType = "application/json-patch+json"
MergePatchType PatchType = "application/merge-patch+json"
StrategicMergePatchType PatchType = "application/strategic-merge-patch+json"
- ApplyPatchType PatchType = "application/apply-patch+yaml"
+ ApplyPatchType PatchType = ApplyYAMLPatchType
+ ApplyYAMLPatchType PatchType = "application/apply-patch+yaml"
+ ApplyCBORPatchType PatchType = "application/apply-patch+cbor"
)
diff --git a/vendor/k8s.io/apimachinery/pkg/util/cache/expiring.go b/vendor/k8s.io/apimachinery/pkg/util/cache/expiring.go
index 0d2f153bf..1396274c7 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/cache/expiring.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/cache/expiring.go
@@ -40,6 +40,13 @@ func NewExpiringWithClock(clock clock.Clock) *Expiring {
// Expiring is a map whose entries expire after a per-entry timeout.
type Expiring struct {
+ // AllowExpiredGet causes the expiration check to be skipped on Get.
+ // It should only be used when a key always corresponds to the exact same value.
+ // Thus when this field is true, expired keys are considered valid
+ // until the next call to Set (which causes the GC to run).
+ // It may not be changed concurrently with calls to Get.
+ AllowExpiredGet bool
+
clock clock.Clock
// mu protects the below fields
@@ -70,7 +77,10 @@ func (c *Expiring) Get(key interface{}) (val interface{}, ok bool) {
c.mu.RLock()
defer c.mu.RUnlock()
e, ok := c.cache[key]
- if !ok || !c.clock.Now().Before(e.expiry) {
+ if !ok {
+ return nil, false
+ }
+ if !c.AllowExpiredGet && !c.clock.Now().Before(e.expiry) {
return nil, false
}
return e.val, true
diff --git a/vendor/k8s.io/apimachinery/pkg/util/cache/lruexpirecache.go b/vendor/k8s.io/apimachinery/pkg/util/cache/lruexpirecache.go
index 1328dd612..ad486d580 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/cache/lruexpirecache.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/cache/lruexpirecache.go
@@ -136,6 +136,19 @@ func (c *LRUExpireCache) Remove(key interface{}) {
delete(c.entries, key)
}
+// RemoveAll removes all keys that match predicate.
+func (c *LRUExpireCache) RemoveAll(predicate func(key any) bool) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ for key, element := range c.entries {
+ if predicate(key) {
+ c.evictionList.Remove(element)
+ delete(c.entries, key)
+ }
+ }
+}
+
// Keys returns all unexpired keys in the cache.
//
// Keep in mind that subsequent calls to Get() for any of the returned keys
diff --git a/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go b/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go
index ec4002e38..fc0301844 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go
@@ -23,34 +23,20 @@ import (
"strings"
"text/tabwriter"
- "github.com/davecgh/go-spew/spew"
"github.com/google/go-cmp/cmp"
+ "k8s.io/apimachinery/pkg/util/dump"
)
-// StringDiff diffs a and b and returns a human readable diff.
-func StringDiff(a, b string) string {
- ba := []byte(a)
- bb := []byte(b)
- out := []byte{}
- i := 0
- for ; i < len(ba) && i < len(bb); i++ {
- if ba[i] != bb[i] {
- break
- }
- out = append(out, ba[i])
- }
- out = append(out, []byte("\n\nA: ")...)
- out = append(out, ba[i:]...)
- out = append(out, []byte("\n\nB: ")...)
- out = append(out, bb[i:]...)
- out = append(out, []byte("\n\n")...)
- return string(out)
-}
-
func legacyDiff(a, b interface{}) string {
return cmp.Diff(a, b)
}
+// StringDiff diffs a and b and returns a human readable diff.
+// DEPRECATED: use github.com/google/go-cmp/cmp.Diff
+func StringDiff(a, b string) string {
+ return legacyDiff(a, b)
+}
+
// ObjectDiff prints the diff of two go objects and fails if the objects
// contain unhandled unexported fields.
// DEPRECATED: use github.com/google/go-cmp/cmp.Diff
@@ -75,13 +61,8 @@ func ObjectReflectDiff(a, b interface{}) string {
// ObjectGoPrintSideBySide prints a and b as textual dumps side by side,
// enabling easy visual scanning for mismatches.
func ObjectGoPrintSideBySide(a, b interface{}) string {
- s := spew.ConfigState{
- Indent: " ",
- // Extra deep spew.
- DisableMethods: true,
- }
- sA := s.Sdump(a)
- sB := s.Sdump(b)
+ sA := dump.Pretty(a)
+ sB := dump.Pretty(b)
linesA := strings.Split(sA, "\n")
linesB := strings.Split(sB, "\n")
diff --git a/vendor/k8s.io/apimachinery/pkg/util/dump/dump.go b/vendor/k8s.io/apimachinery/pkg/util/dump/dump.go
new file mode 100644
index 000000000..cf61ef76a
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/dump/dump.go
@@ -0,0 +1,54 @@
+/*
+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 dump
+
+import (
+ "github.com/davecgh/go-spew/spew"
+)
+
+var prettyPrintConfig = &spew.ConfigState{
+ Indent: " ",
+ DisableMethods: true,
+ DisablePointerAddresses: true,
+ DisableCapacities: true,
+}
+
+// The config MUST NOT be changed because that could change the result of a hash operation
+var prettyPrintConfigForHash = &spew.ConfigState{
+ Indent: " ",
+ SortKeys: true,
+ DisableMethods: true,
+ SpewKeys: true,
+ DisablePointerAddresses: true,
+ DisableCapacities: true,
+}
+
+// Pretty wrap the spew.Sdump with Indent, and disabled methods like error() and String()
+// The output may change over time, so for guaranteed output please take more direct control
+func Pretty(a interface{}) string {
+ return prettyPrintConfig.Sdump(a)
+}
+
+// ForHash keeps the original Spew.Sprintf format to ensure the same checksum
+func ForHash(a interface{}) string {
+ return prettyPrintConfigForHash.Sprintf("%#v", a)
+}
+
+// OneLine outputs the object in one line
+func OneLine(a interface{}) string {
+ return prettyPrintConfig.Sprintf("%#v", a)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go b/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go
index 1f5a04fd4..1b60d145c 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go
@@ -214,7 +214,7 @@ func CreateAggregateFromMessageCountMap(m MessageCountMap) Aggregate {
return NewAggregate(result)
}
-// Reduce will return err or, if err is an Aggregate and only has one item,
+// Reduce will return err or nil, if err is an Aggregate and only has one item,
// the first item in the aggregate.
func Reduce(err error) error {
if agg, ok := err.(Aggregate); ok && err != nil {
diff --git a/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go b/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go
index ca08f8561..1ab8fd396 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go
@@ -32,7 +32,7 @@ func NewLengthDelimitedFrameWriter(w io.Writer) io.Writer {
return &lengthDelimitedFrameWriter{w: w}
}
-// Write writes a single frame to the nested writer, prepending it with the length in
+// Write writes a single frame to the nested writer, prepending it with the length
// in bytes of data (as a 4 byte, bigendian uint32).
func (w *lengthDelimitedFrameWriter) Write(data []byte) (int, error) {
binary.BigEndian.PutUint32(w.h[:], uint32(len(data)))
@@ -147,7 +147,6 @@ func (r *jsonFrameReader) Read(data []byte) (int, error) {
// RawMessage#Unmarshal appends to data - we reset the slice down to 0 and will either see
// data written to data, or be larger than data and a different array.
- n := len(data)
m := json.RawMessage(data[:0])
if err := r.decoder.Decode(&m); err != nil {
return 0, err
@@ -156,12 +155,19 @@ func (r *jsonFrameReader) Read(data []byte) (int, error) {
// If capacity of data is less than length of the message, decoder will allocate a new slice
// and set m to it, which means we need to copy the partial result back into data and preserve
// the remaining result for subsequent reads.
- if len(m) > n {
- //nolint:staticcheck // SA4006,SA4010 underlying array of data is modified here.
- data = append(data[0:0], m[:n]...)
- r.remaining = m[n:]
- return n, io.ErrShortBuffer
+ if len(m) > cap(data) {
+ copy(data, m)
+ r.remaining = m[len(data):]
+ return len(data), io.ErrShortBuffer
}
+
+ if len(m) > len(data) {
+ // The bytes beyond len(data) were stored in data's underlying array, which we do
+ // not own after this function returns.
+ r.remaining = append([]byte(nil), m[len(data):]...)
+ return len(data), io.ErrShortBuffer
+ }
+
return len(m), nil
}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go b/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go
index 8f9ced93f..1f2877399 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go
@@ -15,7 +15,7 @@ limitations under the License.
*/
// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.proto
+// source: k8s.io/apimachinery/pkg/util/intstr/generated.proto
package intstr
@@ -43,7 +43,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func (m *IntOrString) Reset() { *m = IntOrString{} }
func (*IntOrString) ProtoMessage() {}
func (*IntOrString) Descriptor() ([]byte, []int) {
- return fileDescriptor_94e046ae3ce6121c, []int{0}
+ return fileDescriptor_771bacc35a5ec189, []int{0}
}
func (m *IntOrString) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -73,30 +73,29 @@ func init() {
}
func init() {
- proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.proto", fileDescriptor_94e046ae3ce6121c)
+ proto.RegisterFile("k8s.io/apimachinery/pkg/util/intstr/generated.proto", fileDescriptor_771bacc35a5ec189)
}
-var fileDescriptor_94e046ae3ce6121c = []byte{
- // 292 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x90, 0xb1, 0x4a, 0x03, 0x31,
- 0x1c, 0xc6, 0x13, 0x5b, 0x8b, 0x9e, 0xe0, 0x50, 0x1c, 0x8a, 0x43, 0x7a, 0x58, 0x90, 0x5b, 0x4c,
- 0x56, 0x71, 0xec, 0x56, 0x10, 0x84, 0x56, 0x1c, 0xdc, 0xee, 0xda, 0x98, 0x86, 0x6b, 0x93, 0x90,
- 0xfb, 0x9f, 0x70, 0x5b, 0x1f, 0x41, 0x37, 0x47, 0x1f, 0xe7, 0xc6, 0x8e, 0x1d, 0xa4, 0x78, 0xf1,
- 0x2d, 0x9c, 0xe4, 0x72, 0x07, 0x3a, 0x3a, 0x25, 0xdf, 0xf7, 0xfd, 0x7e, 0x19, 0x12, 0xdc, 0xa6,
- 0xd7, 0x19, 0x95, 0x9a, 0xa5, 0x79, 0xc2, 0xad, 0xe2, 0xc0, 0x33, 0xf6, 0xcc, 0xd5, 0x42, 0x5b,
- 0xd6, 0x0e, 0xb1, 0x91, 0xeb, 0x78, 0xbe, 0x94, 0x8a, 0xdb, 0x82, 0x99, 0x54, 0xb0, 0x1c, 0xe4,
- 0x8a, 0x49, 0x05, 0x19, 0x58, 0x26, 0xb8, 0xe2, 0x36, 0x06, 0xbe, 0xa0, 0xc6, 0x6a, 0xd0, 0xfd,
- 0x51, 0x23, 0xd1, 0xbf, 0x12, 0x35, 0xa9, 0xa0, 0xb5, 0x44, 0x1b, 0xe9, 0xfc, 0x4a, 0x48, 0x58,
- 0xe6, 0x09, 0x9d, 0xeb, 0x35, 0x13, 0x5a, 0x68, 0xe6, 0xdd, 0x24, 0x7f, 0xf2, 0xc9, 0x07, 0x7f,
- 0x6b, 0xde, 0xbc, 0x78, 0xc5, 0xc1, 0xc9, 0x44, 0xc1, 0x9d, 0x9d, 0x81, 0x95, 0x4a, 0xf4, 0xa3,
- 0xa0, 0x0b, 0x85, 0xe1, 0x03, 0x1c, 0xe2, 0xa8, 0x33, 0x3e, 0x2b, 0xf7, 0x43, 0xe4, 0xf6, 0xc3,
- 0xee, 0x7d, 0x61, 0xf8, 0x77, 0x7b, 0x4e, 0x3d, 0xd1, 0xbf, 0x0c, 0x7a, 0x52, 0xc1, 0x43, 0xbc,
- 0x1a, 0x1c, 0x84, 0x38, 0x3a, 0x1c, 0x9f, 0xb6, 0x6c, 0x6f, 0xe2, 0xdb, 0x69, 0xbb, 0xd6, 0x5c,
- 0x06, 0xb6, 0xe6, 0x3a, 0x21, 0x8e, 0x8e, 0x7f, 0xb9, 0x99, 0x6f, 0xa7, 0xed, 0x7a, 0x73, 0xf4,
- 0xf6, 0x3e, 0x44, 0x9b, 0x8f, 0x10, 0x8d, 0x27, 0x65, 0x45, 0xd0, 0xb6, 0x22, 0x68, 0x57, 0x11,
- 0xb4, 0x71, 0x04, 0x97, 0x8e, 0xe0, 0xad, 0x23, 0x78, 0xe7, 0x08, 0xfe, 0x74, 0x04, 0xbf, 0x7c,
- 0x11, 0xf4, 0x38, 0xfa, 0xc7, 0x17, 0xfe, 0x04, 0x00, 0x00, 0xff, 0xff, 0xdc, 0xc4, 0xf0, 0xa0,
- 0x81, 0x01, 0x00, 0x00,
+var fileDescriptor_771bacc35a5ec189 = []byte{
+ // 277 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0xce, 0xb6, 0x28, 0xd6,
+ 0xcb, 0xcc, 0xd7, 0x4f, 0x2c, 0xc8, 0xcc, 0x4d, 0x4c, 0xce, 0xc8, 0xcc, 0x4b, 0x2d, 0xaa, 0xd4,
+ 0x2f, 0xc8, 0x4e, 0xd7, 0x2f, 0x2d, 0xc9, 0xcc, 0xd1, 0xcf, 0xcc, 0x2b, 0x29, 0x2e, 0x29, 0xd2,
+ 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0x4a, 0x2c, 0x49, 0x4d, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17,
+ 0x52, 0x86, 0x68, 0xd2, 0x43, 0xd6, 0xa4, 0x57, 0x90, 0x9d, 0xae, 0x07, 0xd2, 0xa4, 0x07, 0xd1,
+ 0x24, 0xa5, 0x9b, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x9f, 0x9e, 0x9f,
+ 0x9e, 0xaf, 0x0f, 0xd6, 0x9b, 0x54, 0x9a, 0x06, 0xe6, 0x81, 0x39, 0x60, 0x16, 0xc4, 0x4c, 0xa5,
+ 0x89, 0x8c, 0x5c, 0xdc, 0x9e, 0x79, 0x25, 0xfe, 0x45, 0xc1, 0x25, 0x45, 0x99, 0x79, 0xe9, 0x42,
+ 0x1a, 0x5c, 0x2c, 0x25, 0x95, 0x05, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xcc, 0x4e, 0x22, 0x27,
+ 0xee, 0xc9, 0x33, 0x3c, 0xba, 0x27, 0xcf, 0x12, 0x52, 0x59, 0x90, 0xfa, 0x0b, 0x4a, 0x07, 0x81,
+ 0x55, 0x08, 0xa9, 0x71, 0xb1, 0x65, 0xe6, 0x95, 0x84, 0x25, 0xe6, 0x48, 0x30, 0x29, 0x30, 0x6a,
+ 0xb0, 0x3a, 0xf1, 0x41, 0xd5, 0xb2, 0x79, 0x82, 0x45, 0x83, 0xa0, 0xb2, 0x20, 0x75, 0xc5, 0x25,
+ 0x45, 0x20, 0x75, 0xcc, 0x0a, 0x8c, 0x1a, 0x9c, 0x08, 0x75, 0xc1, 0x60, 0xd1, 0x20, 0xa8, 0xac,
+ 0x15, 0xc7, 0x8c, 0x05, 0xf2, 0x0c, 0x0d, 0x77, 0x14, 0x18, 0x9c, 0x3c, 0x4f, 0x3c, 0x94, 0x63,
+ 0xb8, 0xf0, 0x50, 0x8e, 0xe1, 0xc6, 0x43, 0x39, 0x86, 0x86, 0x47, 0x72, 0x8c, 0x27, 0x1e, 0xc9,
+ 0x31, 0x5e, 0x78, 0x24, 0xc7, 0x78, 0xe3, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e,
+ 0xcb, 0x31, 0x44, 0x29, 0x13, 0x11, 0x84, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x63, 0xa1, 0x0b,
+ 0x1e, 0x68, 0x01, 0x00, 0x00,
}
func (m *IntOrString) Marshal() (dAtA []byte, err error) {
diff --git a/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go b/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go
index 5e8009704..5fd2e16c8 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go
@@ -25,6 +25,7 @@ import (
"strconv"
"strings"
+ cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
"k8s.io/klog/v2"
)
@@ -54,7 +55,7 @@ const (
// FromInt creates an IntOrString object with an int32 value. It is
// your responsibility not to call this method with a value greater
// than int32.
-// TODO: convert to (val int32)
+// Deprecated: use FromInt32 instead.
func FromInt(val int) IntOrString {
if val > math.MaxInt32 || val < math.MinInt32 {
klog.Errorf("value: %d overflows int32\n%s\n", val, debug.Stack())
@@ -62,19 +63,24 @@ func FromInt(val int) IntOrString {
return IntOrString{Type: Int, IntVal: int32(val)}
}
+// FromInt32 creates an IntOrString object with an int32 value.
+func FromInt32(val int32) IntOrString {
+ return IntOrString{Type: Int, IntVal: val}
+}
+
// FromString creates an IntOrString object with a string value.
func FromString(val string) IntOrString {
return IntOrString{Type: String, StrVal: val}
}
-// Parse the given string and try to convert it to an integer before
+// Parse the given string and try to convert it to an int32 integer before
// setting it as a string value.
func Parse(val string) IntOrString {
- i, err := strconv.Atoi(val)
+ i, err := strconv.ParseInt(val, 10, 32)
if err != nil {
return FromString(val)
}
- return FromInt(i)
+ return FromInt32(int32(i))
}
// UnmarshalJSON implements the json.Unmarshaller interface.
@@ -87,6 +93,20 @@ func (intstr *IntOrString) UnmarshalJSON(value []byte) error {
return json.Unmarshal(value, &intstr.IntVal)
}
+func (intstr *IntOrString) UnmarshalCBOR(value []byte) error {
+ if err := cbor.Unmarshal(value, &intstr.StrVal); err == nil {
+ intstr.Type = String
+ return nil
+ }
+
+ if err := cbor.Unmarshal(value, &intstr.IntVal); err != nil {
+ return err
+ }
+
+ intstr.Type = Int
+ return nil
+}
+
// String returns the string value, or the Itoa of the int value.
func (intstr *IntOrString) String() string {
if intstr == nil {
@@ -121,6 +141,17 @@ func (intstr IntOrString) MarshalJSON() ([]byte, error) {
}
}
+func (intstr IntOrString) MarshalCBOR() ([]byte, error) {
+ switch intstr.Type {
+ case Int:
+ return cbor.Marshal(intstr.IntVal)
+ case String:
+ return cbor.Marshal(intstr.StrVal)
+ default:
+ return nil, fmt.Errorf("impossible IntOrString.Type")
+ }
+}
+
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/endpoints.yaml b/vendor/k8s.io/apimachinery/pkg/util/managedfields/endpoints.yaml
new file mode 100644
index 000000000..a667e9834
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/endpoints.yaml
@@ -0,0 +1,7018 @@
+apiVersion: v1
+kind: Endpoints
+metadata:
+ creationTimestamp: '2016-10-04T17:45:58Z'
+ labels:
+ app: my-app
+ name: app-server
+ namespace: default
+ resourceVersion: '184597135'
+ selfLink: /self/link
+ uid: 6826f086-8a5a-11e6-8d09-42010a800005
+subsets:
+- addresses:
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0000
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0001
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0002
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0003
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0004
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0005
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0006
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0007
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0008
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0009
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0010
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0011
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0012
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0013
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0014
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0015
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0016
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0017
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0018
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0019
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0020
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0021
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0022
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0023
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0024
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0025
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0026
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0027
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0028
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0029
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0030
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0031
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0032
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0033
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0034
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0035
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0036
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0037
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0038
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0039
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0040
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0041
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0042
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0043
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0044
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0045
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0046
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0047
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0048
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0049
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0050
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0051
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0052
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0053
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0054
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0055
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0056
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0057
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0058
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0059
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0060
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0061
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0062
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0063
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0064
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0065
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0066
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0067
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0068
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0069
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0070
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0071
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0072
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0073
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0074
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0075
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0076
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0077
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0078
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0079
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0080
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0081
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0082
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0083
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0084
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0085
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0086
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0087
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0088
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0089
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0090
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0091
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0092
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0093
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0094
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0095
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0096
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0097
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0098
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0099
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0100
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0101
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0102
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0103
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0104
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0105
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0106
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0107
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0108
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0109
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0110
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0111
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0112
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0113
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0114
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0115
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0116
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0117
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0118
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0119
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0120
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0121
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0122
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0123
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0124
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0125
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0126
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0127
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0128
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0129
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0130
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0131
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0132
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0133
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0134
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0135
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0136
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0137
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0138
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0139
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0140
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0141
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0142
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0143
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0144
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0145
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0146
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0147
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0148
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0149
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0150
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0151
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0152
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0153
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0154
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0155
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0156
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0157
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0158
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0159
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0160
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0161
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0162
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0163
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0164
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0165
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0166
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0167
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0168
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0169
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0170
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0171
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0172
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0173
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0174
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0175
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0176
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0177
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0178
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0179
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0180
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0181
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0182
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0183
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0184
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0185
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0186
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0187
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0188
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0189
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0190
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0191
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0192
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0193
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0194
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0195
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0196
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0197
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0198
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0199
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0200
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0201
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0202
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0203
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0204
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0205
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0206
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0207
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0208
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0209
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0210
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0211
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0212
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0213
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0214
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0215
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0216
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0217
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0218
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0219
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0220
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0221
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0222
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0223
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0224
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0225
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0226
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0227
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0228
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0229
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0230
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0231
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0232
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0233
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0234
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0235
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0236
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0237
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0238
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0239
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0240
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0241
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0242
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0243
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0244
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0245
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0246
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0247
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0248
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0249
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0250
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0251
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0252
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0253
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0254
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0255
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0256
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0257
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0258
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0259
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0260
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0261
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0262
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0263
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0264
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0265
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0266
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0267
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0268
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0269
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0270
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0271
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0272
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0273
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0274
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0275
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0276
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0277
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0278
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0279
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0280
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0281
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0282
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0283
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0284
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0285
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0286
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0287
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0288
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0289
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0290
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0291
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0292
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0293
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0294
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0295
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0296
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0297
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0298
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0299
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0300
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0301
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0302
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0303
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0304
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0305
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0306
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0307
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0308
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0309
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0310
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0311
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0312
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0313
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0314
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0315
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0316
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0317
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0318
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0319
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0320
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0321
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0322
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0323
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0324
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0325
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0326
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0327
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0328
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0329
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0330
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0331
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0332
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0333
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0334
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0335
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0336
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0337
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0338
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0339
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0340
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0341
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0342
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0343
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0344
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0345
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0346
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0347
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0348
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0349
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0350
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0351
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0352
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0353
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0354
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0355
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0356
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0357
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0358
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0359
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0360
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0361
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0362
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0363
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0364
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0365
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0366
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0367
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0368
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0369
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0370
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0371
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0372
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0373
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0374
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0375
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0376
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0377
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0378
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0379
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0380
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0381
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0382
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0383
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0384
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0385
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0386
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0387
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0388
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0389
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0390
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0391
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0392
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0393
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0394
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0395
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0396
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0397
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0398
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0399
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0400
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0401
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0402
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0403
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0404
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0405
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0406
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0407
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0408
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0409
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0410
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0411
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0412
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0413
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0414
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0415
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0416
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0417
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0418
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0419
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0420
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0421
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0422
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0423
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0424
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0425
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0426
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0427
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0428
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0429
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0430
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0431
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0432
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0433
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0434
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0435
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0436
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0437
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0438
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0439
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0440
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0441
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0442
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0443
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0444
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0445
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0446
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0447
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0448
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0449
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0450
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0451
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0452
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0453
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0454
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0455
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0456
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0457
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0458
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0459
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0460
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0461
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0462
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0463
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0464
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0465
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0466
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0467
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0468
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0469
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0470
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0471
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0472
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0473
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0474
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0475
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0476
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0477
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0478
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0479
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0480
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0481
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0482
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0483
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0484
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0485
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0486
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0487
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0488
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0489
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0490
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0491
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0492
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0493
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0494
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0495
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0496
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0497
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0498
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0499
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0500
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0501
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0502
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0503
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0504
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0505
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0506
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0507
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0508
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0509
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0510
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0511
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0512
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0513
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0514
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0515
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0516
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0517
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0518
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0519
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0520
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0521
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0522
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0523
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0524
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0525
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0526
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0527
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0528
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0529
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0530
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0531
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0532
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0533
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0534
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0535
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0536
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0537
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0538
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0539
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0540
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0541
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0542
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0543
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0544
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0545
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0546
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0547
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0548
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0549
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0550
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0551
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0552
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0553
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0554
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0555
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0556
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0557
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0558
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0559
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0560
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0561
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0562
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0563
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0564
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0565
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0566
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0567
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0568
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0569
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0570
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0571
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0572
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0573
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0574
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0575
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0576
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0577
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0578
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0579
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0580
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0581
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0582
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0583
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0584
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0585
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0586
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0587
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0588
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0589
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0590
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0591
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0592
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0593
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0594
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0595
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0596
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0597
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0598
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0599
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0600
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0601
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0602
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0603
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0604
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0605
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0606
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0607
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0608
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0609
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0610
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0611
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0612
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0613
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0614
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0615
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0616
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0617
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0618
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0619
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0620
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0621
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0622
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0623
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0624
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0625
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0626
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0627
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0628
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0629
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0630
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0631
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0632
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0633
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0634
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0635
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0636
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0637
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0638
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0639
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0640
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0641
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0642
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0643
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0644
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0645
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0646
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0647
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0648
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0649
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0650
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0651
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0652
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0653
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0654
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0655
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0656
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0657
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0658
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0659
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0660
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0661
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0662
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0663
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0664
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0665
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0666
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0667
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0668
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0669
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0670
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0671
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0672
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0673
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0674
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0675
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0676
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0677
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0678
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0679
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0680
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0681
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0682
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0683
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0684
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0685
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0686
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0687
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0688
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0689
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0690
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0691
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0692
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0693
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0694
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0695
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0696
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0697
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0698
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0699
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0700
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0701
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0702
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0703
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0704
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0705
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0706
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0707
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0708
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0709
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0710
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0711
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0712
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0713
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0714
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0715
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0716
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0717
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0718
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0719
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0720
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0721
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0722
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0723
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0724
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0725
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0726
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0727
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0728
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0729
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0730
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0731
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0732
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0733
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0734
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0735
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0736
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0737
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0738
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0739
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0740
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0741
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0742
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0743
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0744
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0745
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0746
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0747
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0748
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0749
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0750
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0751
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0752
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0753
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0754
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0755
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0756
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0757
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0758
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0759
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0760
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0761
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0762
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0763
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0764
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0765
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0766
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0767
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0768
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0769
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0770
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0771
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0772
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0773
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0774
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0775
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0776
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0777
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0778
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0779
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0780
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0781
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0782
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0783
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0784
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0785
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0786
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0787
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0788
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0789
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0790
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0791
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0792
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0793
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0794
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0795
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0796
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0797
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0798
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0799
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0800
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0801
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0802
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0803
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0804
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0805
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0806
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0807
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0808
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0809
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0810
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0811
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0812
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0813
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0814
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0815
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0816
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0817
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0818
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0819
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0820
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0821
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0822
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0823
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0824
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0825
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0826
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0827
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0828
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0829
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0830
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0831
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0832
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0833
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0834
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0835
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0836
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0837
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0838
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0839
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0840
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0841
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0842
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0843
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0844
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0845
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0846
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0847
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0848
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0849
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0850
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0851
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0852
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0853
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0854
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0855
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0856
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0857
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0858
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0859
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0860
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0861
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0862
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0863
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0864
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0865
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0866
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0867
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0868
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0869
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0870
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0871
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0872
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0873
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0874
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0875
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0876
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0877
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0878
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0879
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0880
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0881
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0882
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0883
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0884
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0885
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0886
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0887
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0888
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0889
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0890
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0891
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0892
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0893
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0894
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0895
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0896
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0897
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0898
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0899
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0900
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0901
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0902
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0903
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0904
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0905
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0906
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0907
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0908
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0909
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0910
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0911
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0912
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0913
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0914
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0915
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0916
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0917
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0918
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0919
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0920
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0921
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0922
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0923
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0924
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0925
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0926
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0927
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0928
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0929
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0930
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0931
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0932
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0933
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0934
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0935
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0936
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0937
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0938
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0939
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0940
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0941
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0942
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0943
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0944
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0945
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0946
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0947
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0948
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0949
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0950
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0951
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0952
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0953
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0954
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0955
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0956
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0957
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0958
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0959
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0960
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0961
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0962
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0963
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0964
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0965
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0966
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0967
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0968
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0969
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0970
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0971
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0972
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0973
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0974
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0975
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0976
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0977
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0978
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0979
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0980
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0981
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0982
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0983
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0984
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0985
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0986
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0987
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0988
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0989
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0990
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0991
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0992
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0993
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0994
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0995
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0996
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0997
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0998
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ - ip: 10.0.0.1
+ targetRef:
+ kind: Pod
+ name: pod-name-1234-0999
+ namespace: default
+ resourceVersion: '1234567890'
+ uid: 11111111-2222-3333-4444-555555555555
+ ports:
+ - name: port-name
+ port: 8080
+ protocol: TCP
+
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/fieldmanager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/fieldmanager.go
new file mode 100644
index 000000000..de540c82f
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/fieldmanager.go
@@ -0,0 +1,58 @@
+/*
+Copyright 2018 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 managedfields
+
+import (
+ "fmt"
+
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/util/managedfields/internal"
+)
+
+// FieldManager updates the managed fields and merges applied
+// configurations.
+type FieldManager = internal.FieldManager
+
+// NewDefaultFieldManager creates a new FieldManager that merges apply requests
+// and update managed fields for other types of requests.
+func NewDefaultFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]fieldpath.Filter) (*FieldManager, error) {
+ f, err := internal.NewStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub, resetFields)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create field manager: %v", err)
+ }
+ return internal.NewDefaultFieldManager(f, typeConverter, objectConverter, objectCreater, kind, subresource), nil
+}
+
+// NewDefaultCRDFieldManager creates a new FieldManager specifically for
+// CRDs. This allows for the possibility of fields which are not defined
+// in models, as well as having no models defined at all.
+func NewDefaultCRDFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]fieldpath.Filter) (_ *FieldManager, err error) {
+ f, err := internal.NewCRDStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub, resetFields)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create field manager: %v", err)
+ }
+ return internal.NewDefaultFieldManager(f, typeConverter, objectConverter, objectCreater, kind, subresource), nil
+}
+
+func ValidateManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) error {
+ _, err := internal.DecodeManagedFields(encodedManagedFields)
+ return err
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/atmostevery.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/atmostevery.go
new file mode 100644
index 000000000..b75ef7416
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/atmostevery.go
@@ -0,0 +1,60 @@
+/*
+Copyright 2020 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 internal
+
+import (
+ "sync"
+ "time"
+)
+
+// AtMostEvery will never run the method more than once every specified
+// duration.
+type AtMostEvery struct {
+ delay time.Duration
+ lastCall time.Time
+ mutex sync.Mutex
+}
+
+// NewAtMostEvery creates a new AtMostEvery, that will run the method at
+// most every given duration.
+func NewAtMostEvery(delay time.Duration) *AtMostEvery {
+ return &AtMostEvery{
+ delay: delay,
+ }
+}
+
+// updateLastCall returns true if the lastCall time has been updated,
+// false if it was too early.
+func (s *AtMostEvery) updateLastCall() bool {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ if time.Since(s.lastCall) < s.delay {
+ return false
+ }
+ s.lastCall = time.Now()
+ return true
+}
+
+// Do will run the method if enough time has passed, and return true.
+// Otherwise, it does nothing and returns false.
+func (s *AtMostEvery) Do(fn func()) bool {
+ if !s.updateLastCall() {
+ return false
+ }
+ fn()
+ return true
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/buildmanagerinfo.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/buildmanagerinfo.go
new file mode 100644
index 000000000..fa342ca13
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/buildmanagerinfo.go
@@ -0,0 +1,74 @@
+/*
+Copyright 2019 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 internal
+
+import (
+ "fmt"
+
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+type buildManagerInfoManager struct {
+ fieldManager Manager
+ groupVersion schema.GroupVersion
+ subresource string
+}
+
+var _ Manager = &buildManagerInfoManager{}
+
+// NewBuildManagerInfoManager creates a new Manager that converts the manager name into a unique identifier
+// combining operation and version for update requests, and just operation for apply requests.
+func NewBuildManagerInfoManager(f Manager, gv schema.GroupVersion, subresource string) Manager {
+ return &buildManagerInfoManager{
+ fieldManager: f,
+ groupVersion: gv,
+ subresource: subresource,
+ }
+}
+
+// Update implements Manager.
+func (f *buildManagerInfoManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
+ manager, err := f.buildManagerInfo(manager, metav1.ManagedFieldsOperationUpdate)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to build manager identifier: %v", err)
+ }
+ return f.fieldManager.Update(liveObj, newObj, managed, manager)
+}
+
+// Apply implements Manager.
+func (f *buildManagerInfoManager) Apply(liveObj, appliedObj runtime.Object, managed Managed, manager string, force bool) (runtime.Object, Managed, error) {
+ manager, err := f.buildManagerInfo(manager, metav1.ManagedFieldsOperationApply)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to build manager identifier: %v", err)
+ }
+ return f.fieldManager.Apply(liveObj, appliedObj, managed, manager, force)
+}
+
+func (f *buildManagerInfoManager) buildManagerInfo(prefix string, operation metav1.ManagedFieldsOperationType) (string, error) {
+ managerInfo := metav1.ManagedFieldsEntry{
+ Manager: prefix,
+ Operation: operation,
+ APIVersion: f.groupVersion.String(),
+ Subresource: f.subresource,
+ }
+ if managerInfo.Manager == "" {
+ managerInfo.Manager = "unknown"
+ }
+ return BuildManagerIdentifier(&managerInfo)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/capmanagers.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/capmanagers.go
new file mode 100644
index 000000000..8951932ba
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/capmanagers.go
@@ -0,0 +1,133 @@
+/*
+Copyright 2019 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 internal
+
+import (
+ "fmt"
+ "sort"
+
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+)
+
+type capManagersManager struct {
+ fieldManager Manager
+ maxUpdateManagers int
+ oldUpdatesManagerName string
+}
+
+var _ Manager = &capManagersManager{}
+
+// NewCapManagersManager creates a new wrapped FieldManager which ensures that the number of managers from updates
+// does not exceed maxUpdateManagers, by merging some of the oldest entries on each update.
+func NewCapManagersManager(fieldManager Manager, maxUpdateManagers int) Manager {
+ return &capManagersManager{
+ fieldManager: fieldManager,
+ maxUpdateManagers: maxUpdateManagers,
+ oldUpdatesManagerName: "ancient-changes",
+ }
+}
+
+// Update implements Manager.
+func (f *capManagersManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
+ object, managed, err := f.fieldManager.Update(liveObj, newObj, managed, manager)
+ if err != nil {
+ return object, managed, err
+ }
+ if managed, err = f.capUpdateManagers(managed); err != nil {
+ return nil, nil, fmt.Errorf("failed to cap update managers: %v", err)
+ }
+ return object, managed, nil
+}
+
+// Apply implements Manager.
+func (f *capManagersManager) Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) {
+ return f.fieldManager.Apply(liveObj, appliedObj, managed, fieldManager, force)
+}
+
+// capUpdateManagers merges a number of the oldest update entries into versioned buckets,
+// such that the number of entries from updates does not exceed f.maxUpdateManagers.
+func (f *capManagersManager) capUpdateManagers(managed Managed) (newManaged Managed, err error) {
+ // Gather all entries from updates
+ updaters := []string{}
+ for manager, fields := range managed.Fields() {
+ if !fields.Applied() {
+ updaters = append(updaters, manager)
+ }
+ }
+ if len(updaters) <= f.maxUpdateManagers {
+ return managed, nil
+ }
+
+ // If we have more than the maximum, sort the update entries by time, oldest first.
+ sort.Slice(updaters, func(i, j int) bool {
+ iTime, jTime, iSeconds, jSeconds := managed.Times()[updaters[i]], managed.Times()[updaters[j]], int64(0), int64(0)
+ if iTime != nil {
+ iSeconds = iTime.Unix()
+ }
+ if jTime != nil {
+ jSeconds = jTime.Unix()
+ }
+ if iSeconds != jSeconds {
+ return iSeconds < jSeconds
+ }
+ return updaters[i] < updaters[j]
+ })
+
+ // Merge the oldest updaters with versioned bucket managers until the number of updaters is under the cap
+ versionToFirstManager := map[string]string{}
+ for i, length := 0, len(updaters); i < len(updaters) && length > f.maxUpdateManagers; i++ {
+ manager := updaters[i]
+ vs := managed.Fields()[manager]
+ time := managed.Times()[manager]
+ version := string(vs.APIVersion())
+
+ // Create a new manager identifier for the versioned bucket entry.
+ // The version for this manager comes from the version of the update being merged into the bucket.
+ bucket, err := BuildManagerIdentifier(&metav1.ManagedFieldsEntry{
+ Manager: f.oldUpdatesManagerName,
+ Operation: metav1.ManagedFieldsOperationUpdate,
+ APIVersion: version,
+ })
+ if err != nil {
+ return managed, fmt.Errorf("failed to create bucket manager for version %v: %v", version, err)
+ }
+
+ // Merge the fieldets if this is not the first time the version was seen.
+ // Otherwise just record the manager name in versionToFirstManager
+ if first, ok := versionToFirstManager[version]; ok {
+ // If the bucket doesn't exists yet, create one.
+ if _, ok := managed.Fields()[bucket]; !ok {
+ s := managed.Fields()[first]
+ delete(managed.Fields(), first)
+ managed.Fields()[bucket] = s
+ }
+
+ managed.Fields()[bucket] = fieldpath.NewVersionedSet(vs.Set().Union(managed.Fields()[bucket].Set()), vs.APIVersion(), vs.Applied())
+ delete(managed.Fields(), manager)
+ length--
+
+ // Use the time from the update being merged into the bucket, since it is more recent.
+ managed.Times()[bucket] = time
+ } else {
+ versionToFirstManager[version] = manager
+ }
+ }
+
+ return managed, nil
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/conflict.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/conflict.go
new file mode 100644
index 000000000..8c044c915
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/conflict.go
@@ -0,0 +1,89 @@
+/*
+Copyright 2019 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 internal
+
+import (
+ "encoding/json"
+ "fmt"
+ "sort"
+ "strings"
+ "time"
+
+ "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v4/merge"
+)
+
+// NewConflictError returns an error including details on the requests apply conflicts
+func NewConflictError(conflicts merge.Conflicts) *errors.StatusError {
+ causes := []metav1.StatusCause{}
+ for _, conflict := range conflicts {
+ causes = append(causes, metav1.StatusCause{
+ Type: metav1.CauseTypeFieldManagerConflict,
+ Message: fmt.Sprintf("conflict with %v", printManager(conflict.Manager)),
+ Field: conflict.Path.String(),
+ })
+ }
+ return errors.NewApplyConflict(causes, getConflictMessage(conflicts))
+}
+
+func getConflictMessage(conflicts merge.Conflicts) string {
+ if len(conflicts) == 1 {
+ return fmt.Sprintf("Apply failed with 1 conflict: conflict with %v: %v", printManager(conflicts[0].Manager), conflicts[0].Path)
+ }
+
+ m := map[string][]fieldpath.Path{}
+ for _, conflict := range conflicts {
+ m[conflict.Manager] = append(m[conflict.Manager], conflict.Path)
+ }
+
+ uniqueManagers := []string{}
+ for manager := range m {
+ uniqueManagers = append(uniqueManagers, manager)
+ }
+
+ // Print conflicts by sorted managers.
+ sort.Strings(uniqueManagers)
+
+ messages := []string{}
+ for _, manager := range uniqueManagers {
+ messages = append(messages, fmt.Sprintf("conflicts with %v:", printManager(manager)))
+ for _, path := range m[manager] {
+ messages = append(messages, fmt.Sprintf("- %v", path))
+ }
+ }
+ return fmt.Sprintf("Apply failed with %d conflicts: %s", len(conflicts), strings.Join(messages, "\n"))
+}
+
+func printManager(manager string) string {
+ encodedManager := &metav1.ManagedFieldsEntry{}
+ if err := json.Unmarshal([]byte(manager), encodedManager); err != nil {
+ return fmt.Sprintf("%q", manager)
+ }
+ managerStr := fmt.Sprintf("%q", encodedManager.Manager)
+ if encodedManager.Subresource != "" {
+ managerStr = fmt.Sprintf("%s with subresource %q", managerStr, encodedManager.Subresource)
+ }
+ if encodedManager.Operation == metav1.ManagedFieldsOperationUpdate {
+ if encodedManager.Time == nil {
+ return fmt.Sprintf("%s using %v", managerStr, encodedManager.APIVersion)
+ }
+ return fmt.Sprintf("%s using %v at %v", managerStr, encodedManager.APIVersion, encodedManager.Time.UTC().Format(time.RFC3339))
+ }
+ return managerStr
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go
new file mode 100644
index 000000000..eca04a711
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go
@@ -0,0 +1,209 @@
+/*
+Copyright 2022 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 internal
+
+import (
+ "fmt"
+ "reflect"
+ "time"
+
+ "k8s.io/apimachinery/pkg/api/meta"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/klog/v2"
+ "sigs.k8s.io/structured-merge-diff/v4/merge"
+)
+
+// DefaultMaxUpdateManagers defines the default maximum retained number of managedFields entries from updates
+// if the number of update managers exceeds this, the oldest entries will be merged until the number is below the maximum.
+// TODO(jennybuckley): Determine if this is really the best value. Ideally we wouldn't unnecessarily merge too many entries.
+const DefaultMaxUpdateManagers int = 10
+
+// DefaultTrackOnCreateProbability defines the default probability that the field management of an object
+// starts being tracked from the object's creation, instead of from the first time the object is applied to.
+const DefaultTrackOnCreateProbability float32 = 1
+
+var atMostEverySecond = NewAtMostEvery(time.Second)
+
+// FieldManager updates the managed fields and merges applied
+// configurations.
+type FieldManager struct {
+ fieldManager Manager
+ subresource string
+}
+
+// NewFieldManager creates a new FieldManager that decodes, manages, then re-encodes managedFields
+// on update and apply requests.
+func NewFieldManager(f Manager, subresource string) *FieldManager {
+ return &FieldManager{fieldManager: f, subresource: subresource}
+}
+
+// newDefaultFieldManager is a helper function which wraps a Manager with certain default logic.
+func NewDefaultFieldManager(f Manager, typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, subresource string) *FieldManager {
+ return NewFieldManager(
+ NewVersionCheckManager(
+ NewLastAppliedUpdater(
+ NewLastAppliedManager(
+ NewProbabilisticSkipNonAppliedManager(
+ NewCapManagersManager(
+ NewBuildManagerInfoManager(
+ NewManagedFieldsUpdater(
+ NewStripMetaManager(f),
+ ), kind.GroupVersion(), subresource,
+ ), DefaultMaxUpdateManagers,
+ ), objectCreater, DefaultTrackOnCreateProbability,
+ ), typeConverter, objectConverter, kind.GroupVersion(),
+ ),
+ ), kind,
+ ), subresource,
+ )
+}
+
+func decodeLiveOrNew(liveObj, newObj runtime.Object, ignoreManagedFieldsFromRequestObject bool) (Managed, error) {
+ liveAccessor, err := meta.Accessor(liveObj)
+ if err != nil {
+ return nil, err
+ }
+
+ // We take the managedFields of the live object in case the request tries to
+ // manually set managedFields via a subresource.
+ if ignoreManagedFieldsFromRequestObject {
+ return emptyManagedFieldsOnErr(DecodeManagedFields(liveAccessor.GetManagedFields()))
+ }
+
+ // If the object doesn't have metadata, we should just return without trying to
+ // set the managedFields at all, so creates/updates/patches will work normally.
+ newAccessor, err := meta.Accessor(newObj)
+ if err != nil {
+ return nil, err
+ }
+
+ if isResetManagedFields(newAccessor.GetManagedFields()) {
+ return NewEmptyManaged(), nil
+ }
+
+ // If the managed field is empty or we failed to decode it,
+ // let's try the live object. This is to prevent clients who
+ // don't understand managedFields from deleting it accidentally.
+ managed, err := DecodeManagedFields(newAccessor.GetManagedFields())
+ if err != nil || len(managed.Fields()) == 0 {
+ return emptyManagedFieldsOnErr(DecodeManagedFields(liveAccessor.GetManagedFields()))
+ }
+ return managed, nil
+}
+
+func emptyManagedFieldsOnErr(managed Managed, err error) (Managed, error) {
+ if err != nil {
+ return NewEmptyManaged(), nil
+ }
+ return managed, nil
+}
+
+// Update is used when the object has already been merged (non-apply
+// use-case), and simply updates the managed fields in the output
+// object.
+func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (object runtime.Object, err error) {
+ // First try to decode the managed fields provided in the update,
+ // This is necessary to allow directly updating managed fields.
+ isSubresource := f.subresource != ""
+ managed, err := decodeLiveOrNew(liveObj, newObj, isSubresource)
+ if err != nil {
+ return newObj, nil
+ }
+
+ RemoveObjectManagedFields(newObj)
+
+ if object, managed, err = f.fieldManager.Update(liveObj, newObj, managed, manager); err != nil {
+ return nil, err
+ }
+
+ if err = EncodeObjectManagedFields(object, managed); err != nil {
+ return nil, fmt.Errorf("failed to encode managed fields: %v", err)
+ }
+
+ return object, nil
+}
+
+// UpdateNoErrors is the same as Update, but it will not return
+// errors. If an error happens, the object is returned with
+// managedFields cleared.
+func (f *FieldManager) UpdateNoErrors(liveObj, newObj runtime.Object, manager string) runtime.Object {
+ obj, err := f.Update(liveObj, newObj, manager)
+ if err != nil {
+ atMostEverySecond.Do(func() {
+ ns, name := "unknown", "unknown"
+ if accessor, err := meta.Accessor(newObj); err == nil {
+ ns = accessor.GetNamespace()
+ name = accessor.GetName()
+ }
+
+ klog.ErrorS(err, "[SHOULD NOT HAPPEN] failed to update managedFields", "versionKind",
+ newObj.GetObjectKind().GroupVersionKind(), "namespace", ns, "name", name)
+ })
+ // Explicitly remove managedFields on failure, so that
+ // we can't have garbage in it.
+ RemoveObjectManagedFields(newObj)
+ return newObj
+ }
+ return obj
+}
+
+// Returns true if the managedFields indicate that the user is trying to
+// reset the managedFields, i.e. if the list is non-nil but empty, or if
+// the list has one empty item.
+func isResetManagedFields(managedFields []metav1.ManagedFieldsEntry) bool {
+ if len(managedFields) == 0 {
+ return managedFields != nil
+ }
+
+ if len(managedFields) == 1 {
+ return reflect.DeepEqual(managedFields[0], metav1.ManagedFieldsEntry{})
+ }
+
+ return false
+}
+
+// Apply is used when server-side apply is called, as it merges the
+// object and updates the managed fields.
+func (f *FieldManager) Apply(liveObj, appliedObj runtime.Object, manager string, force bool) (object runtime.Object, err error) {
+ // If the object doesn't have metadata, apply isn't allowed.
+ accessor, err := meta.Accessor(liveObj)
+ if err != nil {
+ return nil, fmt.Errorf("couldn't get accessor: %v", err)
+ }
+
+ // Decode the managed fields in the live object, since it isn't allowed in the patch.
+ managed, err := DecodeManagedFields(accessor.GetManagedFields())
+ if err != nil {
+ return nil, fmt.Errorf("failed to decode managed fields: %v", err)
+ }
+
+ object, managed, err = f.fieldManager.Apply(liveObj, appliedObj, managed, manager, force)
+ if err != nil {
+ if conflicts, ok := err.(merge.Conflicts); ok {
+ return nil, NewConflictError(conflicts)
+ }
+ return nil, err
+ }
+
+ if err = EncodeObjectManagedFields(object, managed); err != nil {
+ return nil, fmt.Errorf("failed to encode managed fields: %v", err)
+ }
+
+ return object, nil
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go
new file mode 100644
index 000000000..08186191a
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go
@@ -0,0 +1,47 @@
+/*
+Copyright 2018 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 internal
+
+import (
+ "bytes"
+
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+)
+
+// EmptyFields represents a set with no paths
+// It looks like metav1.Fields{Raw: []byte("{}")}
+var EmptyFields = func() metav1.FieldsV1 {
+ f, err := SetToFields(*fieldpath.NewSet())
+ if err != nil {
+ panic("should never happen")
+ }
+ return f
+}()
+
+// FieldsToSet creates a set paths from an input trie of fields
+func FieldsToSet(f metav1.FieldsV1) (s fieldpath.Set, err error) {
+ err = s.FromJSON(bytes.NewReader(f.Raw))
+ return s, err
+}
+
+// SetToFields creates a trie of fields from an input set of paths
+func SetToFields(s fieldpath.Set) (f metav1.FieldsV1, err error) {
+ f.Raw, err = s.ToJSON()
+ return f, err
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastapplied.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastapplied.go
new file mode 100644
index 000000000..b00b6b829
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastapplied.go
@@ -0,0 +1,50 @@
+/*
+Copyright 2022 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 internal
+
+import (
+ "fmt"
+
+ "k8s.io/apimachinery/pkg/api/meta"
+ apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
+ "k8s.io/apimachinery/pkg/runtime"
+)
+
+// LastAppliedConfigAnnotation is the annotation used to store the previous
+// configuration of a resource for use in a three way diff by UpdateApplyAnnotation.
+//
+// This is a copy of the corev1 annotation since we don't want to depend on the whole package.
+const LastAppliedConfigAnnotation = "kubectl.kubernetes.io/last-applied-configuration"
+
+// SetLastApplied sets the last-applied annotation the given value in
+// the object.
+func SetLastApplied(obj runtime.Object, value string) error {
+ accessor, err := meta.Accessor(obj)
+ if err != nil {
+ panic(fmt.Sprintf("couldn't get accessor: %v", err))
+ }
+ var annotations = accessor.GetAnnotations()
+ if annotations == nil {
+ annotations = map[string]string{}
+ }
+ annotations[LastAppliedConfigAnnotation] = value
+ if err := apimachineryvalidation.ValidateAnnotationsSize(annotations); err != nil {
+ delete(annotations, LastAppliedConfigAnnotation)
+ }
+ accessor.SetAnnotations(annotations)
+ return nil
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedmanager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedmanager.go
new file mode 100644
index 000000000..3f6cf8821
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedmanager.go
@@ -0,0 +1,171 @@
+/*
+Copyright 2020 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 internal
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "k8s.io/apimachinery/pkg/api/meta"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v4/merge"
+)
+
+type lastAppliedManager struct {
+ fieldManager Manager
+ typeConverter TypeConverter
+ objectConverter runtime.ObjectConvertor
+ groupVersion schema.GroupVersion
+}
+
+var _ Manager = &lastAppliedManager{}
+
+// NewLastAppliedManager converts the client-side apply annotation to
+// server-side apply managed fields
+func NewLastAppliedManager(fieldManager Manager, typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, groupVersion schema.GroupVersion) Manager {
+ return &lastAppliedManager{
+ fieldManager: fieldManager,
+ typeConverter: typeConverter,
+ objectConverter: objectConverter,
+ groupVersion: groupVersion,
+ }
+}
+
+// Update implements Manager.
+func (f *lastAppliedManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
+ return f.fieldManager.Update(liveObj, newObj, managed, manager)
+}
+
+// Apply will consider the last-applied annotation
+// for upgrading an object managed by client-side apply to server-side apply
+// without conflicts.
+func (f *lastAppliedManager) Apply(liveObj, newObj runtime.Object, managed Managed, manager string, force bool) (runtime.Object, Managed, error) {
+ newLiveObj, newManaged, newErr := f.fieldManager.Apply(liveObj, newObj, managed, manager, force)
+ // Upgrade the client-side apply annotation only from kubectl server-side-apply.
+ // To opt-out of this behavior, users may specify a different field manager.
+ if manager != "kubectl" {
+ return newLiveObj, newManaged, newErr
+ }
+
+ // Check if we have conflicts
+ if newErr == nil {
+ return newLiveObj, newManaged, newErr
+ }
+ conflicts, ok := newErr.(merge.Conflicts)
+ if !ok {
+ return newLiveObj, newManaged, newErr
+ }
+ conflictSet := conflictsToSet(conflicts)
+
+ // Check if conflicts are allowed due to client-side apply,
+ // and if so, then force apply
+ allowedConflictSet, err := f.allowedConflictsFromLastApplied(liveObj)
+ if err != nil {
+ return newLiveObj, newManaged, newErr
+ }
+ if !conflictSet.Difference(allowedConflictSet).Empty() {
+ newConflicts := conflictsDifference(conflicts, allowedConflictSet)
+ return newLiveObj, newManaged, newConflicts
+ }
+
+ return f.fieldManager.Apply(liveObj, newObj, managed, manager, true)
+}
+
+func (f *lastAppliedManager) allowedConflictsFromLastApplied(liveObj runtime.Object) (*fieldpath.Set, error) {
+ var accessor, err = meta.Accessor(liveObj)
+ if err != nil {
+ panic(fmt.Sprintf("couldn't get accessor: %v", err))
+ }
+
+ // If there is no client-side apply annotation, then there is nothing to do
+ var annotations = accessor.GetAnnotations()
+ if annotations == nil {
+ return nil, fmt.Errorf("no last applied annotation")
+ }
+ var lastApplied, ok = annotations[LastAppliedConfigAnnotation]
+ if !ok || lastApplied == "" {
+ return nil, fmt.Errorf("no last applied annotation")
+ }
+
+ liveObjVersioned, err := f.objectConverter.ConvertToVersion(liveObj, f.groupVersion)
+ if err != nil {
+ return nil, fmt.Errorf("failed to convert live obj to versioned: %v", err)
+ }
+
+ liveObjTyped, err := f.typeConverter.ObjectToTyped(liveObjVersioned)
+ if err != nil {
+ return nil, fmt.Errorf("failed to convert live obj to typed: %v", err)
+ }
+
+ var lastAppliedObj = &unstructured.Unstructured{Object: map[string]interface{}{}}
+ err = json.Unmarshal([]byte(lastApplied), lastAppliedObj)
+ if err != nil {
+ return nil, fmt.Errorf("failed to decode last applied obj: %v in '%s'", err, lastApplied)
+ }
+
+ if lastAppliedObj.GetAPIVersion() != f.groupVersion.String() {
+ return nil, fmt.Errorf("expected version of last applied to match live object '%s', but got '%s': %v", f.groupVersion.String(), lastAppliedObj.GetAPIVersion(), err)
+ }
+
+ lastAppliedObjTyped, err := f.typeConverter.ObjectToTyped(lastAppliedObj)
+ if err != nil {
+ return nil, fmt.Errorf("failed to convert last applied to typed: %v", err)
+ }
+
+ lastAppliedObjFieldSet, err := lastAppliedObjTyped.ToFieldSet()
+ if err != nil {
+ return nil, fmt.Errorf("failed to create fieldset for last applied object: %v", err)
+ }
+
+ comparison, err := lastAppliedObjTyped.Compare(liveObjTyped)
+ if err != nil {
+ return nil, fmt.Errorf("failed to compare last applied object and live object: %v", err)
+ }
+
+ // Remove fields in last applied that are different, added, or missing in
+ // the live object.
+ // Because last-applied fields don't match the live object fields,
+ // then we don't own these fields.
+ lastAppliedObjFieldSet = lastAppliedObjFieldSet.
+ Difference(comparison.Modified).
+ Difference(comparison.Added).
+ Difference(comparison.Removed)
+
+ return lastAppliedObjFieldSet, nil
+}
+
+// TODO: replace with merge.Conflicts.ToSet()
+func conflictsToSet(conflicts merge.Conflicts) *fieldpath.Set {
+ conflictSet := fieldpath.NewSet()
+ for _, conflict := range []merge.Conflict(conflicts) {
+ conflictSet.Insert(conflict.Path)
+ }
+ return conflictSet
+}
+
+func conflictsDifference(conflicts merge.Conflicts, s *fieldpath.Set) merge.Conflicts {
+ newConflicts := []merge.Conflict{}
+ for _, conflict := range []merge.Conflict(conflicts) {
+ if !s.Has(conflict.Path) {
+ newConflicts = append(newConflicts, conflict)
+ }
+ }
+ return newConflicts
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedupdater.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedupdater.go
new file mode 100644
index 000000000..06e6c5d8c
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedupdater.go
@@ -0,0 +1,102 @@
+/*
+Copyright 2020 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 internal
+
+import (
+ "fmt"
+
+ "k8s.io/apimachinery/pkg/api/meta"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime"
+)
+
+type lastAppliedUpdater struct {
+ fieldManager Manager
+}
+
+var _ Manager = &lastAppliedUpdater{}
+
+// NewLastAppliedUpdater sets the client-side apply annotation up to date with
+// server-side apply managed fields
+func NewLastAppliedUpdater(fieldManager Manager) Manager {
+ return &lastAppliedUpdater{
+ fieldManager: fieldManager,
+ }
+}
+
+// Update implements Manager.
+func (f *lastAppliedUpdater) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
+ return f.fieldManager.Update(liveObj, newObj, managed, manager)
+}
+
+// server-side apply managed fields
+func (f *lastAppliedUpdater) Apply(liveObj, newObj runtime.Object, managed Managed, manager string, force bool) (runtime.Object, Managed, error) {
+ liveObj, managed, err := f.fieldManager.Apply(liveObj, newObj, managed, manager, force)
+ if err != nil {
+ return liveObj, managed, err
+ }
+
+ // Sync the client-side apply annotation only from kubectl server-side apply.
+ // To opt-out of this behavior, users may specify a different field manager.
+ //
+ // If the client-side apply annotation doesn't exist,
+ // then continue because we have no annotation to update
+ if manager == "kubectl" && hasLastApplied(liveObj) {
+ lastAppliedValue, err := buildLastApplied(newObj)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to build last-applied annotation: %v", err)
+ }
+ err = SetLastApplied(liveObj, lastAppliedValue)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to set last-applied annotation: %v", err)
+ }
+ }
+ return liveObj, managed, err
+}
+
+func hasLastApplied(obj runtime.Object) bool {
+ var accessor, err = meta.Accessor(obj)
+ if err != nil {
+ panic(fmt.Sprintf("couldn't get accessor: %v", err))
+ }
+ var annotations = accessor.GetAnnotations()
+ if annotations == nil {
+ return false
+ }
+ lastApplied, ok := annotations[LastAppliedConfigAnnotation]
+ return ok && len(lastApplied) > 0
+}
+
+func buildLastApplied(obj runtime.Object) (string, error) {
+ obj = obj.DeepCopyObject()
+
+ var accessor, err = meta.Accessor(obj)
+ if err != nil {
+ panic(fmt.Sprintf("couldn't get accessor: %v", err))
+ }
+
+ // Remove the annotation from the object before encoding the object
+ var annotations = accessor.GetAnnotations()
+ delete(annotations, LastAppliedConfigAnnotation)
+ accessor.SetAnnotations(annotations)
+
+ lastApplied, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
+ if err != nil {
+ return "", fmt.Errorf("couldn't encode object into last applied annotation: %v", err)
+ }
+ return string(lastApplied), nil
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfields.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfields.go
new file mode 100644
index 000000000..9b4c20326
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfields.go
@@ -0,0 +1,248 @@
+/*
+Copyright 2018 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 internal
+
+import (
+ "encoding/json"
+ "fmt"
+ "sort"
+
+ "k8s.io/apimachinery/pkg/api/meta"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+)
+
+// ManagedInterface groups a fieldpath.ManagedFields together with the timestamps associated with each operation.
+type ManagedInterface interface {
+ // Fields gets the fieldpath.ManagedFields.
+ Fields() fieldpath.ManagedFields
+
+ // Times gets the timestamps associated with each operation.
+ Times() map[string]*metav1.Time
+}
+
+type managedStruct struct {
+ fields fieldpath.ManagedFields
+ times map[string]*metav1.Time
+}
+
+var _ ManagedInterface = &managedStruct{}
+
+// Fields implements ManagedInterface.
+func (m *managedStruct) Fields() fieldpath.ManagedFields {
+ return m.fields
+}
+
+// Times implements ManagedInterface.
+func (m *managedStruct) Times() map[string]*metav1.Time {
+ return m.times
+}
+
+// NewEmptyManaged creates an empty ManagedInterface.
+func NewEmptyManaged() ManagedInterface {
+ return NewManaged(fieldpath.ManagedFields{}, map[string]*metav1.Time{})
+}
+
+// NewManaged creates a ManagedInterface from a fieldpath.ManagedFields and the timestamps associated with each operation.
+func NewManaged(f fieldpath.ManagedFields, t map[string]*metav1.Time) ManagedInterface {
+ return &managedStruct{
+ fields: f,
+ times: t,
+ }
+}
+
+// RemoveObjectManagedFields removes the ManagedFields from the object
+// before we merge so that it doesn't appear in the ManagedFields
+// recursively.
+func RemoveObjectManagedFields(obj runtime.Object) {
+ accessor, err := meta.Accessor(obj)
+ if err != nil {
+ panic(fmt.Sprintf("couldn't get accessor: %v", err))
+ }
+ accessor.SetManagedFields(nil)
+}
+
+// EncodeObjectManagedFields converts and stores the fieldpathManagedFields into the objects ManagedFields
+func EncodeObjectManagedFields(obj runtime.Object, managed ManagedInterface) error {
+ accessor, err := meta.Accessor(obj)
+ if err != nil {
+ panic(fmt.Sprintf("couldn't get accessor: %v", err))
+ }
+
+ encodedManagedFields, err := encodeManagedFields(managed)
+ if err != nil {
+ return fmt.Errorf("failed to convert back managed fields to API: %v", err)
+ }
+ accessor.SetManagedFields(encodedManagedFields)
+
+ return nil
+}
+
+// DecodeManagedFields converts ManagedFields from the wire format (api format)
+// to the format used by sigs.k8s.io/structured-merge-diff
+func DecodeManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) (ManagedInterface, error) {
+ managed := managedStruct{}
+ managed.fields = make(fieldpath.ManagedFields, len(encodedManagedFields))
+ managed.times = make(map[string]*metav1.Time, len(encodedManagedFields))
+
+ for i, encodedVersionedSet := range encodedManagedFields {
+ switch encodedVersionedSet.Operation {
+ case metav1.ManagedFieldsOperationApply, metav1.ManagedFieldsOperationUpdate:
+ default:
+ return nil, fmt.Errorf("operation must be `Apply` or `Update`")
+ }
+ if len(encodedVersionedSet.APIVersion) < 1 {
+ return nil, fmt.Errorf("apiVersion must not be empty")
+ }
+ switch encodedVersionedSet.FieldsType {
+ case "FieldsV1":
+ // Valid case.
+ case "":
+ return nil, fmt.Errorf("missing fieldsType in managed fields entry %d", i)
+ default:
+ return nil, fmt.Errorf("invalid fieldsType %q in managed fields entry %d", encodedVersionedSet.FieldsType, i)
+ }
+ manager, err := BuildManagerIdentifier(&encodedVersionedSet)
+ if err != nil {
+ return nil, fmt.Errorf("error decoding manager from %v: %v", encodedVersionedSet, err)
+ }
+ managed.fields[manager], err = decodeVersionedSet(&encodedVersionedSet)
+ if err != nil {
+ return nil, fmt.Errorf("error decoding versioned set from %v: %v", encodedVersionedSet, err)
+ }
+ managed.times[manager] = encodedVersionedSet.Time
+ }
+ return &managed, nil
+}
+
+// BuildManagerIdentifier creates a manager identifier string from a ManagedFieldsEntry
+func BuildManagerIdentifier(encodedManager *metav1.ManagedFieldsEntry) (manager string, err error) {
+ encodedManagerCopy := *encodedManager
+
+ // Never include fields type in the manager identifier
+ encodedManagerCopy.FieldsType = ""
+
+ // Never include the fields in the manager identifier
+ encodedManagerCopy.FieldsV1 = nil
+
+ // Never include the time in the manager identifier
+ encodedManagerCopy.Time = nil
+
+ // For appliers, don't include the APIVersion in the manager identifier,
+ // so it will always have the same manager identifier each time it applied.
+ if encodedManager.Operation == metav1.ManagedFieldsOperationApply {
+ encodedManagerCopy.APIVersion = ""
+ }
+
+ // Use the remaining fields to build the manager identifier
+ b, err := json.Marshal(&encodedManagerCopy)
+ if err != nil {
+ return "", fmt.Errorf("error marshalling manager identifier: %v", err)
+ }
+
+ return string(b), nil
+}
+
+func decodeVersionedSet(encodedVersionedSet *metav1.ManagedFieldsEntry) (versionedSet fieldpath.VersionedSet, err error) {
+ fields := EmptyFields
+ if encodedVersionedSet.FieldsV1 != nil {
+ fields = *encodedVersionedSet.FieldsV1
+ }
+ set, err := FieldsToSet(fields)
+ if err != nil {
+ return nil, fmt.Errorf("error decoding set: %v", err)
+ }
+ return fieldpath.NewVersionedSet(&set, fieldpath.APIVersion(encodedVersionedSet.APIVersion), encodedVersionedSet.Operation == metav1.ManagedFieldsOperationApply), nil
+}
+
+// encodeManagedFields converts ManagedFields from the format used by
+// sigs.k8s.io/structured-merge-diff to the wire format (api format)
+func encodeManagedFields(managed ManagedInterface) (encodedManagedFields []metav1.ManagedFieldsEntry, err error) {
+ if len(managed.Fields()) == 0 {
+ return nil, nil
+ }
+ encodedManagedFields = []metav1.ManagedFieldsEntry{}
+ for manager := range managed.Fields() {
+ versionedSet := managed.Fields()[manager]
+ v, err := encodeManagerVersionedSet(manager, versionedSet)
+ if err != nil {
+ return nil, fmt.Errorf("error encoding versioned set for %v: %v", manager, err)
+ }
+ if t, ok := managed.Times()[manager]; ok {
+ v.Time = t
+ }
+ encodedManagedFields = append(encodedManagedFields, *v)
+ }
+ return sortEncodedManagedFields(encodedManagedFields)
+}
+
+func sortEncodedManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) (sortedManagedFields []metav1.ManagedFieldsEntry, err error) {
+ sort.Slice(encodedManagedFields, func(i, j int) bool {
+ p, q := encodedManagedFields[i], encodedManagedFields[j]
+
+ if p.Operation != q.Operation {
+ return p.Operation < q.Operation
+ }
+
+ pSeconds, qSeconds := int64(0), int64(0)
+ if p.Time != nil {
+ pSeconds = p.Time.Unix()
+ }
+ if q.Time != nil {
+ qSeconds = q.Time.Unix()
+ }
+ if pSeconds != qSeconds {
+ return pSeconds < qSeconds
+ }
+
+ if p.Manager != q.Manager {
+ return p.Manager < q.Manager
+ }
+
+ if p.APIVersion != q.APIVersion {
+ return p.APIVersion < q.APIVersion
+ }
+ return p.Subresource < q.Subresource
+ })
+
+ return encodedManagedFields, nil
+}
+
+func encodeManagerVersionedSet(manager string, versionedSet fieldpath.VersionedSet) (encodedVersionedSet *metav1.ManagedFieldsEntry, err error) {
+ encodedVersionedSet = &metav1.ManagedFieldsEntry{}
+
+ // Get as many fields as we can from the manager identifier
+ err = json.Unmarshal([]byte(manager), encodedVersionedSet)
+ if err != nil {
+ return nil, fmt.Errorf("error unmarshalling manager identifier %v: %v", manager, err)
+ }
+
+ // Get the APIVersion, Operation, and Fields from the VersionedSet
+ encodedVersionedSet.APIVersion = string(versionedSet.APIVersion())
+ if versionedSet.Applied() {
+ encodedVersionedSet.Operation = metav1.ManagedFieldsOperationApply
+ }
+ encodedVersionedSet.FieldsType = "FieldsV1"
+ fields, err := SetToFields(*versionedSet.Set())
+ if err != nil {
+ return nil, fmt.Errorf("error encoding set: %v", err)
+ }
+ encodedVersionedSet.FieldsV1 = &fields
+
+ return encodedVersionedSet, nil
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfieldsupdater.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfieldsupdater.go
new file mode 100644
index 000000000..376eed6b2
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfieldsupdater.go
@@ -0,0 +1,82 @@
+/*
+Copyright 2020 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 internal
+
+import (
+ "time"
+
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+)
+
+type managedFieldsUpdater struct {
+ fieldManager Manager
+}
+
+var _ Manager = &managedFieldsUpdater{}
+
+// NewManagedFieldsUpdater is responsible for updating the managedfields
+// in the object, updating the time of the operation as necessary. For
+// updates, it uses a hard-coded manager to detect if things have
+// changed, and swaps back the correct manager after the operation is
+// done.
+func NewManagedFieldsUpdater(fieldManager Manager) Manager {
+ return &managedFieldsUpdater{
+ fieldManager: fieldManager,
+ }
+}
+
+// Update implements Manager.
+func (f *managedFieldsUpdater) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
+ self := "current-operation"
+ object, managed, err := f.fieldManager.Update(liveObj, newObj, managed, self)
+ if err != nil {
+ return object, managed, err
+ }
+
+ // If the current operation took any fields from anything, it means the object changed,
+ // so update the timestamp of the managedFieldsEntry and merge with any previous updates from the same manager
+ if vs, ok := managed.Fields()[self]; ok {
+ delete(managed.Fields(), self)
+
+ if previous, ok := managed.Fields()[manager]; ok {
+ managed.Fields()[manager] = fieldpath.NewVersionedSet(vs.Set().Union(previous.Set()), vs.APIVersion(), vs.Applied())
+ } else {
+ managed.Fields()[manager] = vs
+ }
+
+ managed.Times()[manager] = &metav1.Time{Time: time.Now().UTC()}
+ }
+
+ return object, managed, nil
+}
+
+// Apply implements Manager.
+func (f *managedFieldsUpdater) Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) {
+ object, managed, err := f.fieldManager.Apply(liveObj, appliedObj, managed, fieldManager, force)
+ if err != nil {
+ return object, managed, err
+ }
+ if object != nil {
+ managed.Times()[fieldManager] = &metav1.Time{Time: time.Now().UTC()}
+ } else {
+ object = liveObj.DeepCopyObject()
+ RemoveObjectManagedFields(object)
+ }
+ return object, managed, nil
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/manager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/manager.go
new file mode 100644
index 000000000..053936103
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/manager.go
@@ -0,0 +1,52 @@
+/*
+Copyright 2022 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 internal
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+)
+
+// Managed groups a fieldpath.ManagedFields together with the timestamps associated with each operation.
+type Managed interface {
+ // Fields gets the fieldpath.ManagedFields.
+ Fields() fieldpath.ManagedFields
+
+ // Times gets the timestamps associated with each operation.
+ Times() map[string]*metav1.Time
+}
+
+// Manager updates the managed fields and merges applied configurations.
+type Manager interface {
+ // Update is used when the object has already been merged (non-apply
+ // use-case), and simply updates the managed fields in the output
+ // object.
+ // * `liveObj` is not mutated by this function
+ // * `newObj` may be mutated by this function
+ // Returns the new object with managedFields removed, and the object's new
+ // proposed managedFields separately.
+ Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error)
+
+ // Apply is used when server-side apply is called, as it merges the
+ // object and updates the managed fields.
+ // * `liveObj` is not mutated by this function
+ // * `newObj` may be mutated by this function
+ // Returns the new object with managedFields removed, and the object's new
+ // proposed managedFields separately.
+ Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/pathelement.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/pathelement.go
new file mode 100644
index 000000000..1954d65d3
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/pathelement.go
@@ -0,0 +1,140 @@
+/*
+Copyright 2018 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 internal
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "strconv"
+ "strings"
+
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v4/value"
+)
+
+const (
+ // Field indicates that the content of this path element is a field's name
+ Field = "f"
+
+ // Value indicates that the content of this path element is a field's value
+ Value = "v"
+
+ // Index indicates that the content of this path element is an index in an array
+ Index = "i"
+
+ // Key indicates that the content of this path element is a key value map
+ Key = "k"
+
+ // Separator separates the type of a path element from the contents
+ Separator = ":"
+)
+
+// NewPathElement parses a serialized path element
+func NewPathElement(s string) (fieldpath.PathElement, error) {
+ split := strings.SplitN(s, Separator, 2)
+ if len(split) < 2 {
+ return fieldpath.PathElement{}, fmt.Errorf("missing colon: %v", s)
+ }
+ switch split[0] {
+ case Field:
+ return fieldpath.PathElement{
+ FieldName: &split[1],
+ }, nil
+ case Value:
+ val, err := value.FromJSON([]byte(split[1]))
+ if err != nil {
+ return fieldpath.PathElement{}, err
+ }
+ return fieldpath.PathElement{
+ Value: &val,
+ }, nil
+ case Index:
+ i, err := strconv.Atoi(split[1])
+ if err != nil {
+ return fieldpath.PathElement{}, err
+ }
+ return fieldpath.PathElement{
+ Index: &i,
+ }, nil
+ case Key:
+ kv := map[string]json.RawMessage{}
+ err := json.Unmarshal([]byte(split[1]), &kv)
+ if err != nil {
+ return fieldpath.PathElement{}, err
+ }
+ fields := value.FieldList{}
+ for k, v := range kv {
+ b, err := json.Marshal(v)
+ if err != nil {
+ return fieldpath.PathElement{}, err
+ }
+ val, err := value.FromJSON(b)
+ if err != nil {
+ return fieldpath.PathElement{}, err
+ }
+
+ fields = append(fields, value.Field{
+ Name: k,
+ Value: val,
+ })
+ }
+ return fieldpath.PathElement{
+ Key: &fields,
+ }, nil
+ default:
+ // Ignore unknown key types
+ return fieldpath.PathElement{}, nil
+ }
+}
+
+// PathElementString serializes a path element
+func PathElementString(pe fieldpath.PathElement) (string, error) {
+ switch {
+ case pe.FieldName != nil:
+ return Field + Separator + *pe.FieldName, nil
+ case pe.Key != nil:
+ kv := map[string]json.RawMessage{}
+ for _, k := range *pe.Key {
+ b, err := value.ToJSON(k.Value)
+ if err != nil {
+ return "", err
+ }
+ m := json.RawMessage{}
+ err = json.Unmarshal(b, &m)
+ if err != nil {
+ return "", err
+ }
+ kv[k.Name] = m
+ }
+ b, err := json.Marshal(kv)
+ if err != nil {
+ return "", err
+ }
+ return Key + ":" + string(b), nil
+ case pe.Value != nil:
+ b, err := value.ToJSON(*pe.Value)
+ if err != nil {
+ return "", err
+ }
+ return Value + ":" + string(b), nil
+ case pe.Index != nil:
+ return Index + ":" + strconv.Itoa(*pe.Index), nil
+ default:
+ return "", errors.New("Invalid type of path element")
+ }
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/skipnonapplied.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/skipnonapplied.go
new file mode 100644
index 000000000..f24c040ed
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/skipnonapplied.go
@@ -0,0 +1,89 @@
+/*
+Copyright 2019 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 internal
+
+import (
+ "fmt"
+ "math/rand"
+
+ "k8s.io/apimachinery/pkg/api/meta"
+ "k8s.io/apimachinery/pkg/runtime"
+)
+
+type skipNonAppliedManager struct {
+ fieldManager Manager
+ objectCreater runtime.ObjectCreater
+ beforeApplyManagerName string
+ probability float32
+}
+
+var _ Manager = &skipNonAppliedManager{}
+
+// NewSkipNonAppliedManager creates a new wrapped FieldManager that only starts tracking managers after the first apply.
+func NewSkipNonAppliedManager(fieldManager Manager, objectCreater runtime.ObjectCreater) Manager {
+ return NewProbabilisticSkipNonAppliedManager(fieldManager, objectCreater, 0.0)
+}
+
+// NewProbabilisticSkipNonAppliedManager creates a new wrapped FieldManager that starts tracking managers after the first apply,
+// or starts tracking on create with p probability.
+func NewProbabilisticSkipNonAppliedManager(fieldManager Manager, objectCreater runtime.ObjectCreater, p float32) Manager {
+ return &skipNonAppliedManager{
+ fieldManager: fieldManager,
+ objectCreater: objectCreater,
+ beforeApplyManagerName: "before-first-apply",
+ probability: p,
+ }
+}
+
+// Update implements Manager.
+func (f *skipNonAppliedManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
+ accessor, err := meta.Accessor(liveObj)
+ if err != nil {
+ return newObj, managed, nil
+ }
+
+ // If managed fields is empty, we need to determine whether to skip tracking managed fields.
+ if len(managed.Fields()) == 0 {
+ // Check if the operation is a create, by checking whether lastObj's UID is empty.
+ // If the operation is create, P(tracking managed fields) = f.probability
+ // If the operation is update, skip tracking managed fields, since we already know managed fields is empty.
+ if len(accessor.GetUID()) == 0 {
+ if f.probability <= rand.Float32() {
+ return newObj, managed, nil
+ }
+ } else {
+ return newObj, managed, nil
+ }
+ }
+ return f.fieldManager.Update(liveObj, newObj, managed, manager)
+}
+
+// Apply implements Manager.
+func (f *skipNonAppliedManager) Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) {
+ if len(managed.Fields()) == 0 {
+ gvk := appliedObj.GetObjectKind().GroupVersionKind()
+ emptyObj, err := f.objectCreater.New(gvk)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to create empty object of type %v: %v", gvk, err)
+ }
+ liveObj, managed, err = f.fieldManager.Update(emptyObj, liveObj, managed, f.beforeApplyManagerName)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to create manager for existing fields: %v", err)
+ }
+ }
+ return f.fieldManager.Apply(liveObj, appliedObj, managed, fieldManager, force)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/stripmeta.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/stripmeta.go
new file mode 100644
index 000000000..9b61f3a6f
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/stripmeta.go
@@ -0,0 +1,90 @@
+/*
+Copyright 2019 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 internal
+
+import (
+ "fmt"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+)
+
+type stripMetaManager struct {
+ fieldManager Manager
+
+ // stripSet is the list of fields that should never be part of a mangedFields.
+ stripSet *fieldpath.Set
+}
+
+var _ Manager = &stripMetaManager{}
+
+// NewStripMetaManager creates a new Manager that strips metadata and typemeta fields from the manager's fieldset.
+func NewStripMetaManager(fieldManager Manager) Manager {
+ return &stripMetaManager{
+ fieldManager: fieldManager,
+ stripSet: fieldpath.NewSet(
+ fieldpath.MakePathOrDie("apiVersion"),
+ fieldpath.MakePathOrDie("kind"),
+ fieldpath.MakePathOrDie("metadata"),
+ fieldpath.MakePathOrDie("metadata", "name"),
+ fieldpath.MakePathOrDie("metadata", "namespace"),
+ fieldpath.MakePathOrDie("metadata", "creationTimestamp"),
+ fieldpath.MakePathOrDie("metadata", "selfLink"),
+ fieldpath.MakePathOrDie("metadata", "uid"),
+ fieldpath.MakePathOrDie("metadata", "clusterName"),
+ fieldpath.MakePathOrDie("metadata", "generation"),
+ fieldpath.MakePathOrDie("metadata", "managedFields"),
+ fieldpath.MakePathOrDie("metadata", "resourceVersion"),
+ ),
+ }
+}
+
+// Update implements Manager.
+func (f *stripMetaManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
+ newObj, managed, err := f.fieldManager.Update(liveObj, newObj, managed, manager)
+ if err != nil {
+ return nil, nil, err
+ }
+ f.stripFields(managed.Fields(), manager)
+ return newObj, managed, nil
+}
+
+// Apply implements Manager.
+func (f *stripMetaManager) Apply(liveObj, appliedObj runtime.Object, managed Managed, manager string, force bool) (runtime.Object, Managed, error) {
+ newObj, managed, err := f.fieldManager.Apply(liveObj, appliedObj, managed, manager, force)
+ if err != nil {
+ return nil, nil, err
+ }
+ f.stripFields(managed.Fields(), manager)
+ return newObj, managed, nil
+}
+
+// stripFields removes a predefined set of paths found in typed from managed
+func (f *stripMetaManager) stripFields(managed fieldpath.ManagedFields, manager string) {
+ vs, ok := managed[manager]
+ if ok {
+ if vs == nil {
+ panic(fmt.Sprintf("Found unexpected nil manager which should never happen: %s", manager))
+ }
+ newSet := vs.Set().Difference(f.stripSet)
+ if newSet.Empty() {
+ delete(managed, manager)
+ } else {
+ managed[manager] = fieldpath.NewVersionedSet(newSet, vs.APIVersion(), vs.Applied())
+ }
+ }
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/structuredmerge.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/structuredmerge.go
new file mode 100644
index 000000000..3fe36edc9
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/structuredmerge.go
@@ -0,0 +1,190 @@
+/*
+Copyright 2019 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 internal
+
+import (
+ "fmt"
+
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v4/merge"
+ "sigs.k8s.io/structured-merge-diff/v4/typed"
+
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/api/meta"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+type structuredMergeManager struct {
+ typeConverter TypeConverter
+ objectConverter runtime.ObjectConvertor
+ objectDefaulter runtime.ObjectDefaulter
+ groupVersion schema.GroupVersion
+ hubVersion schema.GroupVersion
+ updater merge.Updater
+}
+
+var _ Manager = &structuredMergeManager{}
+
+// NewStructuredMergeManager creates a new Manager that merges apply requests
+// and update managed fields for other types of requests.
+func NewStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, resetFields map[fieldpath.APIVersion]fieldpath.Filter) (Manager, error) {
+ if typeConverter == nil {
+ return nil, fmt.Errorf("typeconverter must not be nil")
+ }
+ return &structuredMergeManager{
+ typeConverter: typeConverter,
+ objectConverter: objectConverter,
+ objectDefaulter: objectDefaulter,
+ groupVersion: gv,
+ hubVersion: hub,
+ updater: merge.Updater{
+ Converter: newVersionConverter(typeConverter, objectConverter, hub), // This is the converter provided to SMD from k8s
+ IgnoreFilter: resetFields,
+ },
+ }, nil
+}
+
+// NewCRDStructuredMergeManager creates a new Manager specifically for
+// CRDs. This allows for the possibility of fields which are not defined
+// in models, as well as having no models defined at all.
+func NewCRDStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, resetFields map[fieldpath.APIVersion]fieldpath.Filter) (_ Manager, err error) {
+ return &structuredMergeManager{
+ typeConverter: typeConverter,
+ objectConverter: objectConverter,
+ objectDefaulter: objectDefaulter,
+ groupVersion: gv,
+ hubVersion: hub,
+ updater: merge.Updater{
+ Converter: newCRDVersionConverter(typeConverter, objectConverter, hub),
+ IgnoreFilter: resetFields,
+ },
+ }, nil
+}
+
+func objectGVKNN(obj runtime.Object) string {
+ name := ""
+ namespace := ""
+ if accessor, err := meta.Accessor(obj); err == nil {
+ name = accessor.GetName()
+ namespace = accessor.GetNamespace()
+ }
+
+ return fmt.Sprintf("%v/%v; %v", namespace, name, obj.GetObjectKind().GroupVersionKind())
+}
+
+// Update implements Manager.
+func (f *structuredMergeManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
+ newObjVersioned, err := f.toVersioned(newObj)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to convert new object (%v) to proper version (%v): %v", objectGVKNN(newObj), f.groupVersion, err)
+ }
+ liveObjVersioned, err := f.toVersioned(liveObj)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to convert live object (%v) to proper version: %v", objectGVKNN(liveObj), err)
+ }
+ newObjTyped, err := f.typeConverter.ObjectToTyped(newObjVersioned, typed.AllowDuplicates)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to convert new object (%v) to smd typed: %v", objectGVKNN(newObjVersioned), err)
+ }
+ liveObjTyped, err := f.typeConverter.ObjectToTyped(liveObjVersioned, typed.AllowDuplicates)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to convert live object (%v) to smd typed: %v", objectGVKNN(liveObjVersioned), err)
+ }
+ apiVersion := fieldpath.APIVersion(f.groupVersion.String())
+
+ // TODO(apelisse) use the first return value when unions are implemented
+ _, managedFields, err := f.updater.Update(liveObjTyped, newObjTyped, apiVersion, managed.Fields(), manager)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to update ManagedFields (%v): %v", objectGVKNN(newObjVersioned), err)
+ }
+ managed = NewManaged(managedFields, managed.Times())
+
+ return newObj, managed, nil
+}
+
+// Apply implements Manager.
+func (f *structuredMergeManager) Apply(liveObj, patchObj runtime.Object, managed Managed, manager string, force bool) (runtime.Object, Managed, error) {
+ // Check that the patch object has the same version as the live object
+ if patchVersion := patchObj.GetObjectKind().GroupVersionKind().GroupVersion(); patchVersion != f.groupVersion {
+ return nil, nil,
+ errors.NewBadRequest(
+ fmt.Sprintf("Incorrect version specified in apply patch. "+
+ "Specified patch version: %s, expected: %s",
+ patchVersion, f.groupVersion))
+ }
+
+ patchObjMeta, err := meta.Accessor(patchObj)
+ if err != nil {
+ return nil, nil, fmt.Errorf("couldn't get accessor: %v", err)
+ }
+ if patchObjMeta.GetManagedFields() != nil {
+ return nil, nil, errors.NewBadRequest("metadata.managedFields must be nil")
+ }
+
+ liveObjVersioned, err := f.toVersioned(liveObj)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to convert live object (%v) to proper version: %v", objectGVKNN(liveObj), err)
+ }
+
+ // Don't allow duplicates in the applied object.
+ patchObjTyped, err := f.typeConverter.ObjectToTyped(patchObj)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to create typed patch object (%v): %v", objectGVKNN(patchObj), err)
+ }
+
+ liveObjTyped, err := f.typeConverter.ObjectToTyped(liveObjVersioned, typed.AllowDuplicates)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to create typed live object (%v): %v", objectGVKNN(liveObjVersioned), err)
+ }
+
+ apiVersion := fieldpath.APIVersion(f.groupVersion.String())
+ newObjTyped, managedFields, err := f.updater.Apply(liveObjTyped, patchObjTyped, apiVersion, managed.Fields(), manager, force)
+ if err != nil {
+ return nil, nil, err
+ }
+ managed = NewManaged(managedFields, managed.Times())
+
+ if newObjTyped == nil {
+ return nil, managed, nil
+ }
+
+ newObj, err := f.typeConverter.TypedToObject(newObjTyped)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to convert new typed object (%v) to object: %v", objectGVKNN(patchObj), err)
+ }
+
+ newObjVersioned, err := f.toVersioned(newObj)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to convert new object (%v) to proper version: %v", objectGVKNN(patchObj), err)
+ }
+ f.objectDefaulter.Default(newObjVersioned)
+
+ newObjUnversioned, err := f.toUnversioned(newObjVersioned)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to convert to unversioned (%v): %v", objectGVKNN(patchObj), err)
+ }
+ return newObjUnversioned, managed, nil
+}
+
+func (f *structuredMergeManager) toVersioned(obj runtime.Object) (runtime.Object, error) {
+ return f.objectConverter.ConvertToVersion(obj, f.groupVersion)
+}
+
+func (f *structuredMergeManager) toUnversioned(obj runtime.Object) (runtime.Object, error) {
+ return f.objectConverter.ConvertToVersion(obj, f.hubVersion)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go
new file mode 100644
index 000000000..c6449467c
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go
@@ -0,0 +1,193 @@
+/*
+Copyright 2022 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 internal
+
+import (
+ "fmt"
+
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/kube-openapi/pkg/schemaconv"
+ "k8s.io/kube-openapi/pkg/validation/spec"
+ smdschema "sigs.k8s.io/structured-merge-diff/v4/schema"
+ "sigs.k8s.io/structured-merge-diff/v4/typed"
+ "sigs.k8s.io/structured-merge-diff/v4/value"
+)
+
+// TypeConverter allows you to convert from runtime.Object to
+// typed.TypedValue and the other way around.
+type TypeConverter interface {
+ ObjectToTyped(runtime.Object, ...typed.ValidationOptions) (*typed.TypedValue, error)
+ TypedToObject(*typed.TypedValue) (runtime.Object, error)
+}
+
+type typeConverter struct {
+ parser map[schema.GroupVersionKind]*typed.ParseableType
+}
+
+var _ TypeConverter = &typeConverter{}
+
+func NewTypeConverter(openapiSpec map[string]*spec.Schema, preserveUnknownFields bool) (TypeConverter, error) {
+ typeSchema, err := schemaconv.ToSchemaFromOpenAPI(openapiSpec, preserveUnknownFields)
+ if err != nil {
+ return nil, fmt.Errorf("failed to convert models to schema: %v", err)
+ }
+
+ typeParser := typed.Parser{Schema: smdschema.Schema{Types: typeSchema.Types}}
+ tr := indexModels(&typeParser, openapiSpec)
+
+ return &typeConverter{parser: tr}, nil
+}
+
+func (c *typeConverter) ObjectToTyped(obj runtime.Object, opts ...typed.ValidationOptions) (*typed.TypedValue, error) {
+ gvk := obj.GetObjectKind().GroupVersionKind()
+ t := c.parser[gvk]
+ if t == nil {
+ return nil, NewNoCorrespondingTypeError(gvk)
+ }
+ switch o := obj.(type) {
+ case *unstructured.Unstructured:
+ return t.FromUnstructured(o.UnstructuredContent(), opts...)
+ default:
+ return t.FromStructured(obj, opts...)
+ }
+}
+
+func (c *typeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) {
+ return valueToObject(value.AsValue())
+}
+
+type deducedTypeConverter struct{}
+
+// DeducedTypeConverter is a TypeConverter for CRDs that don't have a
+// schema. It does implement the same interface though (and create the
+// same types of objects), so that everything can still work the same.
+// CRDs are merged with all their fields being "atomic" (lists
+// included).
+func NewDeducedTypeConverter() TypeConverter {
+ return deducedTypeConverter{}
+}
+
+// ObjectToTyped converts an object into a TypedValue with a "deduced type".
+func (deducedTypeConverter) ObjectToTyped(obj runtime.Object, opts ...typed.ValidationOptions) (*typed.TypedValue, error) {
+ switch o := obj.(type) {
+ case *unstructured.Unstructured:
+ return typed.DeducedParseableType.FromUnstructured(o.UnstructuredContent(), opts...)
+ default:
+ return typed.DeducedParseableType.FromStructured(obj, opts...)
+ }
+}
+
+// TypedToObject transforms the typed value into a runtime.Object. That
+// is not specific to deduced type.
+func (deducedTypeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) {
+ return valueToObject(value.AsValue())
+}
+
+func valueToObject(val value.Value) (runtime.Object, error) {
+ vu := val.Unstructured()
+ switch o := vu.(type) {
+ case map[string]interface{}:
+ return &unstructured.Unstructured{Object: o}, nil
+ default:
+ return nil, fmt.Errorf("failed to convert value to unstructured for type %T", vu)
+ }
+}
+
+func indexModels(
+ typeParser *typed.Parser,
+ openAPISchemas map[string]*spec.Schema,
+) map[schema.GroupVersionKind]*typed.ParseableType {
+ tr := map[schema.GroupVersionKind]*typed.ParseableType{}
+ for modelName, model := range openAPISchemas {
+ gvkList := parseGroupVersionKind(model.Extensions)
+ if len(gvkList) == 0 {
+ continue
+ }
+
+ parsedType := typeParser.Type(modelName)
+ for _, gvk := range gvkList {
+ if len(gvk.Kind) > 0 {
+ tr[schema.GroupVersionKind(gvk)] = &parsedType
+ }
+ }
+ }
+ return tr
+}
+
+// Get and parse GroupVersionKind from the extension. Returns empty if it doesn't have one.
+func parseGroupVersionKind(extensions map[string]interface{}) []schema.GroupVersionKind {
+ gvkListResult := []schema.GroupVersionKind{}
+
+ // Get the extensions
+ gvkExtension, ok := extensions["x-kubernetes-group-version-kind"]
+ if !ok {
+ return []schema.GroupVersionKind{}
+ }
+
+ // gvk extension must be a list of at least 1 element.
+ gvkList, ok := gvkExtension.([]interface{})
+ if !ok {
+ return []schema.GroupVersionKind{}
+ }
+
+ for _, gvk := range gvkList {
+ var group, version, kind string
+
+ // gvk extension list must be a map with group, version, and
+ // kind fields
+ if gvkMap, ok := gvk.(map[interface{}]interface{}); ok {
+ group, ok = gvkMap["group"].(string)
+ if !ok {
+ continue
+ }
+ version, ok = gvkMap["version"].(string)
+ if !ok {
+ continue
+ }
+ kind, ok = gvkMap["kind"].(string)
+ if !ok {
+ continue
+ }
+
+ } else if gvkMap, ok := gvk.(map[string]interface{}); ok {
+ group, ok = gvkMap["group"].(string)
+ if !ok {
+ continue
+ }
+ version, ok = gvkMap["version"].(string)
+ if !ok {
+ continue
+ }
+ kind, ok = gvkMap["kind"].(string)
+ if !ok {
+ continue
+ }
+ } else {
+ continue
+ }
+
+ gvkListResult = append(gvkListResult, schema.GroupVersionKind{
+ Group: group,
+ Version: version,
+ Kind: kind,
+ })
+ }
+
+ return gvkListResult
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versioncheck.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versioncheck.go
new file mode 100644
index 000000000..ee1e2bca7
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versioncheck.go
@@ -0,0 +1,52 @@
+/*
+Copyright 2023 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 internal
+
+import (
+ "fmt"
+
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+type versionCheckManager struct {
+ fieldManager Manager
+ gvk schema.GroupVersionKind
+}
+
+var _ Manager = &versionCheckManager{}
+
+// NewVersionCheckManager creates a manager that makes sure that the
+// applied object is in the proper version.
+func NewVersionCheckManager(fieldManager Manager, gvk schema.GroupVersionKind) Manager {
+ return &versionCheckManager{fieldManager: fieldManager, gvk: gvk}
+}
+
+// Update implements Manager.
+func (f *versionCheckManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
+ // Nothing to do for updates, this is checked in many other places.
+ return f.fieldManager.Update(liveObj, newObj, managed, manager)
+}
+
+// Apply implements Manager.
+func (f *versionCheckManager) Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) {
+ if gvk := appliedObj.GetObjectKind().GroupVersionKind(); gvk != f.gvk {
+ return nil, nil, errors.NewBadRequest(fmt.Sprintf("invalid object type: %v", gvk))
+ }
+ return f.fieldManager.Apply(liveObj, appliedObj, managed, fieldManager, force)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go
new file mode 100644
index 000000000..45855fa4c
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go
@@ -0,0 +1,123 @@
+/*
+Copyright 2018 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 internal
+
+import (
+ "fmt"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v4/merge"
+ "sigs.k8s.io/structured-merge-diff/v4/typed"
+)
+
+// versionConverter is an implementation of
+// sigs.k8s.io/structured-merge-diff/merge.Converter
+type versionConverter struct {
+ typeConverter TypeConverter
+ objectConvertor runtime.ObjectConvertor
+ hubGetter func(from schema.GroupVersion) schema.GroupVersion
+}
+
+var _ merge.Converter = &versionConverter{}
+
+// NewVersionConverter builds a VersionConverter from a TypeConverter and an ObjectConvertor.
+func newVersionConverter(t TypeConverter, o runtime.ObjectConvertor, h schema.GroupVersion) merge.Converter {
+ return &versionConverter{
+ typeConverter: t,
+ objectConvertor: o,
+ hubGetter: func(from schema.GroupVersion) schema.GroupVersion {
+ return schema.GroupVersion{
+ Group: from.Group,
+ Version: h.Version,
+ }
+ },
+ }
+}
+
+// NewCRDVersionConverter builds a VersionConverter for CRDs from a TypeConverter and an ObjectConvertor.
+func newCRDVersionConverter(t TypeConverter, o runtime.ObjectConvertor, h schema.GroupVersion) merge.Converter {
+ return &versionConverter{
+ typeConverter: t,
+ objectConvertor: o,
+ hubGetter: func(from schema.GroupVersion) schema.GroupVersion {
+ return h
+ },
+ }
+}
+
+// Convert implements sigs.k8s.io/structured-merge-diff/merge.Converter
+func (v *versionConverter) Convert(object *typed.TypedValue, version fieldpath.APIVersion) (*typed.TypedValue, error) {
+ // Convert the smd typed value to a kubernetes object.
+ objectToConvert, err := v.typeConverter.TypedToObject(object)
+ if err != nil {
+ return object, err
+ }
+
+ // Parse the target groupVersion.
+ groupVersion, err := schema.ParseGroupVersion(string(version))
+ if err != nil {
+ return object, err
+ }
+
+ // If attempting to convert to the same version as we already have, just return it.
+ fromVersion := objectToConvert.GetObjectKind().GroupVersionKind().GroupVersion()
+ if fromVersion == groupVersion {
+ return object, nil
+ }
+
+ // Convert to internal
+ internalObject, err := v.objectConvertor.ConvertToVersion(objectToConvert, v.hubGetter(fromVersion))
+ if err != nil {
+ return object, err
+ }
+
+ // Convert the object into the target version
+ convertedObject, err := v.objectConvertor.ConvertToVersion(internalObject, groupVersion)
+ if err != nil {
+ return object, err
+ }
+
+ // Convert the object back to a smd typed value and return it.
+ return v.typeConverter.ObjectToTyped(convertedObject)
+}
+
+// IsMissingVersionError
+func (v *versionConverter) IsMissingVersionError(err error) bool {
+ return runtime.IsNotRegisteredError(err) || isNoCorrespondingTypeError(err)
+}
+
+type noCorrespondingTypeErr struct {
+ gvk schema.GroupVersionKind
+}
+
+func NewNoCorrespondingTypeError(gvk schema.GroupVersionKind) error {
+ return &noCorrespondingTypeErr{gvk: gvk}
+}
+
+func (k *noCorrespondingTypeErr) Error() string {
+ return fmt.Sprintf("no corresponding type for %v", k.gvk)
+}
+
+func isNoCorrespondingTypeError(err error) bool {
+ if err == nil {
+ return false
+ }
+ _, ok := err.(*noCorrespondingTypeErr)
+ return ok
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/node.yaml b/vendor/k8s.io/apimachinery/pkg/util/managedfields/node.yaml
new file mode 100644
index 000000000..a7f2d54fd
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/node.yaml
@@ -0,0 +1,261 @@
+apiVersion: v1
+kind: Node
+metadata:
+ annotations:
+ container.googleapis.com/instance_id: "123456789321654789"
+ node.alpha.kubernetes.io/ttl: "0"
+ volumes.kubernetes.io/controller-managed-attach-detach: "true"
+ creationTimestamp: "2019-07-09T16:17:29Z"
+ labels:
+ kubernetes.io/arch: amd64
+ beta.kubernetes.io/fluentd-ds-ready: "true"
+ beta.kubernetes.io/instance-type: n1-standard-4
+ kubernetes.io/os: linux
+ cloud.google.com/gke-nodepool: default-pool
+ cloud.google.com/gke-os-distribution: cos
+ failure-domain.beta.kubernetes.io/region: us-central1
+ failure-domain.beta.kubernetes.io/zone: us-central1-b
+ topology.kubernetes.io/region: us-central1
+ topology.kubernetes.io/zone: us-central1-b
+ kubernetes.io/hostname: node-default-pool-something
+ name: node-default-pool-something
+ resourceVersion: "211582541"
+ selfLink: /api/v1/nodes/node-default-pool-something
+ uid: 0c24d0e1-a265-11e9-abe4-42010a80026b
+spec:
+ podCIDR: 10.0.0.1/24
+ providerID: some-provider-id-of-some-sort
+status:
+ addresses:
+ - address: 10.0.0.1
+ type: InternalIP
+ - address: 192.168.0.1
+ type: ExternalIP
+ - address: node-default-pool-something
+ type: Hostname
+ allocatable:
+ cpu: 3920m
+ ephemeral-storage: "104638878617"
+ hugepages-2Mi: "0"
+ memory: 12700100Ki
+ pods: "110"
+ capacity:
+ cpu: "4"
+ ephemeral-storage: 202086868Ki
+ hugepages-2Mi: "0"
+ memory: 15399364Ki
+ pods: "110"
+ conditions:
+ - lastHeartbeatTime: "2019-09-20T19:32:08Z"
+ lastTransitionTime: "2019-07-09T16:22:08Z"
+ message: containerd is functioning properly
+ reason: FrequentContainerdRestart
+ status: "False"
+ type: FrequentContainerdRestart
+ - lastHeartbeatTime: "2019-09-20T19:32:08Z"
+ lastTransitionTime: "2019-07-09T16:22:06Z"
+ message: docker overlay2 is functioning properly
+ reason: CorruptDockerOverlay2
+ status: "False"
+ type: CorruptDockerOverlay2
+ - lastHeartbeatTime: "2019-09-20T19:32:08Z"
+ lastTransitionTime: "2019-07-09T16:22:06Z"
+ message: node is functioning properly
+ reason: UnregisterNetDevice
+ status: "False"
+ type: FrequentUnregisterNetDevice
+ - lastHeartbeatTime: "2019-09-20T19:32:08Z"
+ lastTransitionTime: "2019-07-09T16:17:04Z"
+ message: kernel has no deadlock
+ reason: KernelHasNoDeadlock
+ status: "False"
+ type: KernelDeadlock
+ - lastHeartbeatTime: "2019-09-20T19:32:08Z"
+ lastTransitionTime: "2019-07-09T16:17:04Z"
+ message: Filesystem is not read-only
+ reason: FilesystemIsNotReadOnly
+ status: "False"
+ type: ReadonlyFilesystem
+ - lastHeartbeatTime: "2019-09-20T19:32:08Z"
+ lastTransitionTime: "2019-07-09T16:22:05Z"
+ message: kubelet is functioning properly
+ reason: FrequentKubeletRestart
+ status: "False"
+ type: FrequentKubeletRestart
+ - lastHeartbeatTime: "2019-09-20T19:32:08Z"
+ lastTransitionTime: "2019-07-09T16:22:06Z"
+ message: docker is functioning properly
+ reason: FrequentDockerRestart
+ status: "False"
+ type: FrequentDockerRestart
+ - lastHeartbeatTime: "2019-07-09T16:17:47Z"
+ lastTransitionTime: "2019-07-09T16:17:47Z"
+ message: RouteController created a route
+ reason: RouteCreated
+ status: "False"
+ type: NetworkUnavailable
+ - lastHeartbeatTime: "2019-09-20T19:32:50Z"
+ lastTransitionTime: "2019-07-09T16:17:29Z"
+ message: kubelet has sufficient disk space available
+ reason: KubeletHasSufficientDisk
+ status: "False"
+ type: OutOfDisk
+ - lastHeartbeatTime: "2019-09-20T19:32:50Z"
+ lastTransitionTime: "2019-07-09T16:17:29Z"
+ message: kubelet has sufficient memory available
+ reason: KubeletHasSufficientMemory
+ status: "False"
+ type: MemoryPressure
+ - lastHeartbeatTime: "2019-09-20T19:32:50Z"
+ lastTransitionTime: "2019-07-09T16:17:29Z"
+ message: kubelet has no disk pressure
+ reason: KubeletHasNoDiskPressure
+ status: "False"
+ type: DiskPressure
+ - lastHeartbeatTime: "2019-09-20T19:32:50Z"
+ lastTransitionTime: "2019-07-09T16:17:29Z"
+ message: kubelet has sufficient PID available
+ reason: KubeletHasSufficientPID
+ status: "False"
+ type: PIDPressure
+ - lastHeartbeatTime: "2019-09-20T19:32:50Z"
+ lastTransitionTime: "2019-07-09T16:17:49Z"
+ message: kubelet is posting ready status
+ reason: KubeletReady
+ status: "True"
+ type: Ready
+ daemonEndpoints:
+ kubeletEndpoint:
+ Port: 10250
+ images:
+ - names:
+ - grafana/grafana@sha256:80e5e113a984d74836aa16f5b4524012099436b1a50df293f00ac6377fb512c8
+ - grafana/grafana:4.4.2
+ sizeBytes: 287008013
+ - names:
+ - registry.k8s.io/node-problem-detector@sha256:f95cab985c26b2f46e9bd43283e0bfa88860c14e0fb0649266babe8b65e9eb2b
+ - registry.k8s.io/node-problem-detector:v0.4.1
+ sizeBytes: 286572743
+ - names:
+ - grafana/grafana@sha256:7ff7f9b2501a5d55b55ce3f58d21771b1c5af1f2a4ab7dbf11bef7142aae7033
+ - grafana/grafana:4.2.0
+ sizeBytes: 277940263
+ - names:
+ - influxdb@sha256:7dddf03376348876ed4bdf33d6dfa3326f45a2bae0930dbd80781a374eb519bc
+ - influxdb:1.2.2
+ sizeBytes: 223948571
+ - names:
+ - gcr.io/stackdriver-agents/stackdriver-logging-agent@sha256:f8d5231b67b9c53f60068b535a11811d29d1b3efd53d2b79f2a2591ea338e4f2
+ - gcr.io/stackdriver-agents/stackdriver-logging-agent:0.6-1.6.0-1
+ sizeBytes: 223242132
+ - names:
+ - nginx@sha256:35779791c05d119df4fe476db8f47c0bee5943c83eba5656a15fc046db48178b
+ - nginx:1.10.1
+ sizeBytes: 180708613
+ - names:
+ - registry.k8s.io/fluentd-elasticsearch@sha256:b8c94527b489fb61d3d81ce5ad7f3ddbb7be71e9620a3a36e2bede2f2e487d73
+ - registry.k8s.io/fluentd-elasticsearch:v2.0.4
+ sizeBytes: 135716379
+ - names:
+ - nginx@sha256:00be67d6ba53d5318cd91c57771530f5251cfbe028b7be2c4b70526f988cfc9f
+ - nginx:latest
+ sizeBytes: 109357355
+ - names:
+ - registry.k8s.io/kubernetes-dashboard-amd64@sha256:dc4026c1b595435ef5527ca598e1e9c4343076926d7d62b365c44831395adbd0
+ - registry.k8s.io/kubernetes-dashboard-amd64:v1.8.3
+ sizeBytes: 102319441
+ - names:
+ - gcr.io/google_containers/kube-proxy:v1.11.10-gke.5
+ - registry.k8s.io/kube-proxy:v1.11.10-gke.5
+ sizeBytes: 102279340
+ - names:
+ - registry.k8s.io/event-exporter@sha256:7f9cd7cb04d6959b0aa960727d04fa86759008048c785397b7b0d9dff0007516
+ - registry.k8s.io/event-exporter:v0.2.3
+ sizeBytes: 94171943
+ - names:
+ - registry.k8s.io/prometheus-to-sd@sha256:6c0c742475363d537ff059136e5d5e4ab1f512ee0fd9b7ca42ea48bc309d1662
+ - registry.k8s.io/prometheus-to-sd:v0.3.1
+ sizeBytes: 88077694
+ - names:
+ - registry.k8s.io/fluentd-gcp-scaler@sha256:a5ace7506d393c4ed65eb2cbb6312c64ab357fcea16dff76b9055bc6e498e5ff
+ - registry.k8s.io/fluentd-gcp-scaler:0.5.1
+ sizeBytes: 86637208
+ - names:
+ - registry.k8s.io/heapster-amd64@sha256:9fae0af136ce0cf4f88393b3670f7139ffc464692060c374d2ae748e13144521
+ - registry.k8s.io/heapster-amd64:v1.6.0-beta.1
+ sizeBytes: 76016169
+ - names:
+ - registry.k8s.io/ingress-glbc-amd64@sha256:31d36bbd9c44caffa135fc78cf0737266fcf25e3cf0cd1c2fcbfbc4f7309cc52
+ - registry.k8s.io/ingress-glbc-amd64:v1.1.1
+ sizeBytes: 67801919
+ - names:
+ - registry.k8s.io/kube-addon-manager@sha256:d53486c3a0b49ebee019932878dc44232735d5622a51dbbdcec7124199020d09
+ - registry.k8s.io/kube-addon-manager:v8.7
+ sizeBytes: 63322109
+ - names:
+ - nginx@sha256:4aacdcf186934dcb02f642579314075910f1855590fd3039d8fa4c9f96e48315
+ - nginx:1.10-alpine
+ sizeBytes: 54042627
+ - names:
+ - registry.k8s.io/cpvpa-amd64@sha256:cfe7b0a11c9c8e18c87b1eb34fef9a7cbb8480a8da11fc2657f78dbf4739f869
+ - registry.k8s.io/cpvpa-amd64:v0.6.0
+ sizeBytes: 51785854
+ - names:
+ - registry.k8s.io/cluster-proportional-autoscaler-amd64@sha256:003f98d9f411ddfa6ff6d539196355e03ddd69fa4ed38c7ffb8fec6f729afe2d
+ - registry.k8s.io/cluster-proportional-autoscaler-amd64:1.1.2-r2
+ sizeBytes: 49648481
+ - names:
+ - registry.k8s.io/ip-masq-agent-amd64@sha256:1ffda57d87901bc01324c82ceb2145fe6a0448d3f0dd9cb65aa76a867cd62103
+ - registry.k8s.io/ip-masq-agent-amd64:v2.1.1
+ sizeBytes: 49612505
+ - names:
+ - registry.k8s.io/k8s-dns-kube-dns-amd64@sha256:b99fc3eee2a9f052f7eb4cc00f15eb12fc405fa41019baa2d6b79847ae7284a8
+ - registry.k8s.io/k8s-dns-kube-dns-amd64:1.14.10
+ sizeBytes: 49549457
+ - names:
+ - registry.k8s.io/rescheduler@sha256:156cfbfd05a5a815206fd2eeb6cbdaf1596d71ea4b415d3a6c43071dd7b99450
+ - registry.k8s.io/rescheduler:v0.4.0
+ sizeBytes: 48973149
+ - names:
+ - registry.k8s.io/event-exporter@sha256:16ca66e2b5dc7a1ce6a5aafcb21d0885828b75cdfc08135430480f7ad2364adc
+ - registry.k8s.io/event-exporter:v0.2.4
+ sizeBytes: 47261019
+ - names:
+ - registry.k8s.io/coredns@sha256:db2bf53126ed1c761d5a41f24a1b82a461c85f736ff6e90542e9522be4757848
+ - registry.k8s.io/coredns:1.1.3
+ sizeBytes: 45587362
+ - names:
+ - prom/prometheus@sha256:483f4c9d7733699ba79facca9f8bcce1cef1af43dfc3e7c5a1882aa85f53cb74
+ - prom/prometheus:v1.1.3
+ sizeBytes: 45493941
+ nodeInfo:
+ architecture: amd64
+ bootID: a32eca78-4ad4-4b76-9252-f143d6c2ae61
+ containerRuntimeVersion: docker://17.3.2
+ kernelVersion: 4.14.127+
+ kubeProxyVersion: v1.11.10-gke.5
+ kubeletVersion: v1.11.10-gke.5
+ machineID: 1739555e5b231057f0f9a0b5fa29511b
+ operatingSystem: linux
+ osImage: Container-Optimized OS from Google
+ systemUUID: 1739555E-5B23-1057-F0F9-A0B5FA29511B
+ volumesAttached:
+ - devicePath: /dev/disk/by-id/b9772-pvc-c787c67d-14d7-11e7-9baf-42010a800049
+ name: kubernetes.io/pd/some-random-clusterb9772-pvc-c787c67d-14d7-11e7-9baf-42010a800049
+ - devicePath: /dev/disk/by-id/b9772-pvc-8895a852-fd42-11e6-94d4-42010a800049
+ name: kubernetes.io/pd/some-random-clusterb9772-pvc-8895a852-fd42-11e6-94d4-42010a800049
+ - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-72e1c7f1-fd41-11e6-94d4-42010a800049
+ name: kubernetes.io/pd/some-random-clusterb9772-pvc-72e1c7f1-fd41-11e6-94d4-42010a800049
+ - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-c2435a06-14d7-11e7-9baf-42010a800049
+ name: kubernetes.io/pd/some-random-clusterb9772-pvc-c2435a06-14d7-11e7-9baf-42010a800049
+ - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-8bf50554-fd42-11e6-94d4-42010a800049
+ name: kubernetes.io/pd/some-random-clusterb9772-pvc-8bf50554-fd42-11e6-94d4-42010a800049
+ - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-8fb5e386-4641-11e7-a490-42010a800283
+ name: kubernetes.io/pd/some-random-clusterb9772-pvc-8fb5e386-4641-11e7-a490-42010a800283
+ volumesInUse:
+ - kubernetes.io/pd/some-random-clusterb9772-pvc-72e1c7f1-fd41-11e6-94d4-42010a800049
+ - kubernetes.io/pd/some-random-clusterb9772-pvc-8895a852-fd42-11e6-94d4-42010a800049
+ - kubernetes.io/pd/some-random-clusterb9772-pvc-8bf50554-fd42-11e6-94d4-42010a800049
+ - kubernetes.io/pd/some-random-clusterb9772-pvc-8fb5e386-4641-11e7-a490-42010a800283
+ - kubernetes.io/pd/some-random-clusterb9772-pvc-c2435a06-14d7-11e7-9baf-42010a800049
+ - kubernetes.io/pd/some-random-clusterb9772-pvc-c787c67d-14d7-11e7-9baf-42010a800049
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/pod.yaml b/vendor/k8s.io/apimachinery/pkg/util/managedfields/pod.yaml
new file mode 100644
index 000000000..3fb0877d6
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/pod.yaml
@@ -0,0 +1,121 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ labels:
+ app: some-app
+ plugin1: some-value
+ plugin2: some-value
+ plugin3: some-value
+ plugin4: some-value
+ name: some-name
+ namespace: default
+ ownerReferences:
+ - apiVersion: apps/v1
+ blockOwnerDeletion: true
+ controller: true
+ kind: ReplicaSet
+ name: some-name
+ uid: 0a9d2b9e-779e-11e7-b422-42010a8001be
+spec:
+ containers:
+ - args:
+ - one
+ - two
+ - three
+ - four
+ - five
+ - six
+ - seven
+ - eight
+ - nine
+ env:
+ - name: VAR_3
+ valueFrom:
+ secretKeyRef:
+ key: some-other-key
+ name: some-oher-name
+ - name: VAR_2
+ valueFrom:
+ secretKeyRef:
+ key: other-key
+ name: other-name
+ - name: VAR_1
+ valueFrom:
+ secretKeyRef:
+ key: some-key
+ name: some-name
+ image: some-image-name
+ imagePullPolicy: IfNotPresent
+ name: some-name
+ resources:
+ requests:
+ cpu: '0'
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ volumeMounts:
+ - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
+ name: default-token-hu5jz
+ readOnly: true
+ dnsPolicy: ClusterFirst
+ nodeName: node-name
+ priority: 0
+ restartPolicy: Always
+ schedulerName: default-scheduler
+ securityContext: {}
+ serviceAccount: default
+ serviceAccountName: default
+ terminationGracePeriodSeconds: 30
+ tolerations:
+ - effect: NoExecute
+ key: node.kubernetes.io/not-ready
+ operator: Exists
+ tolerationSeconds: 300
+ - effect: NoExecute
+ key: node.kubernetes.io/unreachable
+ operator: Exists
+ tolerationSeconds: 300
+ volumes:
+ - name: default-token-hu5jz
+ secret:
+ defaultMode: 420
+ secretName: default-token-hu5jz
+status:
+ conditions:
+ - lastProbeTime: null
+ lastTransitionTime: '2019-07-08T09:31:18Z'
+ status: 'True'
+ type: Initialized
+ - lastProbeTime: null
+ lastTransitionTime: '2019-07-08T09:41:59Z'
+ status: 'True'
+ type: Ready
+ - lastProbeTime: null
+ lastTransitionTime: null
+ status: 'True'
+ type: ContainersReady
+ - lastProbeTime: null
+ lastTransitionTime: '2019-07-08T09:31:18Z'
+ status: 'True'
+ type: PodScheduled
+ containerStatuses:
+ - containerID: docker://885e82a1ed0b7356541bb410a0126921ac42439607c09875cd8097dd5d7b5376
+ image: some-image-name
+ imageID: docker-pullable://some-image-id
+ lastState:
+ terminated:
+ containerID: docker://d57290f9e00fad626b20d2dd87a3cf69bbc22edae07985374f86a8b2b4e39565
+ exitCode: 255
+ finishedAt: '2019-07-08T09:39:09Z'
+ reason: Error
+ startedAt: '2019-07-08T09:38:54Z'
+ name: name
+ ready: true
+ restartCount: 6
+ state:
+ running:
+ startedAt: '2019-07-08T09:41:59Z'
+ hostIP: 10.0.0.1
+ phase: Running
+ podIP: 10.0.0.1
+ qosClass: BestEffort
+ startTime: '2019-07-08T09:31:18Z'
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/scalehandler.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/scalehandler.go
new file mode 100644
index 000000000..48b774cec
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/scalehandler.go
@@ -0,0 +1,174 @@
+/*
+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 managedfields
+
+import (
+ "fmt"
+
+ "k8s.io/apimachinery/pkg/api/meta"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/util/managedfields/internal"
+ "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+)
+
+var (
+ scaleGroupVersion = schema.GroupVersion{Group: "autoscaling", Version: "v1"}
+ replicasPathInScale = fieldpath.MakePathOrDie("spec", "replicas")
+)
+
+// ResourcePathMappings maps a group/version to its replicas path. The
+// assumption is that all the paths correspond to leaf fields.
+type ResourcePathMappings map[string]fieldpath.Path
+
+// ScaleHandler manages the conversion of managed fields between a main
+// resource and the scale subresource
+type ScaleHandler struct {
+ parentEntries []metav1.ManagedFieldsEntry
+ groupVersion schema.GroupVersion
+ mappings ResourcePathMappings
+}
+
+// NewScaleHandler creates a new ScaleHandler
+func NewScaleHandler(parentEntries []metav1.ManagedFieldsEntry, groupVersion schema.GroupVersion, mappings ResourcePathMappings) *ScaleHandler {
+ return &ScaleHandler{
+ parentEntries: parentEntries,
+ groupVersion: groupVersion,
+ mappings: mappings,
+ }
+}
+
+// ToSubresource filter the managed fields of the main resource and convert
+// them so that they can be handled by scale.
+// For the managed fields that have a replicas path it performs two changes:
+// 1. APIVersion is changed to the APIVersion of the scale subresource
+// 2. Replicas path of the main resource is transformed to the replicas path of
+// the scale subresource
+func (h *ScaleHandler) ToSubresource() ([]metav1.ManagedFieldsEntry, error) {
+ managed, err := internal.DecodeManagedFields(h.parentEntries)
+ if err != nil {
+ return nil, err
+ }
+
+ f := fieldpath.ManagedFields{}
+ t := map[string]*metav1.Time{}
+ for manager, versionedSet := range managed.Fields() {
+ path, ok := h.mappings[string(versionedSet.APIVersion())]
+ // Skip the entry if the APIVersion is unknown
+ if !ok || path == nil {
+ continue
+ }
+
+ if versionedSet.Set().Has(path) {
+ newVersionedSet := fieldpath.NewVersionedSet(
+ fieldpath.NewSet(replicasPathInScale),
+ fieldpath.APIVersion(scaleGroupVersion.String()),
+ versionedSet.Applied(),
+ )
+
+ f[manager] = newVersionedSet
+ t[manager] = managed.Times()[manager]
+ }
+ }
+
+ return managedFieldsEntries(internal.NewManaged(f, t))
+}
+
+// ToParent merges `scaleEntries` with the entries of the main resource and
+// transforms them accordingly
+func (h *ScaleHandler) ToParent(scaleEntries []metav1.ManagedFieldsEntry) ([]metav1.ManagedFieldsEntry, error) {
+ decodedParentEntries, err := internal.DecodeManagedFields(h.parentEntries)
+ if err != nil {
+ return nil, err
+ }
+ parentFields := decodedParentEntries.Fields()
+
+ decodedScaleEntries, err := internal.DecodeManagedFields(scaleEntries)
+ if err != nil {
+ return nil, err
+ }
+ scaleFields := decodedScaleEntries.Fields()
+
+ f := fieldpath.ManagedFields{}
+ t := map[string]*metav1.Time{}
+
+ for manager, versionedSet := range parentFields {
+ // Get the main resource "replicas" path
+ path, ok := h.mappings[string(versionedSet.APIVersion())]
+ // Drop the entry if the APIVersion is unknown.
+ if !ok {
+ continue
+ }
+
+ // If the parent entry does not have the replicas path or it is nil, just
+ // keep it as it is. The path is nil for Custom Resources without scale
+ // subresource.
+ if path == nil || !versionedSet.Set().Has(path) {
+ f[manager] = versionedSet
+ t[manager] = decodedParentEntries.Times()[manager]
+ continue
+ }
+
+ if _, ok := scaleFields[manager]; !ok {
+ // "Steal" the replicas path from the main resource entry
+ newSet := versionedSet.Set().Difference(fieldpath.NewSet(path))
+
+ if !newSet.Empty() {
+ newVersionedSet := fieldpath.NewVersionedSet(
+ newSet,
+ versionedSet.APIVersion(),
+ versionedSet.Applied(),
+ )
+ f[manager] = newVersionedSet
+ t[manager] = decodedParentEntries.Times()[manager]
+ }
+ } else {
+ // Field wasn't stolen, let's keep the entry as it is.
+ f[manager] = versionedSet
+ t[manager] = decodedParentEntries.Times()[manager]
+ delete(scaleFields, manager)
+ }
+ }
+
+ for manager, versionedSet := range scaleFields {
+ if !versionedSet.Set().Has(replicasPathInScale) {
+ continue
+ }
+ newVersionedSet := fieldpath.NewVersionedSet(
+ fieldpath.NewSet(h.mappings[h.groupVersion.String()]),
+ fieldpath.APIVersion(h.groupVersion.String()),
+ versionedSet.Applied(),
+ )
+ f[manager] = newVersionedSet
+ t[manager] = decodedParentEntries.Times()[manager]
+ }
+
+ return managedFieldsEntries(internal.NewManaged(f, t))
+}
+
+func managedFieldsEntries(entries internal.ManagedInterface) ([]metav1.ManagedFieldsEntry, error) {
+ obj := &unstructured.Unstructured{Object: map[string]interface{}{}}
+ if err := internal.EncodeObjectManagedFields(obj, entries); err != nil {
+ return nil, err
+ }
+ accessor, err := meta.Accessor(obj)
+ if err != nil {
+ panic(fmt.Sprintf("couldn't get accessor: %v", err))
+ }
+ return accessor.GetManagedFields(), nil
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/typeconverter.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/typeconverter.go
new file mode 100644
index 000000000..d031eefaa
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/typeconverter.go
@@ -0,0 +1,47 @@
+/*
+Copyright 2018 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 managedfields
+
+import (
+ "k8s.io/apimachinery/pkg/util/managedfields/internal"
+ "k8s.io/kube-openapi/pkg/validation/spec"
+)
+
+// TypeConverter allows you to convert from runtime.Object to
+// typed.TypedValue and the other way around.
+type TypeConverter = internal.TypeConverter
+
+// NewDeducedTypeConverter creates a TypeConverter for CRDs that don't
+// have a schema. It does implement the same interface though (and
+// create the same types of objects), so that everything can still work
+// the same. CRDs are merged with all their fields being "atomic" (lists
+// included).
+func NewDeducedTypeConverter() TypeConverter {
+ return internal.NewDeducedTypeConverter()
+}
+
+// NewTypeConverter builds a TypeConverter from a map of OpenAPIV3 schemas.
+// This will automatically find the proper version of the object, and the
+// corresponding schema information.
+// The keys to the map must be consistent with the names
+// used by Refs within the schemas.
+// The schemas should conform to the Kubernetes Structural Schema OpenAPI
+// restrictions found in docs:
+// https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema
+func NewTypeConverter(openapiSpec map[string]*spec.Schema, preserveUnknownFields bool) (TypeConverter, error) {
+ return internal.NewTypeConverter(openapiSpec, preserveUnknownFields)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go b/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go
index e39627568..25626cf3a 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go
@@ -20,7 +20,7 @@ import (
"fmt"
"reflect"
- "github.com/davecgh/go-spew/spew"
+ "k8s.io/apimachinery/pkg/util/dump"
"sigs.k8s.io/yaml"
)
@@ -76,7 +76,7 @@ func ToYAMLOrError(v interface{}) string {
func toYAML(v interface{}) (string, error) {
y, err := yaml.Marshal(v)
if err != nil {
- return "", fmt.Errorf("yaml marshal failed:%v\n%v\n", err, spew.Sdump(v))
+ return "", fmt.Errorf("yaml marshal failed:%v\n%v\n", err, dump.Pretty(v))
}
return string(y), nil
@@ -88,8 +88,7 @@ func toYAML(v interface{}) (string, error) {
// supports JSON merge patch semantics.
//
// NOTE: Numbers with different types (e.g. int(0) vs int64(0)) will be detected as conflicts.
-//
-// Make sure the unmarshaling of left and right are consistent (e.g. use the same library).
+// Make sure the unmarshaling of left and right are consistent (e.g. use the same library).
func HasConflicts(left, right interface{}) (bool, error) {
switch typedLeft := left.(type) {
case map[string]interface{}:
diff --git a/vendor/k8s.io/apimachinery/pkg/util/net/util.go b/vendor/k8s.io/apimachinery/pkg/util/net/util.go
index 1c2aba55f..1635e69a5 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/net/util.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/net/util.go
@@ -20,6 +20,7 @@ import (
"errors"
"net"
"reflect"
+ "strings"
"syscall"
)
@@ -47,6 +48,11 @@ func IsConnectionReset(err error) bool {
return false
}
+// Returns if the given err is "http2: client connection lost" error.
+func IsHTTP2ConnectionLost(err error) bool {
+ return err != nil && strings.Contains(err.Error(), "http2: client connection lost")
+}
+
// Returns if the given err is "connection refused" error
func IsConnectionRefused(err error) bool {
var errno syscall.Errno
diff --git a/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go b/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go
index d738725ca..df374949d 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go
@@ -17,6 +17,7 @@ limitations under the License.
package runtime
import (
+ "context"
"fmt"
"net/http"
"runtime"
@@ -35,7 +36,7 @@ var (
)
// PanicHandlers is a list of functions which will be invoked when a panic happens.
-var PanicHandlers = []func(interface{}){logPanic}
+var PanicHandlers = []func(context.Context, interface{}){logPanic}
// HandleCrash simply catches a crash and logs an error. Meant to be called via
// defer. Additional context-specific handlers can be provided, and will be
@@ -43,23 +44,54 @@ var PanicHandlers = []func(interface{}){logPanic}
// handlers and logging the panic message.
//
// E.g., you can provide one or more additional handlers for something like shutting down go routines gracefully.
+//
+// Contextual logging: HandleCrashWithContext should be used instead of HandleCrash in code which supports contextual logging.
func HandleCrash(additionalHandlers ...func(interface{})) {
if r := recover(); r != nil {
- for _, fn := range PanicHandlers {
- fn(r)
- }
- for _, fn := range additionalHandlers {
- fn(r)
- }
- if ReallyCrash {
- // Actually proceed to panic.
- panic(r)
+ additionalHandlersWithContext := make([]func(context.Context, interface{}), len(additionalHandlers))
+ for i, handler := range additionalHandlers {
+ handler := handler // capture loop variable
+ additionalHandlersWithContext[i] = func(_ context.Context, r interface{}) {
+ handler(r)
+ }
}
+
+ handleCrash(context.Background(), r, additionalHandlersWithContext...)
+ }
+}
+
+// HandleCrashWithContext simply catches a crash and logs an error. Meant to be called via
+// defer. Additional context-specific handlers can be provided, and will be
+// called in case of panic. HandleCrash actually crashes, after calling the
+// handlers and logging the panic message.
+//
+// E.g., you can provide one or more additional handlers for something like shutting down go routines gracefully.
+//
+// The context is used to determine how to log.
+func HandleCrashWithContext(ctx context.Context, additionalHandlers ...func(context.Context, interface{})) {
+ if r := recover(); r != nil {
+ handleCrash(ctx, r, additionalHandlers...)
+ }
+}
+
+// handleCrash is the common implementation of HandleCrash and HandleCrash.
+// Having those call a common implementation ensures that the stack depth
+// is the same regardless through which path the handlers get invoked.
+func handleCrash(ctx context.Context, r any, additionalHandlers ...func(context.Context, interface{})) {
+ for _, fn := range PanicHandlers {
+ fn(ctx, r)
+ }
+ for _, fn := range additionalHandlers {
+ fn(ctx, r)
+ }
+ if ReallyCrash {
+ // Actually proceed to panic.
+ panic(r)
}
}
// logPanic logs the caller tree when a panic occurs (except in the special case of http.ErrAbortHandler).
-func logPanic(r interface{}) {
+func logPanic(ctx context.Context, r interface{}) {
if r == http.ErrAbortHandler {
// honor the http.ErrAbortHandler sentinel panic value:
// ErrAbortHandler is a sentinel panic value to abort a handler.
@@ -73,10 +105,20 @@ func logPanic(r interface{}) {
const size = 64 << 10
stacktrace := make([]byte, size)
stacktrace = stacktrace[:runtime.Stack(stacktrace, false)]
+
+ // We don't really know how many call frames to skip because the Go
+ // panic handler is between us and the code where the panic occurred.
+ // If it's one function (as in Go 1.21), then skipping four levels
+ // gets us to the function which called the `defer HandleCrashWithontext(...)`.
+ logger := klog.FromContext(ctx).WithCallDepth(4)
+
+ // For backwards compatibility, conversion to string
+ // is handled here instead of defering to the logging
+ // backend.
if _, ok := r.(string); ok {
- klog.Errorf("Observed a panic: %s\n%s", r, stacktrace)
+ logger.Error(nil, "Observed a panic", "panic", r, "stacktrace", string(stacktrace))
} else {
- klog.Errorf("Observed a panic: %#v (%v)\n%s", r, r, stacktrace)
+ logger.Error(nil, "Observed a panic", "panic", fmt.Sprintf("%v", r), "panicGoValue", fmt.Sprintf("%#v", r), "stacktrace", string(stacktrace))
}
}
@@ -84,35 +126,76 @@ func logPanic(r interface{}) {
// error occurs.
// TODO(lavalamp): for testability, this and the below HandleError function
// should be packaged up into a testable and reusable object.
-var ErrorHandlers = []func(error){
+var ErrorHandlers = []ErrorHandler{
logError,
- (&rudimentaryErrorBackoff{
- lastErrorTime: time.Now(),
- // 1ms was the number folks were able to stomach as a global rate limit.
- // If you need to log errors more than 1000 times a second you
- // should probably consider fixing your code instead. :)
- minPeriod: time.Millisecond,
- }).OnError,
+ func(_ context.Context, _ error, _ string, _ ...interface{}) {
+ (&rudimentaryErrorBackoff{
+ lastErrorTime: time.Now(),
+ // 1ms was the number folks were able to stomach as a global rate limit.
+ // If you need to log errors more than 1000 times a second you
+ // should probably consider fixing your code instead. :)
+ minPeriod: time.Millisecond,
+ }).OnError()
+ },
}
+type ErrorHandler func(ctx context.Context, err error, msg string, keysAndValues ...interface{})
+
// HandlerError is a method to invoke when a non-user facing piece of code cannot
// return an error and needs to indicate it has been ignored. Invoking this method
// is preferable to logging the error - the default behavior is to log but the
// errors may be sent to a remote server for analysis.
+//
+// Contextual logging: HandleErrorWithContext should be used instead of HandleError in code which supports contextual logging.
func HandleError(err error) {
// this is sometimes called with a nil error. We probably shouldn't fail and should do nothing instead
if err == nil {
return
}
+ handleError(context.Background(), err, "Unhandled Error")
+}
+
+// HandlerErrorWithContext is a method to invoke when a non-user facing piece of code cannot
+// return an error and needs to indicate it has been ignored. Invoking this method
+// is preferable to logging the error - the default behavior is to log but the
+// errors may be sent to a remote server for analysis. The context is used to
+// determine how to log the error.
+//
+// If contextual logging is enabled, the default log output is equivalent to
+//
+// logr.FromContext(ctx).WithName("UnhandledError").Error(err, msg, keysAndValues...)
+//
+// Without contextual logging, it is equivalent to:
+//
+// klog.ErrorS(err, msg, keysAndValues...)
+//
+// In contrast to HandleError, passing nil for the error is still going to
+// trigger a log entry. Don't construct a new error or wrap an error
+// with fmt.Errorf. Instead, add additional information via the mssage
+// and key/value pairs.
+//
+// This variant should be used instead of HandleError because it supports
+// structured, contextual logging.
+func HandleErrorWithContext(ctx context.Context, err error, msg string, keysAndValues ...interface{}) {
+ handleError(ctx, err, msg, keysAndValues...)
+}
+
+// handleError is the common implementation of HandleError and HandleErrorWithContext.
+// Using this common implementation ensures that the stack depth
+// is the same regardless through which path the handlers get invoked.
+func handleError(ctx context.Context, err error, msg string, keysAndValues ...interface{}) {
for _, fn := range ErrorHandlers {
- fn(err)
+ fn(ctx, err, msg, keysAndValues...)
}
}
-// logError prints an error with the call stack of the location it was reported
-func logError(err error) {
- klog.ErrorDepth(2, err)
+// logError prints an error with the call stack of the location it was reported.
+// It expects to be called as -> HandleError[WithContext] -> handleError -> logError.
+func logError(ctx context.Context, err error, msg string, keysAndValues ...interface{}) {
+ logger := klog.FromContext(ctx).WithCallDepth(3)
+ logger = klog.LoggerWithName(logger, "UnhandledError")
+ logger.Error(err, msg, keysAndValues...) //nolint:logcheck // logcheck complains about unknown key/value pairs.
}
type rudimentaryErrorBackoff struct {
@@ -125,15 +208,18 @@ type rudimentaryErrorBackoff struct {
// OnError will block if it is called more often than the embedded period time.
// This will prevent overly tight hot error loops.
-func (r *rudimentaryErrorBackoff) OnError(error) {
+func (r *rudimentaryErrorBackoff) OnError() {
+ now := time.Now() // start the timer before acquiring the lock
r.lastErrorTimeLock.Lock()
- defer r.lastErrorTimeLock.Unlock()
- d := time.Since(r.lastErrorTime)
- if d < r.minPeriod {
- // If the time moves backwards for any reason, do nothing
- time.Sleep(r.minPeriod - d)
- }
+ d := now.Sub(r.lastErrorTime)
r.lastErrorTime = time.Now()
+ r.lastErrorTimeLock.Unlock()
+
+ // Do not sleep with the lock held because that causes all callers of HandleError to block.
+ // We only want the current goroutine to block.
+ // A negative or zero duration causes time.Sleep to return immediately.
+ // If the time moves backwards for any reason, do nothing.
+ time.Sleep(r.minPeriod - d)
}
// GetCaller returns the caller of the function that calls it.
diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/doc.go b/vendor/k8s.io/apimachinery/pkg/util/sets/doc.go
index 194883390..fd281bdb8 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/sets/doc.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/sets/doc.go
@@ -16,4 +16,4 @@ limitations under the License.
// Package sets has generic set and specified sets. Generic set will
// replace specified ones over time. And specific ones are deprecated.
-package sets
+package sets // import "k8s.io/apimachinery/pkg/util/sets"
diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/ordered.go b/vendor/k8s.io/apimachinery/pkg/util/sets/ordered.go
deleted file mode 100644
index 443dac62e..000000000
--- a/vendor/k8s.io/apimachinery/pkg/util/sets/ordered.go
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-Copyright 2022 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 sets
-
-// ordered is a constraint that permits any ordered type: any type
-// that supports the operators < <= >= >.
-// If future releases of Go add new ordered types,
-// this constraint will be modified to include them.
-type ordered interface {
- integer | float | ~string
-}
-
-// integer is a constraint that permits any integer type.
-// If future releases of Go add new predeclared integer types,
-// this constraint will be modified to include them.
-type integer interface {
- signed | unsigned
-}
-
-// float is a constraint that permits any floating-point type.
-// If future releases of Go add new predeclared floating-point types,
-// this constraint will be modified to include them.
-type float interface {
- ~float32 | ~float64
-}
-
-// signed is a constraint that permits any signed integer type.
-// If future releases of Go add new predeclared signed integer types,
-// this constraint will be modified to include them.
-type signed interface {
- ~int | ~int8 | ~int16 | ~int32 | ~int64
-}
-
-// unsigned is a constraint that permits any unsigned integer type.
-// If future releases of Go add new predeclared unsigned integer types,
-// this constraint will be modified to include them.
-type unsigned interface {
- ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
-}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/set.go b/vendor/k8s.io/apimachinery/pkg/util/sets/set.go
index 99c292fed..cd961c8c5 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/sets/set.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/sets/set.go
@@ -17,6 +17,7 @@ limitations under the License.
package sets
import (
+ "cmp"
"sort"
)
@@ -37,7 +38,7 @@ func New[T comparable](items ...T) Set[T] {
// KeySet creates a Set from a keys of a map[comparable](? extends interface{}).
// If the value passed in is not actually a map, this will panic.
func KeySet[T comparable, V any](theMap map[T]V) Set[T] {
- ret := Set[T]{}
+ ret := make(Set[T], len(theMap))
for keyValue := range theMap {
ret.Insert(keyValue)
}
@@ -64,6 +65,14 @@ func (s Set[T]) Delete(items ...T) Set[T] {
return s
}
+// Clear empties the set.
+// It is preferable to replace the set with a newly constructed set,
+// but not all callers can do that (when there are other references to the map).
+func (s Set[T]) Clear() Set[T] {
+ clear(s)
+ return s
+}
+
// Has returns true if and only if item is contained in the set.
func (s Set[T]) Has(item T) bool {
_, contained := s[item]
@@ -179,7 +188,7 @@ func (s1 Set[T]) Equal(s2 Set[T]) bool {
return len(s1) == len(s2) && s1.IsSuperset(s2)
}
-type sortableSliceOfGeneric[T ordered] []T
+type sortableSliceOfGeneric[T cmp.Ordered] []T
func (g sortableSliceOfGeneric[T]) Len() int { return len(g) }
func (g sortableSliceOfGeneric[T]) Less(i, j int) bool { return less[T](g[i], g[j]) }
@@ -189,7 +198,7 @@ func (g sortableSliceOfGeneric[T]) Swap(i, j int) { g[i], g[j] = g[j], g[i]
//
// This is a separate function and not a method because not all types supported
// by Generic are ordered and only those can be sorted.
-func List[T ordered](s Set[T]) []T {
+func List[T cmp.Ordered](s Set[T]) []T {
res := make(sortableSliceOfGeneric[T], 0, len(s))
for key := range s {
res = append(res, key)
@@ -222,6 +231,6 @@ func (s Set[T]) Len() int {
return len(s)
}
-func less[T ordered](lhs, rhs T) bool {
+func less[T cmp.Ordered](lhs, rhs T) bool {
return lhs < rhs
}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS
index 4443bafd1..73244449f 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS
+++ b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS
@@ -1,6 +1,7 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
+ - apelisse
- pwittrock
reviewers:
- apelisse
diff --git a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/meta.go b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/meta.go
index df305b712..85b0cfc07 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/meta.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/meta.go
@@ -20,12 +20,17 @@ import (
"errors"
"fmt"
"reflect"
+ "strings"
"k8s.io/apimachinery/pkg/util/mergepatch"
forkedjson "k8s.io/apimachinery/third_party/forked/golang/json"
openapi "k8s.io/kube-openapi/pkg/util/proto"
+ "k8s.io/kube-openapi/pkg/validation/spec"
)
+const patchMergeKey = "x-kubernetes-patch-merge-key"
+const patchStrategy = "x-kubernetes-patch-strategy"
+
type PatchMeta struct {
patchStrategies []string
patchMergeKey string
@@ -148,6 +153,90 @@ func GetTagStructTypeOrDie(dataStruct interface{}) reflect.Type {
return t
}
+type PatchMetaFromOpenAPIV3 struct {
+ // SchemaList is required to resolve OpenAPI V3 references
+ SchemaList map[string]*spec.Schema
+ Schema *spec.Schema
+}
+
+func (s PatchMetaFromOpenAPIV3) traverse(key string) (PatchMetaFromOpenAPIV3, error) {
+ if s.Schema == nil {
+ return PatchMetaFromOpenAPIV3{}, nil
+ }
+ if len(s.Schema.Properties) == 0 {
+ return PatchMetaFromOpenAPIV3{}, fmt.Errorf("unable to find api field \"%s\"", key)
+ }
+ subschema, ok := s.Schema.Properties[key]
+ if !ok {
+ return PatchMetaFromOpenAPIV3{}, fmt.Errorf("unable to find api field \"%s\"", key)
+ }
+ return PatchMetaFromOpenAPIV3{SchemaList: s.SchemaList, Schema: &subschema}, nil
+}
+
+func resolve(l *PatchMetaFromOpenAPIV3) error {
+ if len(l.Schema.AllOf) > 0 {
+ l.Schema = &l.Schema.AllOf[0]
+ }
+ if refString := l.Schema.Ref.String(); refString != "" {
+ str := strings.TrimPrefix(refString, "#/components/schemas/")
+ sch, ok := l.SchemaList[str]
+ if ok {
+ l.Schema = sch
+ } else {
+ return fmt.Errorf("unable to resolve %s in OpenAPI V3", refString)
+ }
+ }
+ return nil
+}
+
+func (s PatchMetaFromOpenAPIV3) LookupPatchMetadataForStruct(key string) (LookupPatchMeta, PatchMeta, error) {
+ l, err := s.traverse(key)
+ if err != nil {
+ return l, PatchMeta{}, err
+ }
+ p := PatchMeta{}
+ f, ok := l.Schema.Extensions[patchMergeKey]
+ if ok {
+ p.SetPatchMergeKey(f.(string))
+ }
+ g, ok := l.Schema.Extensions[patchStrategy]
+ if ok {
+ p.SetPatchStrategies(strings.Split(g.(string), ","))
+ }
+
+ err = resolve(&l)
+ return l, p, err
+}
+
+func (s PatchMetaFromOpenAPIV3) LookupPatchMetadataForSlice(key string) (LookupPatchMeta, PatchMeta, error) {
+ l, err := s.traverse(key)
+ if err != nil {
+ return l, PatchMeta{}, err
+ }
+ p := PatchMeta{}
+ f, ok := l.Schema.Extensions[patchMergeKey]
+ if ok {
+ p.SetPatchMergeKey(f.(string))
+ }
+ g, ok := l.Schema.Extensions[patchStrategy]
+ if ok {
+ p.SetPatchStrategies(strings.Split(g.(string), ","))
+ }
+ if l.Schema.Items != nil {
+ l.Schema = l.Schema.Items.Schema
+ }
+ err = resolve(&l)
+ return l, p, err
+}
+
+func (s PatchMetaFromOpenAPIV3) Name() string {
+ schema := s.Schema
+ if len(schema.Type) > 0 {
+ return strings.Join(schema.Type, "")
+ }
+ return "Struct"
+}
+
type PatchMetaFromOpenAPI struct {
Schema openapi.Schema
}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go
index 6fb369732..6825a808e 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go
@@ -1106,7 +1106,7 @@ func applyRetainKeysDirective(original, patch map[string]interface{}, options Me
// Then, sort them by the relative order in setElementOrder, patch list and live list.
// The precedence is $setElementOrder > order in patch list > order in live list.
// This function will delete the item after merging it to prevent process it again in the future.
-// Ref: https://git.k8s.io/community/contributors/design-proposals/cli/preserve-order-in-strategic-merge-patch.md
+// Ref: https://git.k8s.io/design-proposals-archive/cli/preserve-order-in-strategic-merge-patch.md
func mergePatchIntoOriginal(original, patch map[string]interface{}, schema LookupPatchMeta, mergeOptions MergeOptions) error {
for key, patchV := range patch {
// Do nothing if there is no ordering directive
@@ -1182,7 +1182,13 @@ func mergePatchIntoOriginal(original, patch map[string]interface{}, schema Looku
merged = originalFieldValue
case !foundOriginal && foundPatch:
// list was added
- merged = patchFieldValue
+ v, keep := removeDirectives(patchFieldValue)
+ if !keep {
+ // Shouldn't be possible since patchFieldValue is a slice
+ continue
+ }
+
+ merged = v.([]interface{})
case foundOriginal && foundPatch:
merged, err = mergeSliceHandler(originalList, patchList, subschema,
patchStrategy, patchMeta.GetPatchMergeKey(), false, mergeOptions)
@@ -1270,6 +1276,42 @@ func partitionMapsByPresentInList(original, partitionBy []interface{}, mergeKey
return patch, serverOnly, nil
}
+// Removes directives from an object and returns value to use instead and whether
+// or not the field/index should even be kept
+// May modify input
+func removeDirectives(obj interface{}) (interface{}, bool) {
+ if obj == nil {
+ return obj, true
+ } else if typedV, ok := obj.(map[string]interface{}); ok {
+ if _, hasDirective := typedV[directiveMarker]; hasDirective {
+ return nil, false
+ }
+
+ for k, v := range typedV {
+ var keep bool
+ typedV[k], keep = removeDirectives(v)
+ if !keep {
+ delete(typedV, k)
+ }
+ }
+ return typedV, true
+ } else if typedV, ok := obj.([]interface{}); ok {
+ var res []interface{}
+ if typedV != nil {
+ // Make sure res is non-nil if patch is non-nil
+ res = []interface{}{}
+ }
+ for _, v := range typedV {
+ if newV, keep := removeDirectives(v); keep {
+ res = append(res, newV)
+ }
+ }
+ return res, true
+ } else {
+ return obj, true
+ }
+}
+
// Merge fields from a patch map into the original map. Note: This may modify
// both the original map and the patch because getting a deep copy of a map in
// golang is highly non-trivial.
@@ -1319,6 +1361,10 @@ func mergeMap(original, patch map[string]interface{}, schema LookupPatchMeta, me
// original. Otherwise, check if we want to preserve it or skip it.
// Preserving the null value is useful when we want to send an explicit
// delete to the API server.
+ // In some cases, this may lead to inconsistent behavior with create.
+ // ref: https://github.com/kubernetes/kubernetes/issues/123304
+ // To avoid breaking compatibility,
+ // we made corresponding changes on the client side to ensure that the create and patch behaviors are idempotent.
if patchV == nil {
delete(original, k)
if mergeOptions.IgnoreUnmatchedNulls {
@@ -1333,7 +1379,10 @@ func mergeMap(original, patch map[string]interface{}, schema LookupPatchMeta, me
if mergeOptions.IgnoreUnmatchedNulls {
discardNullValuesFromPatch(patchV)
}
- original[k] = patchV
+ original[k], ok = removeDirectives(patchV)
+ if !ok {
+ delete(original, k)
+ }
}
continue
}
@@ -1345,7 +1394,10 @@ func mergeMap(original, patch map[string]interface{}, schema LookupPatchMeta, me
if mergeOptions.IgnoreUnmatchedNulls {
discardNullValuesFromPatch(patchV)
}
- original[k] = patchV
+ original[k], ok = removeDirectives(patchV)
+ if !ok {
+ delete(original, k)
+ }
}
continue
}
@@ -1372,7 +1424,11 @@ func mergeMap(original, patch map[string]interface{}, schema LookupPatchMeta, me
}
original[k], err = mergeSliceHandler(original[k], patchV, subschema, patchStrategy, patchMeta.GetPatchMergeKey(), isDeleteList, mergeOptions)
default:
- original[k] = patchV
+ original[k], ok = removeDirectives(patchV)
+ if !ok {
+ // if patchV itself is a directive, then don't keep it
+ delete(original, k)
+ }
}
if err != nil {
return nil, err
@@ -1425,7 +1481,8 @@ func mergeSliceHandler(original, patch interface{}, schema LookupPatchMeta,
return nil, err
}
- if fieldPatchStrategy == mergeDirective {
+ // Delete lists are handled the same way regardless of what the field's patch strategy is
+ if fieldPatchStrategy == mergeDirective || isDeleteList {
return mergeSlice(typedOriginal, typedPatch, schema, fieldPatchMergeKey, mergeOptions, isDeleteList)
} else {
return typedPatch, nil
diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/OWNERS b/vendor/k8s.io/apimachinery/pkg/util/validation/OWNERS
new file mode 100644
index 000000000..402373247
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/validation/OWNERS
@@ -0,0 +1,11 @@
+# See the OWNERS docs at https://go.k8s.io/owners
+
+# Disable inheritance as this is an api owners file
+options:
+ no_parent_owners: true
+approvers:
+ - api-approvers
+reviewers:
+ - api-reviewers
+labels:
+ - kind/api-change
diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go b/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go
index ae73bda96..f1634bc0d 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go
@@ -200,12 +200,12 @@ func Invalid(field *Path, value interface{}, detail string) *Error {
// NotSupported returns a *Error indicating "unsupported value".
// This is used to report unknown values for enumerated fields (e.g. a list of
// valid values).
-func NotSupported(field *Path, value interface{}, validValues []string) *Error {
+func NotSupported[T ~string](field *Path, value interface{}, validValues []T) *Error {
detail := ""
if len(validValues) > 0 {
quotedValues := make([]string, len(validValues))
for i, v := range validValues {
- quotedValues[i] = strconv.Quote(v)
+ quotedValues[i] = strconv.Quote(fmt.Sprint(v))
}
detail = "supported values: " + strings.Join(quotedValues, ", ")
}
@@ -220,26 +220,24 @@ func Forbidden(field *Path, detail string) *Error {
return &Error{ErrorTypeForbidden, field.String(), "", detail}
}
-// TooLong returns a *Error indicating "too long". This is used to
-// report that the given value is too long. This is similar to
-// Invalid, but the returned error will not include the too-long
-// value.
+// TooLong returns a *Error indicating "too long". This is used to report that
+// the given value is too long. This is similar to Invalid, but the returned
+// error will not include the too-long value. If maxLength is negative, it will
+// be included in the message. The value argument is not used.
func TooLong(field *Path, value interface{}, maxLength int) *Error {
- return &Error{ErrorTypeTooLong, field.String(), value, fmt.Sprintf("must have at most %d bytes", maxLength)}
-}
-
-// TooLongMaxLength returns a *Error indicating "too long". This is used to
-// report that the given value is too long. This is similar to
-// Invalid, but the returned error will not include the too-long
-// value. If maxLength is negative, no max length will be included in the message.
-func TooLongMaxLength(field *Path, value interface{}, maxLength int) *Error {
var msg string
if maxLength >= 0 {
- msg = fmt.Sprintf("may not be longer than %d", maxLength)
+ msg = fmt.Sprintf("may not be more than %d bytes", maxLength)
} else {
msg = "value is too long"
}
- return &Error{ErrorTypeTooLong, field.String(), value, msg}
+ return &Error{ErrorTypeTooLong, field.String(), "", msg}
+}
+
+// TooLongMaxLength returns a *Error indicating "too long".
+// Deprecated: Use TooLong instead.
+func TooLongMaxLength(field *Path, value interface{}, maxLength int) *Error {
+ return TooLong(field, "", maxLength)
}
// TooMany returns a *Error indicating "too many". This is used to
diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go b/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go
index e767092dd..9bc393cf5 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go
@@ -19,10 +19,9 @@ package validation
import (
"fmt"
"math"
- "net"
"regexp"
- "strconv"
"strings"
+ "unicode"
"k8s.io/apimachinery/pkg/util/validation/field"
netutils "k8s.io/utils/net"
@@ -176,6 +175,8 @@ func IsValidLabelValue(value string) []string {
}
const dns1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
+const dns1123LabelFmtWithUnderscore string = "_?[a-z0-9]([-_a-z0-9]*[a-z0-9])?"
+
const dns1123LabelErrMsg string = "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character"
// DNS1123LabelMaxLength is a label's max length in DNS (RFC 1123)
@@ -191,7 +192,13 @@ func IsDNS1123Label(value string) []string {
errs = append(errs, MaxLenError(DNS1123LabelMaxLength))
}
if !dns1123LabelRegexp.MatchString(value) {
- errs = append(errs, RegexError(dns1123LabelErrMsg, dns1123LabelFmt, "my-name", "123-abc"))
+ if dns1123SubdomainRegexp.MatchString(value) {
+ // It was a valid subdomain and not a valid label. Since we
+ // already checked length, it must be dots.
+ errs = append(errs, "must not contain dots")
+ } else {
+ errs = append(errs, RegexError(dns1123LabelErrMsg, dns1123LabelFmt, "my-name", "123-abc"))
+ }
}
return errs
}
@@ -199,10 +206,14 @@ func IsDNS1123Label(value string) []string {
const dns1123SubdomainFmt string = dns1123LabelFmt + "(\\." + dns1123LabelFmt + ")*"
const dns1123SubdomainErrorMsg string = "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character"
+const dns1123SubdomainFmtWithUnderscore string = dns1123LabelFmtWithUnderscore + "(\\." + dns1123LabelFmtWithUnderscore + ")*"
+const dns1123SubdomainErrorMsgFG string = "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '_', '-' or '.', and must start and end with an alphanumeric character"
+
// DNS1123SubdomainMaxLength is a subdomain's max length in DNS (RFC 1123)
const DNS1123SubdomainMaxLength int = 253
var dns1123SubdomainRegexp = regexp.MustCompile("^" + dns1123SubdomainFmt + "$")
+var dns1123SubdomainRegexpWithUnderscore = regexp.MustCompile("^" + dns1123SubdomainFmtWithUnderscore + "$")
// IsDNS1123Subdomain tests for a string that conforms to the definition of a
// subdomain in DNS (RFC 1123).
@@ -217,6 +228,19 @@ func IsDNS1123Subdomain(value string) []string {
return errs
}
+// IsDNS1123SubdomainWithUnderscore tests for a string that conforms to the definition of a
+// subdomain in DNS (RFC 1123), but allows the use of an underscore in the string
+func IsDNS1123SubdomainWithUnderscore(value string) []string {
+ var errs []string
+ if len(value) > DNS1123SubdomainMaxLength {
+ errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength))
+ }
+ if !dns1123SubdomainRegexpWithUnderscore.MatchString(value) {
+ errs = append(errs, RegexError(dns1123SubdomainErrorMsgFG, dns1123SubdomainFmt, "example.com"))
+ }
+ return errs
+}
+
const dns1035LabelFmt string = "[a-z]([-a-z0-9]*[a-z0-9])?"
const dns1035LabelErrMsg string = "a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character"
@@ -346,11 +370,12 @@ func IsValidPortName(port string) []string {
}
// IsValidIP tests that the argument is a valid IP address.
-func IsValidIP(value string) []string {
+func IsValidIP(fldPath *field.Path, value string) field.ErrorList {
+ var allErrors field.ErrorList
if netutils.ParseIPSloppy(value) == nil {
- return []string{"must be a valid IP address, (e.g. 10.9.8.7 or 2001:db8::ffff)"}
+ allErrors = append(allErrors, field.Invalid(fldPath, value, "must be a valid IP address, (e.g. 10.9.8.7 or 2001:db8::ffff)"))
}
- return nil
+ return allErrors
}
// IsValidIPv4Address tests that the argument is a valid IPv4 address.
@@ -373,6 +398,16 @@ func IsValidIPv6Address(fldPath *field.Path, value string) field.ErrorList {
return allErrors
}
+// IsValidCIDR tests that the argument is a valid CIDR value.
+func IsValidCIDR(fldPath *field.Path, value string) field.ErrorList {
+ var allErrors field.ErrorList
+ _, _, err := netutils.ParseCIDRSloppy(value)
+ if err != nil {
+ allErrors = append(allErrors, field.Invalid(fldPath, value, "must be a valid CIDR value, (e.g. 10.9.8.0/24 or 2001:db8::/64)"))
+ }
+ return allErrors
+}
+
const percentFmt string = "[0-9]+%"
const percentErrMsg string = "a valid percent string must be a numeric string followed by an ending '%'"
@@ -403,6 +438,9 @@ func IsHTTPHeaderName(value string) []string {
const envVarNameFmt = "[-._a-zA-Z][-._a-zA-Z0-9]*"
const envVarNameFmtErrMsg string = "a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit"
+// TODO(hirazawaui): Rename this when the RelaxedEnvironmentVariableValidation gate is removed.
+const relaxedEnvVarNameFmtErrMsg string = "a valid environment variable name must consist only of printable ASCII characters other than '='"
+
var envVarNameRegexp = regexp.MustCompile("^" + envVarNameFmt + "$")
// IsEnvVarName tests if a string is a valid environment variable name.
@@ -416,6 +454,24 @@ func IsEnvVarName(value string) []string {
return errs
}
+// IsRelaxedEnvVarName tests if a string is a valid environment variable name.
+func IsRelaxedEnvVarName(value string) []string {
+ var errs []string
+
+ if len(value) == 0 {
+ errs = append(errs, "environment variable name "+EmptyError())
+ }
+
+ for _, r := range value {
+ if r > unicode.MaxASCII || !unicode.IsPrint(r) || r == '=' {
+ errs = append(errs, relaxedEnvVarNameFmtErrMsg)
+ break
+ }
+ }
+
+ return errs
+}
+
const configMapKeyFmt = `[-._a-zA-Z0-9]+`
const configMapKeyErrMsg string = "a valid config key must consist of alphanumeric characters, '-', '_' or '.'"
@@ -487,18 +543,3 @@ func hasChDirPrefix(value string) []string {
}
return errs
}
-
-// IsValidSocketAddr checks that string represents a valid socket address
-// as defined in RFC 789. (e.g 0.0.0.0:10254 or [::]:10254))
-func IsValidSocketAddr(value string) []string {
- var errs []string
- ip, port, err := net.SplitHostPort(value)
- if err != nil {
- errs = append(errs, "must be a valid socket address format, (e.g. 0.0.0.0:10254 or [::]:10254)")
- return errs
- }
- portInt, _ := strconv.Atoi(port)
- errs = append(errs, IsValidPortNum(portInt)...)
- errs = append(errs, IsValidIP(ip)...)
- return errs
-}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/version/version.go b/vendor/k8s.io/apimachinery/pkg/util/version/version.go
index 8c997ec45..b7812ff2d 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/version/version.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/version/version.go
@@ -18,10 +18,13 @@ package version
import (
"bytes"
+ "errors"
"fmt"
"regexp"
"strconv"
"strings"
+
+ apimachineryversion "k8s.io/apimachinery/pkg/version"
)
// Version is an opaque representation of a version number
@@ -30,6 +33,7 @@ type Version struct {
semver bool
preRelease string
buildMetadata string
+ info apimachineryversion.Info
}
var (
@@ -85,6 +89,47 @@ func parse(str string, semver bool) (*Version, error) {
return v, nil
}
+// HighestSupportedVersion returns the highest supported version
+// This function assumes that the highest supported version must be v1.x.
+func HighestSupportedVersion(versions []string) (*Version, error) {
+ if len(versions) == 0 {
+ return nil, errors.New("empty array for supported versions")
+ }
+
+ var (
+ highestSupportedVersion *Version
+ theErr error
+ )
+
+ for i := len(versions) - 1; i >= 0; i-- {
+ currentHighestVer, err := ParseGeneric(versions[i])
+ if err != nil {
+ theErr = err
+ continue
+ }
+
+ if currentHighestVer.Major() > 1 {
+ continue
+ }
+
+ if highestSupportedVersion == nil || highestSupportedVersion.LessThan(currentHighestVer) {
+ highestSupportedVersion = currentHighestVer
+ }
+ }
+
+ if highestSupportedVersion == nil {
+ return nil, fmt.Errorf(
+ "could not find a highest supported version from versions (%v) reported: %+v",
+ versions, theErr)
+ }
+
+ if highestSupportedVersion.Major() != 1 {
+ return nil, fmt.Errorf("highest supported version reported is %v, must be v1.x", highestSupportedVersion)
+ }
+
+ return highestSupportedVersion, nil
+}
+
// ParseGeneric parses a "generic" version string. The version string must consist of two
// or more dot-separated numeric fields (the first of which can't have leading zeroes),
// followed by arbitrary uninterpreted data (which need not be separated from the final
@@ -103,6 +148,43 @@ func MustParseGeneric(str string) *Version {
return v
}
+// Parse tries to do ParseSemantic first to keep more information.
+// If ParseSemantic fails, it would just do ParseGeneric.
+func Parse(str string) (*Version, error) {
+ v, err := parse(str, true)
+ if err != nil {
+ return parse(str, false)
+ }
+ return v, err
+}
+
+// MustParse is like Parse except that it panics on error
+func MustParse(str string) *Version {
+ v, err := Parse(str)
+ if err != nil {
+ panic(err)
+ }
+ return v
+}
+
+// ParseMajorMinor parses a "generic" version string and returns a version with the major and minor version.
+func ParseMajorMinor(str string) (*Version, error) {
+ v, err := ParseGeneric(str)
+ if err != nil {
+ return nil, err
+ }
+ return MajorMinor(v.Major(), v.Minor()), nil
+}
+
+// MustParseMajorMinor is like ParseMajorMinor except that it panics on error
+func MustParseMajorMinor(str string) *Version {
+ v, err := ParseMajorMinor(str)
+ if err != nil {
+ panic(err)
+ }
+ return v
+}
+
// ParseSemantic parses a version string that exactly obeys the syntax and semantics of
// the "Semantic Versioning" specification (http://semver.org/) (although it ignores
// leading and trailing whitespace, and allows the version to be preceded by "v"). For
@@ -121,6 +203,11 @@ func MustParseSemantic(str string) *Version {
return v
}
+// MajorMinor returns a version with the provided major and minor version.
+func MajorMinor(major, minor uint) *Version {
+ return &Version{components: []uint{major, minor}}
+}
+
// Major returns the major release number
func (v *Version) Major() uint {
return v.components[0]
@@ -168,6 +255,32 @@ func (v *Version) WithMinor(minor uint) *Version {
return &result
}
+// SubtractMinor returns the version with offset from the original minor, with the same major and no patch.
+// If -offset >= current minor, the minor would be 0.
+func (v *Version) OffsetMinor(offset int) *Version {
+ var minor uint
+ if offset >= 0 {
+ minor = v.Minor() + uint(offset)
+ } else {
+ diff := uint(-offset)
+ if diff < v.Minor() {
+ minor = v.Minor() - diff
+ }
+ }
+ return MajorMinor(v.Major(), minor)
+}
+
+// SubtractMinor returns the version diff minor versions back, with the same major and no patch.
+// If diff >= current minor, the minor would be 0.
+func (v *Version) SubtractMinor(diff uint) *Version {
+ return v.OffsetMinor(-int(diff))
+}
+
+// AddMinor returns the version diff minor versions forward, with the same major and no patch.
+func (v *Version) AddMinor(diff uint) *Version {
+ return v.OffsetMinor(int(diff))
+}
+
// WithPatch returns copy of the version object with requested patch number
func (v *Version) WithPatch(patch uint) *Version {
result := *v
@@ -177,6 +290,9 @@ func (v *Version) WithPatch(patch uint) *Version {
// WithPreRelease returns copy of the version object with requested prerelease
func (v *Version) WithPreRelease(preRelease string) *Version {
+ if len(preRelease) == 0 {
+ return v
+ }
result := *v
result.components = []uint{v.Major(), v.Minor(), v.Patch()}
result.preRelease = preRelease
@@ -298,6 +414,17 @@ func onlyZeros(array []uint) bool {
return true
}
+// EqualTo tests if a version is equal to a given version.
+func (v *Version) EqualTo(other *Version) bool {
+ if v == nil {
+ return other == nil
+ }
+ if other == nil {
+ return false
+ }
+ return v.compareInternal(other) == 0
+}
+
// AtLeast tests if a version is at least equal to a given minimum version. If both
// Versions are Semantic Versions, this will use the Semantic Version comparison
// algorithm. Otherwise, it will compare only the numeric components, with non-present
@@ -313,6 +440,11 @@ func (v *Version) LessThan(other *Version) bool {
return v.compareInternal(other) == -1
}
+// GreaterThan tests if a version is greater than a given version.
+func (v *Version) GreaterThan(other *Version) bool {
+ return v.compareInternal(other) == 1
+}
+
// Compare compares v against a version string (which will be parsed as either Semantic
// or non-Semantic depending on v). On success it returns -1 if v is less than other, 1 if
// it is greater than other, or 0 if they are equal.
@@ -323,3 +455,30 @@ func (v *Version) Compare(other string) (int, error) {
}
return v.compareInternal(ov), nil
}
+
+// WithInfo returns copy of the version object with requested info
+func (v *Version) WithInfo(info apimachineryversion.Info) *Version {
+ result := *v
+ result.info = info
+ return &result
+}
+
+func (v *Version) Info() *apimachineryversion.Info {
+ if v == nil {
+ return nil
+ }
+ // in case info is empty, or the major and minor in info is different from the actual major and minor
+ v.info.Major = itoa(v.Major())
+ v.info.Minor = itoa(v.Minor())
+ if v.info.GitVersion == "" {
+ v.info.GitVersion = v.String()
+ }
+ return &v.info
+}
+
+func itoa(i uint) string {
+ if i == 0 {
+ return ""
+ }
+ return strconv.Itoa(int(i))
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/backoff.go b/vendor/k8s.io/apimachinery/pkg/util/wait/backoff.go
new file mode 100644
index 000000000..418761925
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/wait/backoff.go
@@ -0,0 +1,502 @@
+/*
+Copyright 2023 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 wait
+
+import (
+ "context"
+ "math"
+ "sync"
+ "time"
+
+ "k8s.io/apimachinery/pkg/util/runtime"
+ "k8s.io/utils/clock"
+)
+
+// Backoff holds parameters applied to a Backoff function.
+type Backoff struct {
+ // The initial duration.
+ Duration time.Duration
+ // Duration is multiplied by factor each iteration, if factor is not zero
+ // and the limits imposed by Steps and Cap have not been reached.
+ // Should not be negative.
+ // The jitter does not contribute to the updates to the duration parameter.
+ Factor float64
+ // The sleep at each iteration is the duration plus an additional
+ // amount chosen uniformly at random from the interval between
+ // zero and `jitter*duration`.
+ Jitter float64
+ // The remaining number of iterations in which the duration
+ // parameter may change (but progress can be stopped earlier by
+ // hitting the cap). If not positive, the duration is not
+ // changed. Used for exponential backoff in combination with
+ // Factor and Cap.
+ Steps int
+ // A limit on revised values of the duration parameter. If a
+ // multiplication by the factor parameter would make the duration
+ // exceed the cap then the duration is set to the cap and the
+ // steps parameter is set to zero.
+ Cap time.Duration
+}
+
+// Step returns an amount of time to sleep determined by the original
+// Duration and Jitter. The backoff is mutated to update its Steps and
+// Duration. A nil Backoff always has a zero-duration step.
+func (b *Backoff) Step() time.Duration {
+ if b == nil {
+ return 0
+ }
+ var nextDuration time.Duration
+ nextDuration, b.Duration, b.Steps = delay(b.Steps, b.Duration, b.Cap, b.Factor, b.Jitter)
+ return nextDuration
+}
+
+// DelayFunc returns a function that will compute the next interval to
+// wait given the arguments in b. It does not mutate the original backoff
+// but the function is safe to use only from a single goroutine.
+func (b Backoff) DelayFunc() DelayFunc {
+ steps := b.Steps
+ duration := b.Duration
+ cap := b.Cap
+ factor := b.Factor
+ jitter := b.Jitter
+
+ return func() time.Duration {
+ var nextDuration time.Duration
+ // jitter is applied per step and is not cumulative over multiple steps
+ nextDuration, duration, steps = delay(steps, duration, cap, factor, jitter)
+ return nextDuration
+ }
+}
+
+// Timer returns a timer implementation appropriate to this backoff's parameters
+// for use with wait functions.
+func (b Backoff) Timer() Timer {
+ if b.Steps > 1 || b.Jitter != 0 {
+ return &variableTimer{new: internalClock.NewTimer, fn: b.DelayFunc()}
+ }
+ if b.Duration > 0 {
+ return &fixedTimer{new: internalClock.NewTicker, interval: b.Duration}
+ }
+ return newNoopTimer()
+}
+
+// delay implements the core delay algorithm used in this package.
+func delay(steps int, duration, cap time.Duration, factor, jitter float64) (_ time.Duration, next time.Duration, nextSteps int) {
+ // when steps is non-positive, do not alter the base duration
+ if steps < 1 {
+ if jitter > 0 {
+ return Jitter(duration, jitter), duration, 0
+ }
+ return duration, duration, 0
+ }
+ steps--
+
+ // calculate the next step's interval
+ if factor != 0 {
+ next = time.Duration(float64(duration) * factor)
+ if cap > 0 && next > cap {
+ next = cap
+ steps = 0
+ }
+ } else {
+ next = duration
+ }
+
+ // add jitter for this step
+ if jitter > 0 {
+ duration = Jitter(duration, jitter)
+ }
+
+ return duration, next, steps
+
+}
+
+// DelayWithReset returns a DelayFunc that will return the appropriate next interval to
+// wait. Every resetInterval the backoff parameters are reset to their initial state.
+// This method is safe to invoke from multiple goroutines, but all calls will advance
+// the backoff state when Factor is set. If Factor is zero, this method is the same as
+// invoking b.DelayFunc() since Steps has no impact without Factor. If resetInterval is
+// zero no backoff will be performed as the same calling DelayFunc with a zero factor
+// and steps.
+func (b Backoff) DelayWithReset(c clock.Clock, resetInterval time.Duration) DelayFunc {
+ if b.Factor <= 0 {
+ return b.DelayFunc()
+ }
+ if resetInterval <= 0 {
+ b.Steps = 0
+ b.Factor = 0
+ return b.DelayFunc()
+ }
+ return (&backoffManager{
+ backoff: b,
+ initialBackoff: b,
+ resetInterval: resetInterval,
+
+ clock: c,
+ lastStart: c.Now(),
+ timer: nil,
+ }).Step
+}
+
+// Until loops until stop channel is closed, running f every period.
+//
+// Until is syntactic sugar on top of JitterUntil with zero jitter factor and
+// with sliding = true (which means the timer for period starts after the f
+// completes).
+func Until(f func(), period time.Duration, stopCh <-chan struct{}) {
+ JitterUntil(f, period, 0.0, true, stopCh)
+}
+
+// UntilWithContext loops until context is done, running f every period.
+//
+// UntilWithContext is syntactic sugar on top of JitterUntilWithContext
+// with zero jitter factor and with sliding = true (which means the timer
+// for period starts after the f completes).
+func UntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) {
+ JitterUntilWithContext(ctx, f, period, 0.0, true)
+}
+
+// NonSlidingUntil loops until stop channel is closed, running f every
+// period.
+//
+// NonSlidingUntil is syntactic sugar on top of JitterUntil with zero jitter
+// factor, with sliding = false (meaning the timer for period starts at the same
+// time as the function starts).
+func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{}) {
+ JitterUntil(f, period, 0.0, false, stopCh)
+}
+
+// NonSlidingUntilWithContext loops until context is done, running f every
+// period.
+//
+// NonSlidingUntilWithContext is syntactic sugar on top of JitterUntilWithContext
+// with zero jitter factor, with sliding = false (meaning the timer for period
+// starts at the same time as the function starts).
+func NonSlidingUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) {
+ JitterUntilWithContext(ctx, f, period, 0.0, false)
+}
+
+// JitterUntil loops until stop channel is closed, running f every period.
+//
+// If jitterFactor is positive, the period is jittered before every run of f.
+// If jitterFactor is not positive, the period is unchanged and not jittered.
+//
+// If sliding is true, the period is computed after f runs. If it is false then
+// period includes the runtime for f.
+//
+// Close stopCh to stop. f may not be invoked if stop channel is already
+// closed. Pass NeverStop to if you don't want it stop.
+func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) {
+ BackoffUntil(f, NewJitteredBackoffManager(period, jitterFactor, &clock.RealClock{}), sliding, stopCh)
+}
+
+// BackoffUntil loops until stop channel is closed, run f every duration given by BackoffManager.
+//
+// If sliding is true, the period is computed after f runs. If it is false then
+// period includes the runtime for f.
+func BackoffUntil(f func(), backoff BackoffManager, sliding bool, stopCh <-chan struct{}) {
+ var t clock.Timer
+ for {
+ select {
+ case <-stopCh:
+ return
+ default:
+ }
+
+ if !sliding {
+ t = backoff.Backoff()
+ }
+
+ func() {
+ defer runtime.HandleCrash()
+ f()
+ }()
+
+ if sliding {
+ t = backoff.Backoff()
+ }
+
+ // NOTE: b/c there is no priority selection in golang
+ // it is possible for this to race, meaning we could
+ // trigger t.C and stopCh, and t.C select falls through.
+ // In order to mitigate we re-check stopCh at the beginning
+ // of every loop to prevent extra executions of f().
+ select {
+ case <-stopCh:
+ if !t.Stop() {
+ <-t.C()
+ }
+ return
+ case <-t.C():
+ }
+ }
+}
+
+// JitterUntilWithContext loops until context is done, running f every period.
+//
+// If jitterFactor is positive, the period is jittered before every run of f.
+// If jitterFactor is not positive, the period is unchanged and not jittered.
+//
+// If sliding is true, the period is computed after f runs. If it is false then
+// period includes the runtime for f.
+//
+// Cancel context to stop. f may not be invoked if context is already expired.
+func JitterUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration, jitterFactor float64, sliding bool) {
+ JitterUntil(func() { f(ctx) }, period, jitterFactor, sliding, ctx.Done())
+}
+
+// backoffManager provides simple backoff behavior in a threadsafe manner to a caller.
+type backoffManager struct {
+ backoff Backoff
+ initialBackoff Backoff
+ resetInterval time.Duration
+
+ clock clock.Clock
+
+ lock sync.Mutex
+ lastStart time.Time
+ timer clock.Timer
+}
+
+// Step returns the expected next duration to wait.
+func (b *backoffManager) Step() time.Duration {
+ b.lock.Lock()
+ defer b.lock.Unlock()
+
+ switch {
+ case b.resetInterval == 0:
+ b.backoff = b.initialBackoff
+ case b.clock.Now().Sub(b.lastStart) > b.resetInterval:
+ b.backoff = b.initialBackoff
+ b.lastStart = b.clock.Now()
+ }
+ return b.backoff.Step()
+}
+
+// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer
+// for exponential backoff. The returned timer must be drained before calling Backoff() the second
+// time.
+func (b *backoffManager) Backoff() clock.Timer {
+ b.lock.Lock()
+ defer b.lock.Unlock()
+ if b.timer == nil {
+ b.timer = b.clock.NewTimer(b.Step())
+ } else {
+ b.timer.Reset(b.Step())
+ }
+ return b.timer
+}
+
+// Timer returns a new Timer instance that shares the clock and the reset behavior with all other
+// timers.
+func (b *backoffManager) Timer() Timer {
+ return DelayFunc(b.Step).Timer(b.clock)
+}
+
+// BackoffManager manages backoff with a particular scheme based on its underlying implementation.
+type BackoffManager interface {
+ // Backoff returns a shared clock.Timer that is Reset on every invocation. This method is not
+ // safe for use from multiple threads. It returns a timer for backoff, and caller shall backoff
+ // until Timer.C() drains. If the second Backoff() is called before the timer from the first
+ // Backoff() call finishes, the first timer will NOT be drained and result in undetermined
+ // behavior.
+ Backoff() clock.Timer
+}
+
+// Deprecated: Will be removed when the legacy polling functions are removed.
+type exponentialBackoffManagerImpl struct {
+ backoff *Backoff
+ backoffTimer clock.Timer
+ lastBackoffStart time.Time
+ initialBackoff time.Duration
+ backoffResetDuration time.Duration
+ clock clock.Clock
+}
+
+// NewExponentialBackoffManager returns a manager for managing exponential backoff. Each backoff is jittered and
+// backoff will not exceed the given max. If the backoff is not called within resetDuration, the backoff is reset.
+// This backoff manager is used to reduce load during upstream unhealthiness.
+//
+// Deprecated: Will be removed when the legacy Poll methods are removed. Callers should construct a
+// Backoff struct, use DelayWithReset() to get a DelayFunc that periodically resets itself, and then
+// invoke Timer() when calling wait.BackoffUntil.
+//
+// Instead of:
+//
+// bm := wait.NewExponentialBackoffManager(init, max, reset, factor, jitter, clock)
+// ...
+// wait.BackoffUntil(..., bm.Backoff, ...)
+//
+// Use:
+//
+// delayFn := wait.Backoff{
+// Duration: init,
+// Cap: max,
+// Steps: int(math.Ceil(float64(max) / float64(init))), // now a required argument
+// Factor: factor,
+// Jitter: jitter,
+// }.DelayWithReset(reset, clock)
+// wait.BackoffUntil(..., delayFn.Timer(), ...)
+func NewExponentialBackoffManager(initBackoff, maxBackoff, resetDuration time.Duration, backoffFactor, jitter float64, c clock.Clock) BackoffManager {
+ return &exponentialBackoffManagerImpl{
+ backoff: &Backoff{
+ Duration: initBackoff,
+ Factor: backoffFactor,
+ Jitter: jitter,
+
+ // the current impl of wait.Backoff returns Backoff.Duration once steps are used up, which is not
+ // what we ideally need here, we set it to max int and assume we will never use up the steps
+ Steps: math.MaxInt32,
+ Cap: maxBackoff,
+ },
+ backoffTimer: nil,
+ initialBackoff: initBackoff,
+ lastBackoffStart: c.Now(),
+ backoffResetDuration: resetDuration,
+ clock: c,
+ }
+}
+
+func (b *exponentialBackoffManagerImpl) getNextBackoff() time.Duration {
+ if b.clock.Now().Sub(b.lastBackoffStart) > b.backoffResetDuration {
+ b.backoff.Steps = math.MaxInt32
+ b.backoff.Duration = b.initialBackoff
+ }
+ b.lastBackoffStart = b.clock.Now()
+ return b.backoff.Step()
+}
+
+// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for exponential backoff.
+// The returned timer must be drained before calling Backoff() the second time
+func (b *exponentialBackoffManagerImpl) Backoff() clock.Timer {
+ if b.backoffTimer == nil {
+ b.backoffTimer = b.clock.NewTimer(b.getNextBackoff())
+ } else {
+ b.backoffTimer.Reset(b.getNextBackoff())
+ }
+ return b.backoffTimer
+}
+
+// Deprecated: Will be removed when the legacy polling functions are removed.
+type jitteredBackoffManagerImpl struct {
+ clock clock.Clock
+ duration time.Duration
+ jitter float64
+ backoffTimer clock.Timer
+}
+
+// NewJitteredBackoffManager returns a BackoffManager that backoffs with given duration plus given jitter. If the jitter
+// is negative, backoff will not be jittered.
+//
+// Deprecated: Will be removed when the legacy Poll methods are removed. Callers should construct a
+// Backoff struct and invoke Timer() when calling wait.BackoffUntil.
+//
+// Instead of:
+//
+// bm := wait.NewJitteredBackoffManager(duration, jitter, clock)
+// ...
+// wait.BackoffUntil(..., bm.Backoff, ...)
+//
+// Use:
+//
+// wait.BackoffUntil(..., wait.Backoff{Duration: duration, Jitter: jitter}.Timer(), ...)
+func NewJitteredBackoffManager(duration time.Duration, jitter float64, c clock.Clock) BackoffManager {
+ return &jitteredBackoffManagerImpl{
+ clock: c,
+ duration: duration,
+ jitter: jitter,
+ backoffTimer: nil,
+ }
+}
+
+func (j *jitteredBackoffManagerImpl) getNextBackoff() time.Duration {
+ jitteredPeriod := j.duration
+ if j.jitter > 0.0 {
+ jitteredPeriod = Jitter(j.duration, j.jitter)
+ }
+ return jitteredPeriod
+}
+
+// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for jittered backoff.
+// The returned timer must be drained before calling Backoff() the second time
+func (j *jitteredBackoffManagerImpl) Backoff() clock.Timer {
+ backoff := j.getNextBackoff()
+ if j.backoffTimer == nil {
+ j.backoffTimer = j.clock.NewTimer(backoff)
+ } else {
+ j.backoffTimer.Reset(backoff)
+ }
+ return j.backoffTimer
+}
+
+// ExponentialBackoff repeats a condition check with exponential backoff.
+//
+// It repeatedly checks the condition and then sleeps, using `backoff.Step()`
+// to determine the length of the sleep and adjust Duration and Steps.
+// Stops and returns as soon as:
+// 1. the condition check returns true or an error,
+// 2. `backoff.Steps` checks of the condition have been done, or
+// 3. a sleep truncated by the cap on duration has been completed.
+// In case (1) the returned error is what the condition function returned.
+// In all other cases, ErrWaitTimeout is returned.
+//
+// Since backoffs are often subject to cancellation, we recommend using
+// ExponentialBackoffWithContext and passing a context to the method.
+func ExponentialBackoff(backoff Backoff, condition ConditionFunc) error {
+ for backoff.Steps > 0 {
+ if ok, err := runConditionWithCrashProtection(condition); err != nil || ok {
+ return err
+ }
+ if backoff.Steps == 1 {
+ break
+ }
+ time.Sleep(backoff.Step())
+ }
+ return ErrWaitTimeout
+}
+
+// ExponentialBackoffWithContext repeats a condition check with exponential backoff.
+// It immediately returns an error if the condition returns an error, the context is cancelled
+// or hits the deadline, or if the maximum attempts defined in backoff is exceeded (ErrWaitTimeout).
+// If an error is returned by the condition the backoff stops immediately. The condition will
+// never be invoked more than backoff.Steps times.
+func ExponentialBackoffWithContext(ctx context.Context, backoff Backoff, condition ConditionWithContextFunc) error {
+ for backoff.Steps > 0 {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ default:
+ }
+
+ if ok, err := runConditionWithCrashProtectionWithContext(ctx, condition); err != nil || ok {
+ return err
+ }
+
+ if backoff.Steps == 1 {
+ break
+ }
+
+ waitBeforeRetry := backoff.Step()
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-time.After(waitBeforeRetry):
+ }
+ }
+
+ return ErrWaitTimeout
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/delay.go b/vendor/k8s.io/apimachinery/pkg/util/wait/delay.go
new file mode 100644
index 000000000..1d3dcaa74
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/wait/delay.go
@@ -0,0 +1,51 @@
+/*
+Copyright 2023 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 wait
+
+import (
+ "context"
+ "sync"
+ "time"
+
+ "k8s.io/utils/clock"
+)
+
+// DelayFunc returns the next time interval to wait.
+type DelayFunc func() time.Duration
+
+// Timer takes an arbitrary delay function and returns a timer that can handle arbitrary interval changes.
+// Use Backoff{...}.Timer() for simple delays and more efficient timers.
+func (fn DelayFunc) Timer(c clock.Clock) Timer {
+ return &variableTimer{fn: fn, new: c.NewTimer}
+}
+
+// Until takes an arbitrary delay function and runs until cancelled or the condition indicates exit. This
+// offers all of the functionality of the methods in this package.
+func (fn DelayFunc) Until(ctx context.Context, immediate, sliding bool, condition ConditionWithContextFunc) error {
+ return loopConditionUntilContext(ctx, &variableTimer{fn: fn, new: internalClock.NewTimer}, immediate, sliding, condition)
+}
+
+// Concurrent returns a version of this DelayFunc that is safe for use by multiple goroutines that
+// wish to share a single delay timer.
+func (fn DelayFunc) Concurrent() DelayFunc {
+ var lock sync.Mutex
+ return func() time.Duration {
+ lock.Lock()
+ defer lock.Unlock()
+ return fn()
+ }
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/error.go b/vendor/k8s.io/apimachinery/pkg/util/wait/error.go
new file mode 100644
index 000000000..dd75801d8
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/wait/error.go
@@ -0,0 +1,96 @@
+/*
+Copyright 2023 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 wait
+
+import (
+ "context"
+ "errors"
+)
+
+// ErrWaitTimeout is returned when the condition was not satisfied in time.
+//
+// Deprecated: This type will be made private in favor of Interrupted()
+// for checking errors or ErrorInterrupted(err) for returning a wrapped error.
+var ErrWaitTimeout = ErrorInterrupted(errors.New("timed out waiting for the condition"))
+
+// Interrupted returns true if the error indicates a Poll, ExponentialBackoff, or
+// Until loop exited for any reason besides the condition returning true or an
+// error. A loop is considered interrupted if the calling context is cancelled,
+// the context reaches its deadline, or a backoff reaches its maximum allowed
+// steps.
+//
+// Callers should use this method instead of comparing the error value directly to
+// ErrWaitTimeout, as methods that cancel a context may not return that error.
+//
+// Instead of:
+//
+// err := wait.Poll(...)
+// if err == wait.ErrWaitTimeout {
+// log.Infof("Wait for operation exceeded")
+// } else ...
+//
+// Use:
+//
+// err := wait.Poll(...)
+// if wait.Interrupted(err) {
+// log.Infof("Wait for operation exceeded")
+// } else ...
+func Interrupted(err error) bool {
+ switch {
+ case errors.Is(err, errWaitTimeout),
+ errors.Is(err, context.Canceled),
+ errors.Is(err, context.DeadlineExceeded):
+ return true
+ default:
+ return false
+ }
+}
+
+// errInterrupted
+type errInterrupted struct {
+ cause error
+}
+
+// ErrorInterrupted returns an error that indicates the wait was ended
+// early for a given reason. If no cause is provided a generic error
+// will be used but callers are encouraged to provide a real cause for
+// clarity in debugging.
+func ErrorInterrupted(cause error) error {
+ switch cause.(type) {
+ case errInterrupted:
+ // no need to wrap twice since errInterrupted is only needed
+ // once in a chain
+ return cause
+ default:
+ return errInterrupted{cause}
+ }
+}
+
+// errWaitTimeout is the private version of the previous ErrWaitTimeout
+// and is private to prevent direct comparison. Use ErrorInterrupted(err)
+// to get an error that will return true for Interrupted(err).
+var errWaitTimeout = errInterrupted{}
+
+func (e errInterrupted) Unwrap() error { return e.cause }
+func (e errInterrupted) Is(target error) bool { return target == errWaitTimeout }
+func (e errInterrupted) Error() string {
+ if e.cause == nil {
+ // returns the same error message as historical behavior
+ return "timed out waiting for the condition"
+ }
+ return e.cause.Error()
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/loop.go b/vendor/k8s.io/apimachinery/pkg/util/wait/loop.go
new file mode 100644
index 000000000..107bfc132
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/wait/loop.go
@@ -0,0 +1,95 @@
+/*
+Copyright 2023 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 wait
+
+import (
+ "context"
+ "time"
+
+ "k8s.io/apimachinery/pkg/util/runtime"
+)
+
+// loopConditionUntilContext executes the provided condition at intervals defined by
+// the provided timer until the provided context is cancelled, the condition returns
+// true, or the condition returns an error. If sliding is true, the period is computed
+// after condition runs. If it is false then period includes the runtime for condition.
+// If immediate is false the first delay happens before any call to condition, if
+// immediate is true the condition will be invoked before waiting and guarantees that
+// the condition is invoked at least once, regardless of whether the context has been
+// cancelled. The returned error is the error returned by the last condition or the
+// context error if the context was terminated.
+//
+// This is the common loop construct for all polling in the wait package.
+func loopConditionUntilContext(ctx context.Context, t Timer, immediate, sliding bool, condition ConditionWithContextFunc) error {
+ defer t.Stop()
+
+ var timeCh <-chan time.Time
+ doneCh := ctx.Done()
+
+ if !sliding {
+ timeCh = t.C()
+ }
+
+ // if immediate is true the condition is
+ // guaranteed to be executed at least once,
+ // if we haven't requested immediate execution, delay once
+ if immediate {
+ if ok, err := func() (bool, error) {
+ defer runtime.HandleCrash()
+ return condition(ctx)
+ }(); err != nil || ok {
+ return err
+ }
+ }
+
+ if sliding {
+ timeCh = t.C()
+ }
+
+ for {
+
+ // Wait for either the context to be cancelled or the next invocation be called
+ select {
+ case <-doneCh:
+ return ctx.Err()
+ case <-timeCh:
+ }
+
+ // IMPORTANT: Because there is no channel priority selection in golang
+ // it is possible for very short timers to "win" the race in the previous select
+ // repeatedly even when the context has been canceled. We therefore must
+ // explicitly check for context cancellation on every loop and exit if true to
+ // guarantee that we don't invoke condition more than once after context has
+ // been cancelled.
+ if err := ctx.Err(); err != nil {
+ return err
+ }
+
+ if !sliding {
+ t.Next()
+ }
+ if ok, err := func() (bool, error) {
+ defer runtime.HandleCrash()
+ return condition(ctx)
+ }(); err != nil || ok {
+ return err
+ }
+ if sliding {
+ t.Next()
+ }
+ }
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/poll.go b/vendor/k8s.io/apimachinery/pkg/util/wait/poll.go
new file mode 100644
index 000000000..231d4c384
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/wait/poll.go
@@ -0,0 +1,315 @@
+/*
+Copyright 2023 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 wait
+
+import (
+ "context"
+ "time"
+)
+
+// PollUntilContextCancel tries a condition func until it returns true, an error, or the context
+// is cancelled or hits a deadline. condition will be invoked after the first interval if the
+// context is not cancelled first. The returned error will be from ctx.Err(), the condition's
+// err return value, or nil. If invoking condition takes longer than interval the next condition
+// will be invoked immediately. When using very short intervals, condition may be invoked multiple
+// times before a context cancellation is detected. If immediate is true, condition will be
+// invoked before waiting and guarantees that condition is invoked at least once, regardless of
+// whether the context has been cancelled.
+func PollUntilContextCancel(ctx context.Context, interval time.Duration, immediate bool, condition ConditionWithContextFunc) error {
+ return loopConditionUntilContext(ctx, Backoff{Duration: interval}.Timer(), immediate, false, condition)
+}
+
+// PollUntilContextTimeout will terminate polling after timeout duration by setting a context
+// timeout. This is provided as a convenience function for callers not currently executing under
+// a deadline and is equivalent to:
+//
+// deadlineCtx, deadlineCancel := context.WithTimeout(ctx, timeout)
+// err := PollUntilContextCancel(deadlineCtx, interval, immediate, condition)
+//
+// The deadline context will be cancelled if the Poll succeeds before the timeout, simplifying
+// inline usage. All other behavior is identical to PollUntilContextCancel.
+func PollUntilContextTimeout(ctx context.Context, interval, timeout time.Duration, immediate bool, condition ConditionWithContextFunc) error {
+ deadlineCtx, deadlineCancel := context.WithTimeout(ctx, timeout)
+ defer deadlineCancel()
+ return loopConditionUntilContext(deadlineCtx, Backoff{Duration: interval}.Timer(), immediate, false, condition)
+}
+
+// Poll tries a condition func until it returns true, an error, or the timeout
+// is reached.
+//
+// Poll always waits the interval before the run of 'condition'.
+// 'condition' will always be invoked at least once.
+//
+// Some intervals may be missed if the condition takes too long or the time
+// window is too short.
+//
+// If you want to Poll something forever, see PollInfinite.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextTimeout.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func Poll(interval, timeout time.Duration, condition ConditionFunc) error {
+ return PollWithContext(context.Background(), interval, timeout, condition.WithContext())
+}
+
+// PollWithContext tries a condition func until it returns true, an error,
+// or when the context expires or the timeout is reached, whichever
+// happens first.
+//
+// PollWithContext always waits the interval before the run of 'condition'.
+// 'condition' will always be invoked at least once.
+//
+// Some intervals may be missed if the condition takes too long or the time
+// window is too short.
+//
+// If you want to Poll something forever, see PollInfinite.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextTimeout.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func PollWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error {
+ return poll(ctx, false, poller(interval, timeout), condition)
+}
+
+// PollUntil tries a condition func until it returns true, an error or stopCh is
+// closed.
+//
+// PollUntil always waits interval before the first run of 'condition'.
+// 'condition' will always be invoked at least once.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error {
+ return PollUntilWithContext(ContextForChannel(stopCh), interval, condition.WithContext())
+}
+
+// PollUntilWithContext tries a condition func until it returns true,
+// an error or the specified context is cancelled or expired.
+//
+// PollUntilWithContext always waits interval before the first run of 'condition'.
+// 'condition' will always be invoked at least once.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func PollUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {
+ return poll(ctx, false, poller(interval, 0), condition)
+}
+
+// PollInfinite tries a condition func until it returns true or an error
+//
+// PollInfinite always waits the interval before the run of 'condition'.
+//
+// Some intervals may be missed if the condition takes too long or the time
+// window is too short.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func PollInfinite(interval time.Duration, condition ConditionFunc) error {
+ return PollInfiniteWithContext(context.Background(), interval, condition.WithContext())
+}
+
+// PollInfiniteWithContext tries a condition func until it returns true or an error
+//
+// PollInfiniteWithContext always waits the interval before the run of 'condition'.
+//
+// Some intervals may be missed if the condition takes too long or the time
+// window is too short.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func PollInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {
+ return poll(ctx, false, poller(interval, 0), condition)
+}
+
+// PollImmediate tries a condition func until it returns true, an error, or the timeout
+// is reached.
+//
+// PollImmediate always checks 'condition' before waiting for the interval. 'condition'
+// will always be invoked at least once.
+//
+// Some intervals may be missed if the condition takes too long or the time
+// window is too short.
+//
+// If you want to immediately Poll something forever, see PollImmediateInfinite.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextTimeout.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func PollImmediate(interval, timeout time.Duration, condition ConditionFunc) error {
+ return PollImmediateWithContext(context.Background(), interval, timeout, condition.WithContext())
+}
+
+// PollImmediateWithContext tries a condition func until it returns true, an error,
+// or the timeout is reached or the specified context expires, whichever happens first.
+//
+// PollImmediateWithContext always checks 'condition' before waiting for the interval.
+// 'condition' will always be invoked at least once.
+//
+// Some intervals may be missed if the condition takes too long or the time
+// window is too short.
+//
+// If you want to immediately Poll something forever, see PollImmediateInfinite.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextTimeout.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func PollImmediateWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error {
+ return poll(ctx, true, poller(interval, timeout), condition)
+}
+
+// PollImmediateUntil tries a condition func until it returns true, an error or stopCh is closed.
+//
+// PollImmediateUntil runs the 'condition' before waiting for the interval.
+// 'condition' will always be invoked at least once.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func PollImmediateUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error {
+ return PollImmediateUntilWithContext(ContextForChannel(stopCh), interval, condition.WithContext())
+}
+
+// PollImmediateUntilWithContext tries a condition func until it returns true,
+// an error or the specified context is cancelled or expired.
+//
+// PollImmediateUntilWithContext runs the 'condition' before waiting for the interval.
+// 'condition' will always be invoked at least once.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func PollImmediateUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {
+ return poll(ctx, true, poller(interval, 0), condition)
+}
+
+// PollImmediateInfinite tries a condition func until it returns true or an error
+//
+// PollImmediateInfinite runs the 'condition' before waiting for the interval.
+//
+// Some intervals may be missed if the condition takes too long or the time
+// window is too short.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func PollImmediateInfinite(interval time.Duration, condition ConditionFunc) error {
+ return PollImmediateInfiniteWithContext(context.Background(), interval, condition.WithContext())
+}
+
+// PollImmediateInfiniteWithContext tries a condition func until it returns true
+// or an error or the specified context gets cancelled or expired.
+//
+// PollImmediateInfiniteWithContext runs the 'condition' before waiting for the interval.
+//
+// Some intervals may be missed if the condition takes too long or the time
+// window is too short.
+//
+// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
+// Note that the new method will no longer return ErrWaitTimeout and instead return errors
+// defined by the context package. Will be removed in a future release.
+func PollImmediateInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {
+ return poll(ctx, true, poller(interval, 0), condition)
+}
+
+// Internally used, each of the public 'Poll*' function defined in this
+// package should invoke this internal function with appropriate parameters.
+// ctx: the context specified by the caller, for infinite polling pass
+// a context that never gets cancelled or expired.
+// immediate: if true, the 'condition' will be invoked before waiting for the interval,
+// in this case 'condition' will always be invoked at least once.
+// wait: user specified WaitFunc function that controls at what interval the condition
+// function should be invoked periodically and whether it is bound by a timeout.
+// condition: user specified ConditionWithContextFunc function.
+//
+// Deprecated: will be removed in favor of loopConditionUntilContext.
+func poll(ctx context.Context, immediate bool, wait waitWithContextFunc, condition ConditionWithContextFunc) error {
+ if immediate {
+ done, err := runConditionWithCrashProtectionWithContext(ctx, condition)
+ if err != nil {
+ return err
+ }
+ if done {
+ return nil
+ }
+ }
+
+ select {
+ case <-ctx.Done():
+ // returning ctx.Err() will break backward compatibility, use new PollUntilContext*
+ // methods instead
+ return ErrWaitTimeout
+ default:
+ return waitForWithContext(ctx, wait, condition)
+ }
+}
+
+// poller returns a WaitFunc that will send to the channel every interval until
+// timeout has elapsed and then closes the channel.
+//
+// Over very short intervals you may receive no ticks before the channel is
+// closed. A timeout of 0 is interpreted as an infinity, and in such a case
+// it would be the caller's responsibility to close the done channel.
+// Failure to do so would result in a leaked goroutine.
+//
+// Output ticks are not buffered. If the channel is not ready to receive an
+// item, the tick is skipped.
+//
+// Deprecated: Will be removed in a future release.
+func poller(interval, timeout time.Duration) waitWithContextFunc {
+ return waitWithContextFunc(func(ctx context.Context) <-chan struct{} {
+ ch := make(chan struct{})
+
+ go func() {
+ defer close(ch)
+
+ tick := time.NewTicker(interval)
+ defer tick.Stop()
+
+ var after <-chan time.Time
+ if timeout != 0 {
+ // time.After is more convenient, but it
+ // potentially leaves timers around much longer
+ // than necessary if we exit early.
+ timer := time.NewTimer(timeout)
+ after = timer.C
+ defer timer.Stop()
+ }
+
+ for {
+ select {
+ case <-tick.C:
+ // If the consumer isn't ready for this signal drop it and
+ // check the other channels.
+ select {
+ case ch <- struct{}{}:
+ default:
+ }
+ case <-after:
+ return
+ case <-ctx.Done():
+ return
+ }
+ }
+ }()
+
+ return ch
+ })
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/timer.go b/vendor/k8s.io/apimachinery/pkg/util/wait/timer.go
new file mode 100644
index 000000000..3efba3213
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/util/wait/timer.go
@@ -0,0 +1,121 @@
+/*
+Copyright 2023 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 wait
+
+import (
+ "time"
+
+ "k8s.io/utils/clock"
+)
+
+// Timer abstracts how wait functions interact with time runtime efficiently. Test
+// code may implement this interface directly but package consumers are encouraged
+// to use the Backoff type as the primary mechanism for acquiring a Timer. The
+// interface is a simplification of clock.Timer to prevent misuse. Timers are not
+// expected to be safe for calls from multiple goroutines.
+type Timer interface {
+ // C returns a channel that will receive a struct{} each time the timer fires.
+ // The channel should not be waited on after Stop() is invoked. It is allowed
+ // to cache the returned value of C() for the lifetime of the Timer.
+ C() <-chan time.Time
+ // Next is invoked by wait functions to signal timers that the next interval
+ // should begin. You may only use Next() if you have drained the channel C().
+ // You should not call Next() after Stop() is invoked.
+ Next()
+ // Stop releases the timer. It is safe to invoke if no other methods have been
+ // called.
+ Stop()
+}
+
+type noopTimer struct {
+ closedCh <-chan time.Time
+}
+
+// newNoopTimer creates a timer with a unique channel to avoid contention
+// for the channel's lock across multiple unrelated timers.
+func newNoopTimer() noopTimer {
+ ch := make(chan time.Time)
+ close(ch)
+ return noopTimer{closedCh: ch}
+}
+
+func (t noopTimer) C() <-chan time.Time {
+ return t.closedCh
+}
+func (noopTimer) Next() {}
+func (noopTimer) Stop() {}
+
+type variableTimer struct {
+ fn DelayFunc
+ t clock.Timer
+ new func(time.Duration) clock.Timer
+}
+
+func (t *variableTimer) C() <-chan time.Time {
+ if t.t == nil {
+ d := t.fn()
+ t.t = t.new(d)
+ }
+ return t.t.C()
+}
+func (t *variableTimer) Next() {
+ if t.t == nil {
+ return
+ }
+ d := t.fn()
+ t.t.Reset(d)
+}
+func (t *variableTimer) Stop() {
+ if t.t == nil {
+ return
+ }
+ t.t.Stop()
+ t.t = nil
+}
+
+type fixedTimer struct {
+ interval time.Duration
+ t clock.Ticker
+ new func(time.Duration) clock.Ticker
+}
+
+func (t *fixedTimer) C() <-chan time.Time {
+ if t.t == nil {
+ t.t = t.new(t.interval)
+ }
+ return t.t.C()
+}
+func (t *fixedTimer) Next() {
+ // no-op for fixed timers
+}
+func (t *fixedTimer) Stop() {
+ if t.t == nil {
+ return
+ }
+ t.t.Stop()
+ t.t = nil
+}
+
+var (
+ // RealTimer can be passed to methods that need a clock.Timer.
+ RealTimer = clock.RealClock{}.NewTimer
+)
+
+var (
+ // internalClock is used for test injection of clocks
+ internalClock = clock.RealClock{}
+)
diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go b/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go
index 137627b40..6805e8cf9 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go
@@ -18,14 +18,11 @@ package wait
import (
"context"
- "errors"
- "math"
"math/rand"
"sync"
"time"
"k8s.io/apimachinery/pkg/util/runtime"
- "k8s.io/utils/clock"
)
// For any test of the style:
@@ -83,113 +80,6 @@ func Forever(f func(), period time.Duration) {
Until(f, period, NeverStop)
}
-// Until loops until stop channel is closed, running f every period.
-//
-// Until is syntactic sugar on top of JitterUntil with zero jitter factor and
-// with sliding = true (which means the timer for period starts after the f
-// completes).
-func Until(f func(), period time.Duration, stopCh <-chan struct{}) {
- JitterUntil(f, period, 0.0, true, stopCh)
-}
-
-// UntilWithContext loops until context is done, running f every period.
-//
-// UntilWithContext is syntactic sugar on top of JitterUntilWithContext
-// with zero jitter factor and with sliding = true (which means the timer
-// for period starts after the f completes).
-func UntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) {
- JitterUntilWithContext(ctx, f, period, 0.0, true)
-}
-
-// NonSlidingUntil loops until stop channel is closed, running f every
-// period.
-//
-// NonSlidingUntil is syntactic sugar on top of JitterUntil with zero jitter
-// factor, with sliding = false (meaning the timer for period starts at the same
-// time as the function starts).
-func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{}) {
- JitterUntil(f, period, 0.0, false, stopCh)
-}
-
-// NonSlidingUntilWithContext loops until context is done, running f every
-// period.
-//
-// NonSlidingUntilWithContext is syntactic sugar on top of JitterUntilWithContext
-// with zero jitter factor, with sliding = false (meaning the timer for period
-// starts at the same time as the function starts).
-func NonSlidingUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) {
- JitterUntilWithContext(ctx, f, period, 0.0, false)
-}
-
-// JitterUntil loops until stop channel is closed, running f every period.
-//
-// If jitterFactor is positive, the period is jittered before every run of f.
-// If jitterFactor is not positive, the period is unchanged and not jittered.
-//
-// If sliding is true, the period is computed after f runs. If it is false then
-// period includes the runtime for f.
-//
-// Close stopCh to stop. f may not be invoked if stop channel is already
-// closed. Pass NeverStop to if you don't want it stop.
-func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) {
- BackoffUntil(f, NewJitteredBackoffManager(period, jitterFactor, &clock.RealClock{}), sliding, stopCh)
-}
-
-// BackoffUntil loops until stop channel is closed, run f every duration given by BackoffManager.
-//
-// If sliding is true, the period is computed after f runs. If it is false then
-// period includes the runtime for f.
-func BackoffUntil(f func(), backoff BackoffManager, sliding bool, stopCh <-chan struct{}) {
- var t clock.Timer
- for {
- select {
- case <-stopCh:
- return
- default:
- }
-
- if !sliding {
- t = backoff.Backoff()
- }
-
- func() {
- defer runtime.HandleCrash()
- f()
- }()
-
- if sliding {
- t = backoff.Backoff()
- }
-
- // NOTE: b/c there is no priority selection in golang
- // it is possible for this to race, meaning we could
- // trigger t.C and stopCh, and t.C select falls through.
- // In order to mitigate we re-check stopCh at the beginning
- // of every loop to prevent extra executions of f().
- select {
- case <-stopCh:
- if !t.Stop() {
- <-t.C()
- }
- return
- case <-t.C():
- }
- }
-}
-
-// JitterUntilWithContext loops until context is done, running f every period.
-//
-// If jitterFactor is positive, the period is jittered before every run of f.
-// If jitterFactor is not positive, the period is unchanged and not jittered.
-//
-// If sliding is true, the period is computed after f runs. If it is false then
-// period includes the runtime for f.
-//
-// Cancel context to stop. f may not be invoked if context is already expired.
-func JitterUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration, jitterFactor float64, sliding bool) {
- JitterUntil(func() { f(ctx) }, period, jitterFactor, sliding, ctx.Done())
-}
-
// Jitter returns a time.Duration between duration and duration + maxFactor *
// duration.
//
@@ -203,9 +93,6 @@ func Jitter(duration time.Duration, maxFactor float64) time.Duration {
return wait
}
-// ErrWaitTimeout is returned when the condition exited without success.
-var ErrWaitTimeout = errors.New("timed out waiting for the condition")
-
// ConditionFunc returns true if the condition is satisfied, or an error
// if the loop should be aborted.
type ConditionFunc func() (done bool, err error)
@@ -223,425 +110,80 @@ func (cf ConditionFunc) WithContext() ConditionWithContextFunc {
}
}
-// runConditionWithCrashProtection runs a ConditionFunc with crash protection
-func runConditionWithCrashProtection(condition ConditionFunc) (bool, error) {
- return runConditionWithCrashProtectionWithContext(context.TODO(), condition.WithContext())
-}
-
-// runConditionWithCrashProtectionWithContext runs a
-// ConditionWithContextFunc with crash protection.
-func runConditionWithCrashProtectionWithContext(ctx context.Context, condition ConditionWithContextFunc) (bool, error) {
- defer runtime.HandleCrash()
- return condition(ctx)
-}
-
-// Backoff holds parameters applied to a Backoff function.
-type Backoff struct {
- // The initial duration.
- Duration time.Duration
- // Duration is multiplied by factor each iteration, if factor is not zero
- // and the limits imposed by Steps and Cap have not been reached.
- // Should not be negative.
- // The jitter does not contribute to the updates to the duration parameter.
- Factor float64
- // The sleep at each iteration is the duration plus an additional
- // amount chosen uniformly at random from the interval between
- // zero and `jitter*duration`.
- Jitter float64
- // The remaining number of iterations in which the duration
- // parameter may change (but progress can be stopped earlier by
- // hitting the cap). If not positive, the duration is not
- // changed. Used for exponential backoff in combination with
- // Factor and Cap.
- Steps int
- // A limit on revised values of the duration parameter. If a
- // multiplication by the factor parameter would make the duration
- // exceed the cap then the duration is set to the cap and the
- // steps parameter is set to zero.
- Cap time.Duration
-}
-
-// Step (1) returns an amount of time to sleep determined by the
-// original Duration and Jitter and (2) mutates the provided Backoff
-// to update its Steps and Duration.
-func (b *Backoff) Step() time.Duration {
- if b.Steps < 1 {
- if b.Jitter > 0 {
- return Jitter(b.Duration, b.Jitter)
- }
- return b.Duration
- }
- b.Steps--
-
- duration := b.Duration
-
- // calculate the next step
- if b.Factor != 0 {
- b.Duration = time.Duration(float64(b.Duration) * b.Factor)
- if b.Cap > 0 && b.Duration > b.Cap {
- b.Duration = b.Cap
- b.Steps = 0
- }
- }
-
- if b.Jitter > 0 {
- duration = Jitter(duration, b.Jitter)
- }
- return duration
-}
-
-// ContextForChannel derives a child context from a parent channel.
-//
-// The derived context's Done channel is closed when the returned cancel function
-// is called or when the parent channel is closed, whichever happens first.
-//
-// Note the caller must *always* call the CancelFunc, otherwise resources may be leaked.
-func ContextForChannel(parentCh <-chan struct{}) (context.Context, context.CancelFunc) {
- ctx, cancel := context.WithCancel(context.Background())
-
- go func() {
- select {
- case <-parentCh:
- cancel()
- case <-ctx.Done():
- }
- }()
- return ctx, cancel
-}
-
-// BackoffManager manages backoff with a particular scheme based on its underlying implementation. It provides
-// an interface to return a timer for backoff, and caller shall backoff until Timer.C() drains. If the second Backoff()
-// is called before the timer from the first Backoff() call finishes, the first timer will NOT be drained and result in
-// undetermined behavior.
-// The BackoffManager is supposed to be called in a single-threaded environment.
-type BackoffManager interface {
- Backoff() clock.Timer
-}
-
-type exponentialBackoffManagerImpl struct {
- backoff *Backoff
- backoffTimer clock.Timer
- lastBackoffStart time.Time
- initialBackoff time.Duration
- backoffResetDuration time.Duration
- clock clock.Clock
-}
-
-// NewExponentialBackoffManager returns a manager for managing exponential backoff. Each backoff is jittered and
-// backoff will not exceed the given max. If the backoff is not called within resetDuration, the backoff is reset.
-// This backoff manager is used to reduce load during upstream unhealthiness.
-func NewExponentialBackoffManager(initBackoff, maxBackoff, resetDuration time.Duration, backoffFactor, jitter float64, c clock.Clock) BackoffManager {
- return &exponentialBackoffManagerImpl{
- backoff: &Backoff{
- Duration: initBackoff,
- Factor: backoffFactor,
- Jitter: jitter,
-
- // the current impl of wait.Backoff returns Backoff.Duration once steps are used up, which is not
- // what we ideally need here, we set it to max int and assume we will never use up the steps
- Steps: math.MaxInt32,
- Cap: maxBackoff,
- },
- backoffTimer: nil,
- initialBackoff: initBackoff,
- lastBackoffStart: c.Now(),
- backoffResetDuration: resetDuration,
- clock: c,
- }
-}
-
-func (b *exponentialBackoffManagerImpl) getNextBackoff() time.Duration {
- if b.clock.Now().Sub(b.lastBackoffStart) > b.backoffResetDuration {
- b.backoff.Steps = math.MaxInt32
- b.backoff.Duration = b.initialBackoff
- }
- b.lastBackoffStart = b.clock.Now()
- return b.backoff.Step()
-}
-
-// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for exponential backoff.
-// The returned timer must be drained before calling Backoff() the second time
-func (b *exponentialBackoffManagerImpl) Backoff() clock.Timer {
- if b.backoffTimer == nil {
- b.backoffTimer = b.clock.NewTimer(b.getNextBackoff())
- } else {
- b.backoffTimer.Reset(b.getNextBackoff())
- }
- return b.backoffTimer
-}
-
-type jitteredBackoffManagerImpl struct {
- clock clock.Clock
- duration time.Duration
- jitter float64
- backoffTimer clock.Timer
-}
-
-// NewJitteredBackoffManager returns a BackoffManager that backoffs with given duration plus given jitter. If the jitter
-// is negative, backoff will not be jittered.
-func NewJitteredBackoffManager(duration time.Duration, jitter float64, c clock.Clock) BackoffManager {
- return &jitteredBackoffManagerImpl{
- clock: c,
- duration: duration,
- jitter: jitter,
- backoffTimer: nil,
- }
-}
-
-func (j *jitteredBackoffManagerImpl) getNextBackoff() time.Duration {
- jitteredPeriod := j.duration
- if j.jitter > 0.0 {
- jitteredPeriod = Jitter(j.duration, j.jitter)
- }
- return jitteredPeriod
+// ContextForChannel provides a context that will be treated as cancelled
+// when the provided parentCh is closed. The implementation returns
+// context.Canceled for Err() if and only if the parentCh is closed.
+func ContextForChannel(parentCh <-chan struct{}) context.Context {
+ return channelContext{stopCh: parentCh}
}
-// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for jittered backoff.
-// The returned timer must be drained before calling Backoff() the second time
-func (j *jitteredBackoffManagerImpl) Backoff() clock.Timer {
- backoff := j.getNextBackoff()
- if j.backoffTimer == nil {
- j.backoffTimer = j.clock.NewTimer(backoff)
- } else {
- j.backoffTimer.Reset(backoff)
- }
- return j.backoffTimer
-}
+var _ context.Context = channelContext{}
-// ExponentialBackoff repeats a condition check with exponential backoff.
-//
-// It repeatedly checks the condition and then sleeps, using `backoff.Step()`
-// to determine the length of the sleep and adjust Duration and Steps.
-// Stops and returns as soon as:
-// 1. the condition check returns true or an error,
-// 2. `backoff.Steps` checks of the condition have been done, or
-// 3. a sleep truncated by the cap on duration has been completed.
-// In case (1) the returned error is what the condition function returned.
-// In all other cases, ErrWaitTimeout is returned.
-func ExponentialBackoff(backoff Backoff, condition ConditionFunc) error {
- for backoff.Steps > 0 {
- if ok, err := runConditionWithCrashProtection(condition); err != nil || ok {
- return err
- }
- if backoff.Steps == 1 {
- break
- }
- time.Sleep(backoff.Step())
- }
- return ErrWaitTimeout
-}
-
-// Poll tries a condition func until it returns true, an error, or the timeout
-// is reached.
-//
-// Poll always waits the interval before the run of 'condition'.
-// 'condition' will always be invoked at least once.
-//
-// Some intervals may be missed if the condition takes too long or the time
-// window is too short.
-//
-// If you want to Poll something forever, see PollInfinite.
-func Poll(interval, timeout time.Duration, condition ConditionFunc) error {
- return PollWithContext(context.Background(), interval, timeout, condition.WithContext())
-}
-
-// PollWithContext tries a condition func until it returns true, an error,
-// or when the context expires or the timeout is reached, whichever
-// happens first.
-//
-// PollWithContext always waits the interval before the run of 'condition'.
-// 'condition' will always be invoked at least once.
-//
-// Some intervals may be missed if the condition takes too long or the time
-// window is too short.
-//
-// If you want to Poll something forever, see PollInfinite.
-func PollWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error {
- return poll(ctx, false, poller(interval, timeout), condition)
-}
-
-// PollUntil tries a condition func until it returns true, an error or stopCh is
+// channelContext will behave as if the context were cancelled when stopCh is
// closed.
-//
-// PollUntil always waits interval before the first run of 'condition'.
-// 'condition' will always be invoked at least once.
-func PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error {
- ctx, cancel := ContextForChannel(stopCh)
- defer cancel()
- return PollUntilWithContext(ctx, interval, condition.WithContext())
-}
-
-// PollUntilWithContext tries a condition func until it returns true,
-// an error or the specified context is cancelled or expired.
-//
-// PollUntilWithContext always waits interval before the first run of 'condition'.
-// 'condition' will always be invoked at least once.
-func PollUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {
- return poll(ctx, false, poller(interval, 0), condition)
-}
-
-// PollInfinite tries a condition func until it returns true or an error
-//
-// PollInfinite always waits the interval before the run of 'condition'.
-//
-// Some intervals may be missed if the condition takes too long or the time
-// window is too short.
-func PollInfinite(interval time.Duration, condition ConditionFunc) error {
- return PollInfiniteWithContext(context.Background(), interval, condition.WithContext())
-}
-
-// PollInfiniteWithContext tries a condition func until it returns true or an error
-//
-// PollInfiniteWithContext always waits the interval before the run of 'condition'.
-//
-// Some intervals may be missed if the condition takes too long or the time
-// window is too short.
-func PollInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {
- return poll(ctx, false, poller(interval, 0), condition)
+type channelContext struct {
+ stopCh <-chan struct{}
}
-// PollImmediate tries a condition func until it returns true, an error, or the timeout
-// is reached.
-//
-// PollImmediate always checks 'condition' before waiting for the interval. 'condition'
-// will always be invoked at least once.
-//
-// Some intervals may be missed if the condition takes too long or the time
-// window is too short.
-//
-// If you want to immediately Poll something forever, see PollImmediateInfinite.
-func PollImmediate(interval, timeout time.Duration, condition ConditionFunc) error {
- return PollImmediateWithContext(context.Background(), interval, timeout, condition.WithContext())
-}
-
-// PollImmediateWithContext tries a condition func until it returns true, an error,
-// or the timeout is reached or the specified context expires, whichever happens first.
-//
-// PollImmediateWithContext always checks 'condition' before waiting for the interval.
-// 'condition' will always be invoked at least once.
-//
-// Some intervals may be missed if the condition takes too long or the time
-// window is too short.
-//
-// If you want to immediately Poll something forever, see PollImmediateInfinite.
-func PollImmediateWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error {
- return poll(ctx, true, poller(interval, timeout), condition)
-}
-
-// PollImmediateUntil tries a condition func until it returns true, an error or stopCh is closed.
-//
-// PollImmediateUntil runs the 'condition' before waiting for the interval.
-// 'condition' will always be invoked at least once.
-func PollImmediateUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error {
- ctx, cancel := ContextForChannel(stopCh)
- defer cancel()
- return PollImmediateUntilWithContext(ctx, interval, condition.WithContext())
-}
-
-// PollImmediateUntilWithContext tries a condition func until it returns true,
-// an error or the specified context is cancelled or expired.
-//
-// PollImmediateUntilWithContext runs the 'condition' before waiting for the interval.
-// 'condition' will always be invoked at least once.
-func PollImmediateUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {
- return poll(ctx, true, poller(interval, 0), condition)
+func (c channelContext) Done() <-chan struct{} { return c.stopCh }
+func (c channelContext) Err() error {
+ select {
+ case <-c.stopCh:
+ return context.Canceled
+ default:
+ return nil
+ }
}
+func (c channelContext) Deadline() (time.Time, bool) { return time.Time{}, false }
+func (c channelContext) Value(key any) any { return nil }
-// PollImmediateInfinite tries a condition func until it returns true or an error
+// runConditionWithCrashProtection runs a ConditionFunc with crash protection.
//
-// PollImmediateInfinite runs the 'condition' before waiting for the interval.
-//
-// Some intervals may be missed if the condition takes too long or the time
-// window is too short.
-func PollImmediateInfinite(interval time.Duration, condition ConditionFunc) error {
- return PollImmediateInfiniteWithContext(context.Background(), interval, condition.WithContext())
+// Deprecated: Will be removed when the legacy polling methods are removed.
+func runConditionWithCrashProtection(condition ConditionFunc) (bool, error) {
+ defer runtime.HandleCrash()
+ return condition()
}
-// PollImmediateInfiniteWithContext tries a condition func until it returns true
-// or an error or the specified context gets cancelled or expired.
+// runConditionWithCrashProtectionWithContext runs a ConditionWithContextFunc
+// with crash protection.
//
-// PollImmediateInfiniteWithContext runs the 'condition' before waiting for the interval.
-//
-// Some intervals may be missed if the condition takes too long or the time
-// window is too short.
-func PollImmediateInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {
- return poll(ctx, true, poller(interval, 0), condition)
-}
-
-// Internally used, each of the public 'Poll*' function defined in this
-// package should invoke this internal function with appropriate parameters.
-// ctx: the context specified by the caller, for infinite polling pass
-// a context that never gets cancelled or expired.
-// immediate: if true, the 'condition' will be invoked before waiting for the interval,
-// in this case 'condition' will always be invoked at least once.
-// wait: user specified WaitFunc function that controls at what interval the condition
-// function should be invoked periodically and whether it is bound by a timeout.
-// condition: user specified ConditionWithContextFunc function.
-func poll(ctx context.Context, immediate bool, wait WaitWithContextFunc, condition ConditionWithContextFunc) error {
- if immediate {
- done, err := runConditionWithCrashProtectionWithContext(ctx, condition)
- if err != nil {
- return err
- }
- if done {
- return nil
- }
- }
-
- select {
- case <-ctx.Done():
- // returning ctx.Err() will break backward compatibility
- return ErrWaitTimeout
- default:
- return WaitForWithContext(ctx, wait, condition)
- }
+// Deprecated: Will be removed when the legacy polling methods are removed.
+func runConditionWithCrashProtectionWithContext(ctx context.Context, condition ConditionWithContextFunc) (bool, error) {
+ defer runtime.HandleCrash()
+ return condition(ctx)
}
-// WaitFunc creates a channel that receives an item every time a test
+// waitFunc creates a channel that receives an item every time a test
// should be executed and is closed when the last test should be invoked.
-type WaitFunc func(done <-chan struct{}) <-chan struct{}
+//
+// Deprecated: Will be removed in a future release in favor of
+// loopConditionUntilContext.
+type waitFunc func(done <-chan struct{}) <-chan struct{}
// WithContext converts the WaitFunc to an equivalent WaitWithContextFunc
-func (w WaitFunc) WithContext() WaitWithContextFunc {
+func (w waitFunc) WithContext() waitWithContextFunc {
return func(ctx context.Context) <-chan struct{} {
return w(ctx.Done())
}
}
-// WaitWithContextFunc creates a channel that receives an item every time a test
+// waitWithContextFunc creates a channel that receives an item every time a test
// should be executed and is closed when the last test should be invoked.
//
// When the specified context gets cancelled or expires the function
// stops sending item and returns immediately.
-type WaitWithContextFunc func(ctx context.Context) <-chan struct{}
-
-// WaitFor continually checks 'fn' as driven by 'wait'.
//
-// WaitFor gets a channel from 'wait()”, and then invokes 'fn' once for every value
-// placed on the channel and once more when the channel is closed. If the channel is closed
-// and 'fn' returns false without error, WaitFor returns ErrWaitTimeout.
-//
-// If 'fn' returns an error the loop ends and that error is returned. If
-// 'fn' returns true the loop ends and nil is returned.
-//
-// ErrWaitTimeout will be returned if the 'done' channel is closed without fn ever
-// returning true.
-//
-// When the done channel is closed, because the golang `select` statement is
-// "uniform pseudo-random", the `fn` might still run one or multiple time,
-// though eventually `WaitFor` will return.
-func WaitFor(wait WaitFunc, fn ConditionFunc, done <-chan struct{}) error {
- ctx, cancel := ContextForChannel(done)
- defer cancel()
- return WaitForWithContext(ctx, wait.WithContext(), fn.WithContext())
-}
+// Deprecated: Will be removed in a future release in favor of
+// loopConditionUntilContext.
+type waitWithContextFunc func(ctx context.Context) <-chan struct{}
-// WaitForWithContext continually checks 'fn' as driven by 'wait'.
+// waitForWithContext continually checks 'fn' as driven by 'wait'.
//
-// WaitForWithContext gets a channel from 'wait()”, and then invokes 'fn'
+// waitForWithContext gets a channel from 'wait()”, and then invokes 'fn'
// once for every value placed on the channel and once more when the
// channel is closed. If the channel is closed and 'fn'
-// returns false without error, WaitForWithContext returns ErrWaitTimeout.
+// returns false without error, waitForWithContext returns ErrWaitTimeout.
//
// If 'fn' returns an error the loop ends and that error is returned. If
// 'fn' returns true the loop ends and nil is returned.
@@ -651,8 +193,11 @@ func WaitFor(wait WaitFunc, fn ConditionFunc, done <-chan struct{}) error {
//
// When the ctx.Done() channel is closed, because the golang `select` statement is
// "uniform pseudo-random", the `fn` might still run one or multiple times,
-// though eventually `WaitForWithContext` will return.
-func WaitForWithContext(ctx context.Context, wait WaitWithContextFunc, fn ConditionWithContextFunc) error {
+// though eventually `waitForWithContext` will return.
+//
+// Deprecated: Will be removed in a future release in favor of
+// loopConditionUntilContext.
+func waitForWithContext(ctx context.Context, wait waitWithContextFunc, fn ConditionWithContextFunc) error {
waitCtx, cancel := context.WithCancel(context.Background())
defer cancel()
c := wait(waitCtx)
@@ -670,88 +215,9 @@ func WaitForWithContext(ctx context.Context, wait WaitWithContextFunc, fn Condit
return ErrWaitTimeout
}
case <-ctx.Done():
- // returning ctx.Err() will break backward compatibility
+ // returning ctx.Err() will break backward compatibility, use new PollUntilContext*
+ // methods instead
return ErrWaitTimeout
}
}
}
-
-// poller returns a WaitFunc that will send to the channel every interval until
-// timeout has elapsed and then closes the channel.
-//
-// Over very short intervals you may receive no ticks before the channel is
-// closed. A timeout of 0 is interpreted as an infinity, and in such a case
-// it would be the caller's responsibility to close the done channel.
-// Failure to do so would result in a leaked goroutine.
-//
-// Output ticks are not buffered. If the channel is not ready to receive an
-// item, the tick is skipped.
-func poller(interval, timeout time.Duration) WaitWithContextFunc {
- return WaitWithContextFunc(func(ctx context.Context) <-chan struct{} {
- ch := make(chan struct{})
-
- go func() {
- defer close(ch)
-
- tick := time.NewTicker(interval)
- defer tick.Stop()
-
- var after <-chan time.Time
- if timeout != 0 {
- // time.After is more convenient, but it
- // potentially leaves timers around much longer
- // than necessary if we exit early.
- timer := time.NewTimer(timeout)
- after = timer.C
- defer timer.Stop()
- }
-
- for {
- select {
- case <-tick.C:
- // If the consumer isn't ready for this signal drop it and
- // check the other channels.
- select {
- case ch <- struct{}{}:
- default:
- }
- case <-after:
- return
- case <-ctx.Done():
- return
- }
- }
- }()
-
- return ch
- })
-}
-
-// ExponentialBackoffWithContext works with a request context and a Backoff. It ensures that the retry wait never
-// exceeds the deadline specified by the request context.
-func ExponentialBackoffWithContext(ctx context.Context, backoff Backoff, condition ConditionFunc) error {
- for backoff.Steps > 0 {
- select {
- case <-ctx.Done():
- return ctx.Err()
- default:
- }
-
- if ok, err := runConditionWithCrashProtection(condition); err != nil || ok {
- return err
- }
-
- if backoff.Steps == 1 {
- break
- }
-
- waitBeforeRetry := backoff.Step()
- select {
- case <-ctx.Done():
- return ctx.Err()
- case <-time.After(waitBeforeRetry):
- }
- }
-
- return ErrWaitTimeout
-}
diff --git a/vendor/k8s.io/apimachinery/pkg/watch/watch.go b/vendor/k8s.io/apimachinery/pkg/watch/watch.go
index b6c7bbfa8..ce37fd8c1 100644
--- a/vendor/k8s.io/apimachinery/pkg/watch/watch.go
+++ b/vendor/k8s.io/apimachinery/pkg/watch/watch.go
@@ -27,13 +27,25 @@ import (
// Interface can be implemented by anything that knows how to watch and report changes.
type Interface interface {
- // Stop stops watching. Will close the channel returned by ResultChan(). Releases
- // any resources used by the watch.
+ // Stop tells the producer that the consumer is done watching, so the
+ // producer should stop sending events and close the result channel. The
+ // consumer should keep watching for events until the result channel is
+ // closed.
+ //
+ // Because some implementations may create channels when constructed, Stop
+ // must always be called, even if the consumer has not yet called
+ // ResultChan().
+ //
+ // Only the consumer should call Stop(), not the producer. If the producer
+ // errors and needs to stop the watch prematurely, it should instead send
+ // an error event and close the result channel.
Stop()
- // ResultChan returns a chan which will receive all the events. If an error occurs
- // or Stop() is called, the implementation will close this channel and
- // release any resources used by the watch.
+ // ResultChan returns a channel which will receive events from the event
+ // producer. If an error occurs or Stop() is called, the producer must
+ // close this channel and release any resources used by the watch.
+ // Closing the result channel tells the consumer that no more events will be
+ // sent.
ResultChan() <-chan Event
}
@@ -322,3 +334,21 @@ func (pw *ProxyWatcher) ResultChan() <-chan Event {
func (pw *ProxyWatcher) StopChan() <-chan struct{} {
return pw.stopCh
}
+
+// MockWatcher implements watch.Interface with mockable functions.
+type MockWatcher struct {
+ StopFunc func()
+ ResultChanFunc func() <-chan Event
+}
+
+var _ Interface = &MockWatcher{}
+
+// Stop calls StopFunc
+func (mw MockWatcher) Stop() {
+ mw.StopFunc()
+}
+
+// ResultChan calls ResultChanFunc
+func (mw MockWatcher) ResultChan() <-chan Event {
+ return mw.ResultChanFunc()
+}
diff --git a/vendor/k8s.io/klog/v2/OWNERS b/vendor/k8s.io/klog/v2/OWNERS
index a2fe8f351..7500475a6 100644
--- a/vendor/k8s.io/klog/v2/OWNERS
+++ b/vendor/k8s.io/klog/v2/OWNERS
@@ -1,14 +1,16 @@
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- harshanarayana
+ - mengjiao-liu
- pohly
approvers:
- dims
+ - pohly
- thockin
- - serathius
emeritus_approvers:
- brancz
- justinsb
- lavalamp
- piosz
+ - serathius
- tallclair
diff --git a/vendor/k8s.io/klog/v2/contextual_slog.go b/vendor/k8s.io/klog/v2/contextual_slog.go
new file mode 100644
index 000000000..d3b562521
--- /dev/null
+++ b/vendor/k8s.io/klog/v2/contextual_slog.go
@@ -0,0 +1,31 @@
+//go:build go1.21
+// +build go1.21
+
+/*
+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 klog
+
+import (
+ "log/slog"
+
+ "github.com/go-logr/logr"
+)
+
+// SetSlogLogger reconfigures klog to log through the slog logger. The logger must not be nil.
+func SetSlogLogger(logger *slog.Logger) {
+ SetLoggerWithOptions(logr.FromSlogHandler(logger.Handler()), ContextualLogger(true))
+}
diff --git a/vendor/k8s.io/klog/v2/klog.go b/vendor/k8s.io/klog/v2/klog.go
index 72502db3a..47ec9466a 100644
--- a/vendor/k8s.io/klog/v2/klog.go
+++ b/vendor/k8s.io/klog/v2/klog.go
@@ -14,9 +14,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Package klog implements logging analogous to the Google-internal C++ INFO/ERROR/V setup.
-// It provides functions Info, Warning, Error, Fatal, plus formatting variants such as
-// Infof. It also provides V-style logging controlled by the -v and -vmodule=file=2 flags.
+// Package klog contains the following functionality:
+//
+// - output routing as defined via command line flags ([InitFlags])
+// - log formatting as text, either with a single, unstructured string ([Info], [Infof], etc.)
+// or as a structured log entry with message and key/value pairs ([InfoS], etc.)
+// - management of a go-logr [Logger] ([SetLogger], [Background], [TODO])
+// - helper functions for logging values ([Format]) and managing the state of klog ([CaptureState], [State.Restore])
+// - wrappers for [logr] APIs for contextual logging where the wrappers can
+// be turned into no-ops ([EnableContextualLogging], [NewContext], [FromContext],
+// [LoggerWithValues], [LoggerWithName]); if the ability to turn off
+// contextual logging is not needed, then go-logr can also be used directly
+// - type aliases for go-logr types to simplify imports in code which uses both (e.g. [Logger])
+// - [k8s.io/klog/v2/textlogger]: a logger which uses the same formatting as klog log with
+// simpler output routing; beware that it comes with its own command line flags
+// and does not use the ones from klog
+// - [k8s.io/klog/v2/ktesting]: per-test output in Go unit tests
+// - [k8s.io/klog/v2/klogr]: a deprecated, standalone [logr.Logger] on top of the main klog package;
+// use [Background] instead if klog output routing is needed, [k8s.io/klog/v2/textlogger] if not
+// - [k8s.io/klog/v2/examples]: demos of this functionality
+// - [k8s.io/klog/v2/test]: reusable tests for [logr.Logger] implementations
//
// Basic examples:
//
@@ -387,13 +404,6 @@ func (t *traceLocation) Set(value string) error {
return nil
}
-// flushSyncWriter is the interface satisfied by logging destinations.
-type flushSyncWriter interface {
- Flush() error
- Sync() error
- io.Writer
-}
-
var logging loggingT
var commandLine flag.FlagSet
@@ -469,7 +479,7 @@ type settings struct {
// Access to all of the following fields must be protected via a mutex.
// file holds writer for each of the log types.
- file [severity.NumSeverity]flushSyncWriter
+ file [severity.NumSeverity]io.Writer
// flushInterval is the interval for periodic flushing. If zero,
// the global default will be used.
flushInterval time.Duration
@@ -814,32 +824,12 @@ func (l *loggingT) printS(err error, s severity.Severity, depth int, msg string,
buffer.PutBuffer(b)
}
-// redirectBuffer is used to set an alternate destination for the logs
-type redirectBuffer struct {
- w io.Writer
-}
-
-func (rb *redirectBuffer) Sync() error {
- return nil
-}
-
-func (rb *redirectBuffer) Flush() error {
- return nil
-}
-
-func (rb *redirectBuffer) Write(bytes []byte) (n int, err error) {
- return rb.w.Write(bytes)
-}
-
// SetOutput sets the output destination for all severities
func SetOutput(w io.Writer) {
logging.mu.Lock()
defer logging.mu.Unlock()
for s := severity.FatalLog; s >= severity.InfoLog; s-- {
- rb := &redirectBuffer{
- w: w,
- }
- logging.file[s] = rb
+ logging.file[s] = w
}
}
@@ -851,10 +841,7 @@ func SetOutputBySeverity(name string, w io.Writer) {
if !ok {
panic(fmt.Sprintf("SetOutputBySeverity(%q): unrecognized severity name", name))
}
- rb := &redirectBuffer{
- w: w,
- }
- logging.file[sev] = rb
+ logging.file[sev] = w
}
// LogToStderr sets whether to log exclusively to stderr, bypassing outputs
@@ -994,7 +981,8 @@ func (l *loggingT) exit(err error) {
logExitFunc(err)
return
}
- l.flushAll()
+ needToSync := l.flushAll()
+ l.syncAll(needToSync)
OsExit(2)
}
@@ -1011,10 +999,6 @@ type syncBuffer struct {
maxbytes uint64 // The max number of bytes this syncBuffer.file can hold before cleaning up.
}
-func (sb *syncBuffer) Sync() error {
- return sb.file.Sync()
-}
-
// CalculateMaxSize returns the real max size in bytes after considering the default max size and the flag options.
func CalculateMaxSize() uint64 {
if logging.logFile != "" {
@@ -1206,24 +1190,45 @@ func StartFlushDaemon(interval time.Duration) {
// lockAndFlushAll is like flushAll but locks l.mu first.
func (l *loggingT) lockAndFlushAll() {
l.mu.Lock()
- l.flushAll()
+ needToSync := l.flushAll()
l.mu.Unlock()
+ // Some environments are slow when syncing and holding the lock might cause contention.
+ l.syncAll(needToSync)
}
-// flushAll flushes all the logs and attempts to "sync" their data to disk.
+// flushAll flushes all the logs
// l.mu is held.
-func (l *loggingT) flushAll() {
+//
+// The result is the number of files which need to be synced and the pointers to them.
+func (l *loggingT) flushAll() fileArray {
+ var needToSync fileArray
+
// Flush from fatal down, in case there's trouble flushing.
for s := severity.FatalLog; s >= severity.InfoLog; s-- {
file := l.file[s]
- if file != nil {
- _ = file.Flush() // ignore error
- _ = file.Sync() // ignore error
+ if sb, ok := file.(*syncBuffer); ok && sb.file != nil {
+ _ = sb.Flush() // ignore error
+ needToSync.files[needToSync.num] = sb.file
+ needToSync.num++
}
}
if logging.loggerOptions.flush != nil {
logging.loggerOptions.flush()
}
+ return needToSync
+}
+
+type fileArray struct {
+ num int
+ files [severity.NumSeverity]*os.File
+}
+
+// syncAll attempts to "sync" their data to disk.
+func (l *loggingT) syncAll(needToSync fileArray) {
+ // Flush from fatal down, in case there's trouble flushing.
+ for i := 0; i < needToSync.num; i++ {
+ _ = needToSync.files[i].Sync() // ignore error
+ }
}
// CopyStandardLogTo arranges for messages written to the Go "log" package's
diff --git a/vendor/k8s.io/klog/v2/klogr_slog.go b/vendor/k8s.io/klog/v2/klogr_slog.go
index f7bf74030..c77d7baaf 100644
--- a/vendor/k8s.io/klog/v2/klogr_slog.go
+++ b/vendor/k8s.io/klog/v2/klogr_slog.go
@@ -25,7 +25,7 @@ import (
"strconv"
"time"
- "github.com/go-logr/logr/slogr"
+ "github.com/go-logr/logr"
"k8s.io/klog/v2/internal/buffer"
"k8s.io/klog/v2/internal/serialize"
@@ -35,7 +35,7 @@ import (
func (l *klogger) Handle(ctx context.Context, record slog.Record) error {
if logging.logger != nil {
- if slogSink, ok := logging.logger.GetSink().(slogr.SlogSink); ok {
+ if slogSink, ok := logging.logger.GetSink().(logr.SlogSink); ok {
// Let that logger do the work.
return slogSink.Handle(ctx, record)
}
@@ -77,13 +77,13 @@ func slogOutput(file string, line int, now time.Time, err error, s severity.Seve
buffer.PutBuffer(b)
}
-func (l *klogger) WithAttrs(attrs []slog.Attr) slogr.SlogSink {
+func (l *klogger) WithAttrs(attrs []slog.Attr) logr.SlogSink {
clone := *l
clone.values = serialize.WithValues(l.values, sloghandler.Attrs2KVList(l.groups, attrs))
return &clone
}
-func (l *klogger) WithGroup(name string) slogr.SlogSink {
+func (l *klogger) WithGroup(name string) logr.SlogSink {
clone := *l
if clone.groups != "" {
clone.groups += "." + name
@@ -93,4 +93,4 @@ func (l *klogger) WithGroup(name string) slogr.SlogSink {
return &clone
}
-var _ slogr.SlogSink = &klogger{}
+var _ logr.SlogSink = &klogger{}
diff --git a/vendor/k8s.io/klog/v2/safeptr.go b/vendor/k8s.io/klog/v2/safeptr.go
new file mode 100644
index 000000000..bbe24c2e8
--- /dev/null
+++ b/vendor/k8s.io/klog/v2/safeptr.go
@@ -0,0 +1,34 @@
+//go:build go1.18
+// +build go1.18
+
+/*
+Copyright 2023 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 klog
+
+// SafePtr is a function that takes a pointer of any type (T) as an argument.
+// If the provided pointer is not nil, it returns the same pointer. If it is nil, it returns nil instead.
+//
+// This function is particularly useful to prevent nil pointer dereferencing when:
+//
+// - The type implements interfaces that are called by the logger, such as `fmt.Stringer`.
+// - And these interface implementations do not perform nil checks themselves.
+func SafePtr[T any](p *T) any {
+ if p == nil {
+ return nil
+ }
+ return p
+}
diff --git a/vendor/k8s.io/kube-openapi/pkg/common/common.go b/vendor/k8s.io/kube-openapi/pkg/common/common.go
index 2e15e163c..e4ce843b0 100644
--- a/vendor/k8s.io/kube-openapi/pkg/common/common.go
+++ b/vendor/k8s.io/kube-openapi/pkg/common/common.go
@@ -164,6 +164,9 @@ type OpenAPIV3Config struct {
// It is an optional function to customize model names.
GetDefinitionName func(name string) (string, spec.Extensions)
+ // PostProcessSpec runs after the spec is ready to serve. It allows a final modification to the spec before serving.
+ PostProcessSpec func(*spec3.OpenAPI) (*spec3.OpenAPI, error)
+
// SecuritySchemes is list of all security schemes for OpenAPI service.
SecuritySchemes spec3.SecuritySchemes
diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go
index 799d866d5..9887d185b 100644
--- a/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go
+++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go
@@ -214,9 +214,6 @@ func makeUnion(extensions map[string]interface{}) (schema.Union, error) {
}
}
- if union.Discriminator != nil && len(union.Fields) == 0 {
- return schema.Union{}, fmt.Errorf("discriminator set to %v, but no fields in union", *union.Discriminator)
- }
return union, nil
}
diff --git a/vendor/k8s.io/kube-openapi/pkg/util/proto/document.go b/vendor/k8s.io/kube-openapi/pkg/util/proto/document.go
index 5789e67ab..1b758ab25 100644
--- a/vendor/k8s.io/kube-openapi/pkg/util/proto/document.go
+++ b/vendor/k8s.io/kube-openapi/pkg/util/proto/document.go
@@ -22,7 +22,7 @@ import (
"strings"
openapi_v2 "github.com/google/gnostic-models/openapiv2"
- "gopkg.in/yaml.v2"
+ yaml "sigs.k8s.io/yaml/goyaml.v2"
)
func newSchemaError(path *Path, format string, a ...interface{}) error {
diff --git a/vendor/k8s.io/mount-utils/fake_mounter.go b/vendor/k8s.io/mount-utils/fake_mounter.go
index 55ea5e298..084428445 100644
--- a/vendor/k8s.io/mount-utils/fake_mounter.go
+++ b/vendor/k8s.io/mount-utils/fake_mounter.go
@@ -32,8 +32,9 @@ type FakeMounter struct {
MountCheckErrors map[string]error
// Some tests run things in parallel, make sure the mounter does not produce
// any golang's DATA RACE warnings.
- mutex sync.Mutex
- UnmountFunc UnmountFunc
+ mutex sync.Mutex
+ UnmountFunc UnmountFunc
+ skipMountPointCheck bool
}
// UnmountFunc is a function callback to be executed during the Unmount() call.
@@ -64,6 +65,11 @@ func NewFakeMounter(mps []MountPoint) *FakeMounter {
}
}
+func (f *FakeMounter) WithSkipMountPointCheck() *FakeMounter {
+ f.skipMountPointCheck = true
+ return f
+}
+
// ResetLog clears all the log entries in FakeMounter
func (f *FakeMounter) ResetLog() {
f.mutex.Lock()
@@ -212,6 +218,18 @@ func (f *FakeMounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, nil
}
+func (f *FakeMounter) CanSafelySkipMountPointCheck() bool {
+ return f.skipMountPointCheck
+}
+
+func (f *FakeMounter) IsMountPoint(file string) (bool, error) {
+ notMnt, err := f.IsLikelyNotMountPoint(file)
+ if err != nil {
+ return false, err
+ }
+ return !notMnt, nil
+}
+
// GetMountRefs finds all mount references to the path, returns a
// list of paths.
func (f *FakeMounter) GetMountRefs(pathname string) ([]string, error) {
diff --git a/vendor/k8s.io/mount-utils/mount.go b/vendor/k8s.io/mount-utils/mount.go
index a882fcc73..0bd91ee61 100644
--- a/vendor/k8s.io/mount-utils/mount.go
+++ b/vendor/k8s.io/mount-utils/mount.go
@@ -21,7 +21,6 @@ package mount
import (
"fmt"
- "os"
"path/filepath"
"strings"
"time"
@@ -66,6 +65,18 @@ type Interface interface {
// care about such situations, this is a faster alternative to calling List()
// and scanning that output.
IsLikelyNotMountPoint(file string) (bool, error)
+ // CanSafelySkipMountPointCheck indicates whether this mounter returns errors on
+ // operations for targets that are not mount points. If this returns true, no such
+ // errors will be returned.
+ CanSafelySkipMountPointCheck() bool
+ // IsMountPoint determines if a directory is a mountpoint.
+ // It should return ErrNotExist when the directory does not exist.
+ // IsMountPoint is more expensive than IsLikelyNotMountPoint.
+ // IsMountPoint detects bind mounts in linux.
+ // IsMountPoint may enumerate all the mountpoints using List() and
+ // the list of mountpoints may be large, then it uses
+ // isMountPointMatch to evaluate whether the directory is a mountpoint.
+ IsMountPoint(file string) (bool, error)
// GetMountRefs finds all mount references to pathname, returning a slice of
// paths. Pathname can be a mountpoint path or a normal directory
// (for bind mount). On Linux, pathname is excluded from the slice.
@@ -136,6 +147,37 @@ func NewMountError(mountErrorValue MountErrorType, format string, args ...interf
type SafeFormatAndMount struct {
Interface
Exec utilexec.Interface
+
+ formatSem chan any
+ formatTimeout time.Duration
+}
+
+func NewSafeFormatAndMount(mounter Interface, exec utilexec.Interface, opts ...Option) *SafeFormatAndMount {
+ res := &SafeFormatAndMount{
+ Interface: mounter,
+ Exec: exec,
+ }
+ for _, opt := range opts {
+ opt(res)
+ }
+ return res
+}
+
+type Option func(*SafeFormatAndMount)
+
+// WithMaxConcurrentFormat sets the maximum number of concurrent format
+// operations executed by the mounter. The timeout controls the maximum
+// duration of a format operation before its concurrency token is released.
+// Once a token is released, it can be acquired by another concurrent format
+// operation. The original operation is allowed to complete.
+// If n < 1, concurrency is set to unlimited.
+func WithMaxConcurrentFormat(n int, timeout time.Duration) Option {
+ return func(mounter *SafeFormatAndMount) {
+ if n > 0 {
+ mounter.formatSem = make(chan any, n)
+ mounter.formatTimeout = timeout
+ }
+ }
}
// FormatAndMount formats the given disk, if needed, and mounts it.
@@ -154,7 +196,15 @@ func (mounter *SafeFormatAndMount) FormatAndMount(source string, target string,
// be used by callers that pass sensitive material (like passwords) as mount
// options.
func (mounter *SafeFormatAndMount) FormatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error {
- return mounter.formatAndMountSensitive(source, target, fstype, options, sensitiveOptions)
+ return mounter.FormatAndMountSensitiveWithFormatOptions(source, target, fstype, options, sensitiveOptions, nil /* formatOptions */)
+}
+
+// FormatAndMountSensitiveWithFormatOptions behaves exactly the same as
+// FormatAndMountSensitive, but allows for options to be passed when the disk
+// is formatted. These options are NOT validated in any way and should never
+// come directly from untrusted user input as that would be an injection risk.
+func (mounter *SafeFormatAndMount) FormatAndMountSensitiveWithFormatOptions(source string, target string, fstype string, options []string, sensitiveOptions []string, formatOptions []string) error {
+ return mounter.formatAndMountSensitive(source, target, fstype, options, sensitiveOptions, formatOptions)
}
// getMountRefsByDev finds all references to the device provided
@@ -187,6 +237,24 @@ func getMountRefsByDev(mounter Interface, mountPath string) ([]string, error) {
return refs, nil
}
+// IsNotMountPoint determines if a directory is a mountpoint.
+// It should return ErrNotExist when the directory does not exist.
+// IsNotMountPoint is more expensive than IsLikelyNotMountPoint
+// and depends on IsMountPoint.
+//
+// If an error occurs, it returns true (assuming it is not a mountpoint)
+// when ErrNotExist is returned for callers similar to IsLikelyNotMountPoint.
+//
+// Deprecated: This function is kept to keep changes backward compatible with
+// previous library version. Callers should prefer mounter.IsMountPoint.
+func IsNotMountPoint(mounter Interface, file string) (bool, error) {
+ isMnt, err := mounter.IsMountPoint(file)
+ if err != nil {
+ return true, err
+ }
+ return !isMnt, nil
+}
+
// GetDeviceNameFromMount given a mnt point, find the device from /proc/mounts
// returns the device name, reference count, and error code.
func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, error) {
@@ -220,56 +288,11 @@ func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, e
return device, refCount, nil
}
-// IsNotMountPoint determines if a directory is a mountpoint.
-// It should return ErrNotExist when the directory does not exist.
-// IsNotMountPoint is more expensive than IsLikelyNotMountPoint.
-// IsNotMountPoint detects bind mounts in linux.
-// IsNotMountPoint enumerates all the mountpoints using List() and
-// the list of mountpoints may be large, then it uses
-// isMountPointMatch to evaluate whether the directory is a mountpoint.
-func IsNotMountPoint(mounter Interface, file string) (bool, error) {
- // IsLikelyNotMountPoint provides a quick check
- // to determine whether file IS A mountpoint.
- notMnt, notMntErr := mounter.IsLikelyNotMountPoint(file)
- if notMntErr != nil && os.IsPermission(notMntErr) {
- // We were not allowed to do the simple stat() check, e.g. on NFS with
- // root_squash. Fall back to /proc/mounts check below.
- notMnt = true
- notMntErr = nil
- }
- if notMntErr != nil {
- return notMnt, notMntErr
- }
- // identified as mountpoint, so return this fact.
- if notMnt == false {
- return notMnt, nil
- }
-
- // Resolve any symlinks in file, kernel would do the same and use the resolved path in /proc/mounts.
- resolvedFile, err := filepath.EvalSymlinks(file)
- if err != nil {
- return true, err
- }
-
- // check all mountpoints since IsLikelyNotMountPoint
- // is not reliable for some mountpoint types.
- mountPoints, mountPointsErr := mounter.List()
- if mountPointsErr != nil {
- return notMnt, mountPointsErr
- }
- for _, mp := range mountPoints {
- if isMountPointMatch(mp, resolvedFile) {
- notMnt = false
- break
- }
- }
- return notMnt, nil
-}
-
// MakeBindOpts detects whether a bind mount is being requested and makes the remount options to
// use in case of bind mount, due to the fact that bind mount doesn't respect mount options.
// The list equals:
-// options - 'bind' + 'remount' (no duplicate)
+//
+// options - 'bind' + 'remount' (no duplicate)
func MakeBindOpts(options []string) (bool, []string, []string) {
bind, bindOpts, bindRemountOpts, _ := MakeBindOptsSensitive(options, nil /* sensitiveOptions */)
return bind, bindOpts, bindRemountOpts
diff --git a/vendor/k8s.io/mount-utils/mount_helper_common.go b/vendor/k8s.io/mount-utils/mount_helper_common.go
index 196ae30ad..fc7bbc143 100644
--- a/vendor/k8s.io/mount-utils/mount_helper_common.go
+++ b/vendor/k8s.io/mount-utils/mount_helper_common.go
@@ -31,7 +31,7 @@ import (
func CleanupMountPoint(mountPath string, mounter Interface, extensiveMountPointCheck bool) error {
pathExists, pathErr := PathExists(mountPath)
if !pathExists && pathErr == nil {
- klog.Warningf("Warning: Unmount skipped because path does not exist: %v", mountPath)
+ klog.Warningf("Warning: mount cleanup skipped because path does not exist: %v", mountPath)
return nil
}
corruptedMnt := IsCorruptedMnt(pathErr)
@@ -44,36 +44,41 @@ func CleanupMountPoint(mountPath string, mounter Interface, extensiveMountPointC
func CleanupMountWithForce(mountPath string, mounter MounterForceUnmounter, extensiveMountPointCheck bool, umountTimeout time.Duration) error {
pathExists, pathErr := PathExists(mountPath)
if !pathExists && pathErr == nil {
- klog.Warningf("Warning: Unmount skipped because path does not exist: %v", mountPath)
+ klog.Warningf("Warning: mount cleanup skipped because path does not exist: %v", mountPath)
return nil
}
corruptedMnt := IsCorruptedMnt(pathErr)
if pathErr != nil && !corruptedMnt {
return fmt.Errorf("Error checking path: %v", pathErr)
}
- var notMnt bool
- var err error
- if !corruptedMnt {
- notMnt, err = removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
- // if mountPath was not a mount point - we would have attempted to remove mountPath
- // and hence return errors if any.
- if err != nil || notMnt {
+
+ if corruptedMnt || mounter.CanSafelySkipMountPointCheck() {
+ klog.V(4).Infof("unmounting %q (corruptedMount: %t, mounterCanSkipMountPointChecks: %t)",
+ mountPath, corruptedMnt, mounter.CanSafelySkipMountPointCheck())
+ if err := mounter.UnmountWithForce(mountPath, umountTimeout); err != nil {
return err
}
+ return removePath(mountPath)
+ }
+
+ notMnt, err := removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
+ // if mountPath is not a mount point, it's just been removed or there was an error
+ if err != nil || notMnt {
+ return err
}
- // Unmount the mount path
klog.V(4).Infof("%q is a mountpoint, unmounting", mountPath)
if err := mounter.UnmountWithForce(mountPath, umountTimeout); err != nil {
return err
}
notMnt, err = removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
- // mountPath is not a mount point we should return whatever error we saw
+ // if mountPath is not a mount point, it's either just been removed or there was an error
if notMnt {
return err
}
- return fmt.Errorf("Failed to unmount path %v", mountPath)
+ // mountPath is still a mount point
+ return fmt.Errorf("failed to cleanup mount point %v", mountPath)
}
// doCleanupMountPoint unmounts the given path and
@@ -82,31 +87,35 @@ func CleanupMountWithForce(mountPath string, mounter MounterForceUnmounter, exte
// IsNotMountPoint will be called instead of IsLikelyNotMountPoint.
// IsNotMountPoint is more expensive but properly handles bind mounts within the same fs.
// if corruptedMnt is true, it means that the mountPath is a corrupted mountpoint, and the mount point check
-// will be skipped
+// will be skipped. The mount point check will also be skipped if the mounter supports it.
func doCleanupMountPoint(mountPath string, mounter Interface, extensiveMountPointCheck bool, corruptedMnt bool) error {
- var notMnt bool
- var err error
- if !corruptedMnt {
- notMnt, err = removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
- // if mountPath was not a mount point - we would have attempted to remove mountPath
- // and hence return errors if any.
- if err != nil || notMnt {
+ if corruptedMnt || mounter.CanSafelySkipMountPointCheck() {
+ klog.V(4).Infof("unmounting %q (corruptedMount: %t, mounterCanSkipMountPointChecks: %t)",
+ mountPath, corruptedMnt, mounter.CanSafelySkipMountPointCheck())
+ if err := mounter.Unmount(mountPath); err != nil {
return err
}
+ return removePath(mountPath)
+ }
+
+ notMnt, err := removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
+ // if mountPath is not a mount point, it's just been removed or there was an error
+ if err != nil || notMnt {
+ return err
}
- // Unmount the mount path
klog.V(4).Infof("%q is a mountpoint, unmounting", mountPath)
if err := mounter.Unmount(mountPath); err != nil {
return err
}
notMnt, err = removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
- // mountPath is not a mount point we should return whatever error we saw
+ // if mountPath is not a mount point, it's either just been removed or there was an error
if notMnt {
return err
}
- return fmt.Errorf("Failed to unmount path %v", mountPath)
+ // mountPath is still a mount point
+ return fmt.Errorf("failed to cleanup mount point %v", mountPath)
}
// removePathIfNotMountPoint verifies if given mountPath is a mount point if not it attempts
@@ -130,8 +139,19 @@ func removePathIfNotMountPoint(mountPath string, mounter Interface, extensiveMou
}
if notMnt {
- klog.Warningf("Warning: %q is not a mountpoint, deleting", mountPath)
+ klog.V(4).Infof("%q is not a mountpoint, deleting", mountPath)
return notMnt, os.Remove(mountPath)
}
return notMnt, nil
}
+
+// removePath attempts to remove the directory. Returns nil if the directory was removed or does not exist.
+func removePath(mountPath string) error {
+ klog.V(4).Infof("Deleting path %q", mountPath)
+ err := os.Remove(mountPath)
+ if os.IsNotExist(err) {
+ klog.V(4).Infof("%q does not exist", mountPath)
+ return nil
+ }
+ return err
+}
diff --git a/vendor/k8s.io/mount-utils/mount_helper_unix.go b/vendor/k8s.io/mount-utils/mount_helper_unix.go
index cb8732fce..1c603dca7 100644
--- a/vendor/k8s.io/mount-utils/mount_helper_unix.go
+++ b/vendor/k8s.io/mount-utils/mount_helper_unix.go
@@ -20,14 +20,17 @@ limitations under the License.
package mount
import (
+ "bytes"
"errors"
"fmt"
"io/fs"
"os"
"strconv"
"strings"
+ "sync"
"syscall"
+ "golang.org/x/sys/unix"
"k8s.io/klog/v2"
utilio "k8s.io/utils/io"
)
@@ -58,7 +61,13 @@ func IsCorruptedMnt(err error) bool {
underlyingError = err
}
- return underlyingError == syscall.ENOTCONN || underlyingError == syscall.ESTALE || underlyingError == syscall.EIO || underlyingError == syscall.EACCES || underlyingError == syscall.EHOSTDOWN
+ return errors.Is(underlyingError, syscall.ENOTCONN) ||
+ errors.Is(underlyingError, syscall.ESTALE) ||
+ errors.Is(underlyingError, syscall.EIO) ||
+ errors.Is(underlyingError, syscall.EACCES) ||
+ errors.Is(underlyingError, syscall.EHOSTDOWN) ||
+ errors.Is(underlyingError, syscall.EWOULDBLOCK) ||
+ errors.Is(underlyingError, syscall.ENODEV)
}
// MountInfo represents a single line in /proc//mountinfo.
@@ -91,7 +100,7 @@ type MountInfo struct { // nolint: golint
// ParseMountInfo parses /proc/xxx/mountinfo.
func ParseMountInfo(filename string) ([]MountInfo, error) {
- content, err := utilio.ConsistentRead(filename, maxListTries)
+ content, err := readMountInfo(filename)
if err != nil {
return []MountInfo{}, err
}
@@ -173,8 +182,7 @@ func splitMountOptions(s string) []string {
// isMountPointMatch returns true if the path in mp is the same as dir.
// Handles case where mountpoint dir has been renamed due to stale NFS mount.
func isMountPointMatch(mp MountPoint, dir string) bool {
- deletedDir := fmt.Sprintf("%s\\040(deleted)", dir)
- return ((mp.Path == dir) || (mp.Path == deletedDir))
+ return strings.TrimSuffix(mp.Path, "\\040(deleted)") == dir
}
// PathExists returns true if the specified path exists.
@@ -199,3 +207,50 @@ func PathExists(path string) (bool, error) {
}
return false, err
}
+
+// These variables are used solely by kernelHasMountinfoBug.
+var (
+ hasMountinfoBug bool
+ checkMountinfoBugOnce sync.Once
+)
+
+// kernelHasMountinfoBug checks if the kernel bug that can lead to incomplete
+// mountinfo being read is fixed. It does so by checking the kernel version.
+//
+// The bug was fixed by the kernel commit 9f6c61f96f2d97 (since Linux 5.8).
+// Alas, there is no better way to check if the bug is fixed other than to
+// rely on the kernel version returned by uname.
+func kernelHasMountinfoBug() bool {
+ checkMountinfoBugOnce.Do(func() {
+ // Assume old kernel.
+ hasMountinfoBug = true
+
+ uname := unix.Utsname{}
+ err := unix.Uname(&uname)
+ if err != nil {
+ return
+ }
+
+ end := bytes.IndexByte(uname.Release[:], 0)
+ v := bytes.SplitN(uname.Release[:end], []byte{'.'}, 3)
+ if len(v) != 3 {
+ return
+ }
+ major, _ := strconv.Atoi(string(v[0]))
+ minor, _ := strconv.Atoi(string(v[1]))
+
+ if major > 5 || (major == 5 && minor >= 8) {
+ hasMountinfoBug = false
+ }
+ })
+
+ return hasMountinfoBug
+}
+
+func readMountInfo(path string) ([]byte, error) {
+ if kernelHasMountinfoBug() {
+ return utilio.ConsistentRead(path, maxListTries)
+ }
+
+ return os.ReadFile(path)
+}
diff --git a/vendor/k8s.io/mount-utils/mount_linux.go b/vendor/k8s.io/mount-utils/mount_linux.go
index aaa592161..439d50589 100644
--- a/vendor/k8s.io/mount-utils/mount_linux.go
+++ b/vendor/k8s.io/mount-utils/mount_linux.go
@@ -21,7 +21,9 @@ package mount
import (
"context"
+ "errors"
"fmt"
+ "io/fs"
"os"
"os/exec"
"path/filepath"
@@ -30,9 +32,12 @@ import (
"syscall"
"time"
+ "github.com/moby/sys/mountinfo"
+ "golang.org/x/sys/unix"
+
+ inuserns "github.com/moby/sys/userns"
"k8s.io/klog/v2"
utilexec "k8s.io/utils/exec"
- utilio "k8s.io/utils/io"
)
const (
@@ -48,14 +53,23 @@ const (
fsckErrorsUncorrected = 4
// Error thrown by exec cmd.Run() when process spawned by cmd.Start() completes before cmd.Wait() is called (see - k/k issue #103753)
errNoChildProcesses = "wait: no child processes"
+ // Error returned by some `umount` implementations when the specified path is not a mount point
+ errNotMounted = "not mounted"
+)
+
+var (
+ // Error statx support since Linux 4.11, https://man7.org/linux/man-pages/man2/statx.2.html
+ errStatxNotSupport = errors.New("the statx syscall is not supported. At least Linux kernel 4.11 is needed")
)
// Mounter provides the default implementation of mount.Interface
// for the linux platform. This implementation assumes that the
// kubelet is running in the host's root mount namespace.
type Mounter struct {
- mounterPath string
- withSystemd bool
+ mounterPath string
+ withSystemd *bool
+ trySystemd bool
+ withSafeNotMountedBehavior bool
}
var _ MounterForceUnmounter = &Mounter{}
@@ -65,8 +79,89 @@ var _ MounterForceUnmounter = &Mounter{}
// mounterPath allows using an alternative to `/bin/mount` for mounting.
func New(mounterPath string) Interface {
return &Mounter{
- mounterPath: mounterPath,
- withSystemd: detectSystemd(),
+ mounterPath: mounterPath,
+ trySystemd: true,
+ withSafeNotMountedBehavior: detectSafeNotMountedBehavior(),
+ }
+}
+
+// NewWithoutSystemd returns a Linux specific mount.Interface for the current
+// system. It provides options to override the default mounter behavior.
+// mounterPath allows using an alternative to `/bin/mount` for mounting. Any
+// detection for systemd functionality is disabled with this Mounter.
+func NewWithoutSystemd(mounterPath string) Interface {
+ return &Mounter{
+ mounterPath: mounterPath,
+ trySystemd: false,
+ withSafeNotMountedBehavior: detectSafeNotMountedBehavior(),
+ }
+}
+
+// hasSystemd validates that the withSystemd bool is set, if it is not,
+// detectSystemd will be called once for this Mounter instance.
+func (mounter *Mounter) hasSystemd() bool {
+ if !mounter.trySystemd {
+ mounter.withSystemd = &mounter.trySystemd
+ }
+
+ if mounter.withSystemd == nil {
+ withSystemd := detectSystemd()
+ mounter.withSystemd = &withSystemd
+ }
+
+ return *mounter.withSystemd
+}
+
+// Map unix.Statfs mount flags ro, nodev, noexec, nosuid, noatime, relatime,
+// nodiratime to mount option flag strings.
+func getUserNSBindMountOptions(path string, statfs func(path string, buf *unix.Statfs_t) (err error)) ([]string, error) {
+ var s unix.Statfs_t
+ var mountOpts []string
+ if err := statfs(path, &s); err != nil {
+ return nil, &os.PathError{Op: "statfs", Path: path, Err: err}
+ }
+ flagMapping := map[int]string{
+ unix.MS_RDONLY: "ro",
+ unix.MS_NODEV: "nodev",
+ unix.MS_NOEXEC: "noexec",
+ unix.MS_NOSUID: "nosuid",
+ unix.MS_NOATIME: "noatime",
+ unix.MS_RELATIME: "relatime",
+ unix.MS_NODIRATIME: "nodiratime",
+ }
+ for k, v := range flagMapping {
+ if int(s.Flags)&k == k {
+ mountOpts = append(mountOpts, v)
+ }
+ }
+ return mountOpts, nil
+}
+
+// Do a bind mount including the needed remount for applying the bind opts.
+// If the remount fails and we are running in a user namespace
+// figure out if the source filesystem has the ro, nodev, noexec, nosuid,
+// noatime, relatime or nodiratime flag set and try another remount with the found flags.
+func (mounter *Mounter) bindMountSensitive(mounterPath string, mountCmd string, source string, target string, fstype string, bindOpts []string, bindRemountOpts []string, bindRemountOptsSensitive []string, mountFlags []string, systemdMountRequired bool) error {
+ err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindOpts, bindRemountOptsSensitive, mountFlags, systemdMountRequired)
+ if err != nil {
+ return err
+ }
+ err = mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindRemountOpts, bindRemountOptsSensitive, mountFlags, systemdMountRequired)
+ if inuserns.RunningInUserNS() {
+ if err == nil {
+ return nil
+ }
+ // Check if the source has ro, nodev, noexec, nosuid, noatime, relatime,
+ // nodiratime flag...
+ fixMountOpts, err := getUserNSBindMountOptions(source, unix.Statfs)
+ if err != nil {
+ return &os.PathError{Op: "statfs", Path: source, Err: err}
+ }
+ // ... and retry the mount with flags found above.
+ bindRemountOpts = append(bindRemountOpts, fixMountOpts...)
+ return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindRemountOpts, bindRemountOptsSensitive, mountFlags, systemdMountRequired)
+ } else {
+ return err
}
}
@@ -90,11 +185,7 @@ func (mounter *Mounter) MountSensitive(source string, target string, fstype stri
mounterPath := ""
bind, bindOpts, bindRemountOpts, bindRemountOptsSensitive := MakeBindOptsSensitive(options, sensitiveOptions)
if bind {
- err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindOpts, bindRemountOptsSensitive, nil /* mountFlags */, true)
- if err != nil {
- return err
- }
- return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindRemountOpts, bindRemountOptsSensitive, nil /* mountFlags */, true)
+ return mounter.bindMountSensitive(mounterPath, defaultMountCommand, source, target, fstype, bindOpts, bindRemountOpts, bindRemountOptsSensitive, nil /* mountFlags */, mounter.trySystemd)
}
// The list of filesystems that require containerized mounter on GCI image cluster
fsTypesNeedMounter := map[string]struct{}{
@@ -106,7 +197,7 @@ func (mounter *Mounter) MountSensitive(source string, target string, fstype stri
if _, ok := fsTypesNeedMounter[fstype]; ok {
mounterPath = mounter.mounterPath
}
- return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, options, sensitiveOptions, nil /* mountFlags */, true)
+ return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, options, sensitiveOptions, nil /* mountFlags */, mounter.trySystemd)
}
// MountSensitiveWithoutSystemd is the same as MountSensitive() but disable using systemd mount.
@@ -119,11 +210,7 @@ func (mounter *Mounter) MountSensitiveWithoutSystemdWithMountFlags(source string
mounterPath := ""
bind, bindOpts, bindRemountOpts, bindRemountOptsSensitive := MakeBindOptsSensitive(options, sensitiveOptions)
if bind {
- err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindOpts, bindRemountOptsSensitive, mountFlags, false)
- if err != nil {
- return err
- }
- return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindRemountOpts, bindRemountOptsSensitive, mountFlags, false)
+ return mounter.bindMountSensitive(mounterPath, defaultMountCommand, source, target, fstype, bindOpts, bindRemountOpts, bindRemountOptsSensitive, mountFlags, false)
}
// The list of filesystems that require containerized mounter on GCI image cluster
fsTypesNeedMounter := map[string]struct{}{
@@ -149,7 +236,7 @@ func (mounter *Mounter) doMount(mounterPath string, mountCmd string, source stri
mountCmd = mounterPath
}
- if mounter.withSystemd && systemdMountRequired {
+ if systemdMountRequired && mounter.hasSystemd() {
// Try to run mount via systemd-run --scope. This will escape the
// service where kubelet runs and any fuse daemons will be started in a
// specific scope. kubelet service than can be restarted without killing
@@ -223,6 +310,36 @@ func detectSystemd() bool {
return true
}
+// detectSafeNotMountedBehavior returns true if the umount implementation replies "not mounted"
+// when the specified path is not mounted. When not sure (permission errors, ...), it returns false.
+// When possible, we will trust umount's message and avoid doing our own mount point checks.
+// More info: https://github.com/util-linux/util-linux/blob/v2.2/mount/umount.c#L179
+func detectSafeNotMountedBehavior() bool {
+ return detectSafeNotMountedBehaviorWithExec(utilexec.New())
+}
+
+// detectSafeNotMountedBehaviorWithExec is for testing with FakeExec.
+func detectSafeNotMountedBehaviorWithExec(exec utilexec.Interface) bool {
+ // create a temp dir and try to umount it
+ path, err := os.MkdirTemp("", "kubelet-detect-safe-umount")
+ if err != nil {
+ klog.V(4).Infof("Cannot create temp dir to detect safe 'not mounted' behavior: %v", err)
+ return false
+ }
+ defer os.RemoveAll(path)
+ cmd := exec.Command("umount", path)
+ output, err := cmd.CombinedOutput()
+ if err != nil {
+ if strings.Contains(string(output), errNotMounted) {
+ klog.V(4).Infof("Detected umount with safe 'not mounted' behavior")
+ return true
+ }
+ klog.V(4).Infof("'umount %s' failed with: %v, output: %s", path, err, string(output))
+ }
+ klog.V(4).Infof("Detected umount with unsafe 'not mounted' behavior")
+ return false
+}
+
// MakeMountArgs makes the arguments to the mount(8) command.
// options MUST not contain sensitive material (like passwords).
func MakeMountArgs(source, target, fstype string, options []string) (mountArgs []string) {
@@ -290,20 +407,13 @@ func AddSystemdScopeSensitive(systemdRunPath, mountName, command string, args []
}
// Unmount unmounts the target.
+// If the mounter has safe "not mounted" behavior, no error will be returned when the target is not a mount point.
func (mounter *Mounter) Unmount(target string) error {
klog.V(4).Infof("Unmounting %s", target)
command := exec.Command("umount", target)
output, err := command.CombinedOutput()
if err != nil {
- if err.Error() == errNoChildProcesses {
- if command.ProcessState.Success() {
- // We don't consider errNoChildProcesses an error if the process itself succeeded (see - k/k issue #103753).
- return nil
- }
- // Rewrite err with the actual exit error of the process.
- err = &exec.ExitError{ProcessState: command.ProcessState}
- }
- return fmt.Errorf("unmount failed: %v\nUnmounting arguments: %s\nOutput: %s", err, target, string(output))
+ return checkUmountError(target, command, output, err, mounter.withSafeNotMountedBehavior)
}
return nil
}
@@ -311,11 +421,11 @@ func (mounter *Mounter) Unmount(target string) error {
// UnmountWithForce unmounts given target but will retry unmounting with force option
// after given timeout.
func (mounter *Mounter) UnmountWithForce(target string, umountTimeout time.Duration) error {
- err := tryUnmount(target, umountTimeout)
+ err := tryUnmount(target, mounter.withSafeNotMountedBehavior, umountTimeout)
if err != nil {
if err == context.DeadlineExceeded {
klog.V(2).Infof("Timed out waiting for unmount of %s, trying with -f", target)
- err = forceUmount(target)
+ err = forceUmount(target, mounter.withSafeNotMountedBehavior)
}
return err
}
@@ -327,14 +437,20 @@ func (*Mounter) List() ([]MountPoint, error) {
return ListProcMounts(procMountsPath)
}
-// IsLikelyNotMountPoint determines if a directory is not a mountpoint.
-// It is fast but not necessarily ALWAYS correct. If the path is in fact
-// a bind mount from one part of a mount to another it will not be detected.
-// It also can not distinguish between mountpoints and symbolic links.
-// mkdir /tmp/a /tmp/b; mount --bind /tmp/a /tmp/b; IsLikelyNotMountPoint("/tmp/b")
-// will return true. When in fact /tmp/b is a mount point. If this situation
-// is of interest to you, don't use this function...
-func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
+func statx(file string) (unix.Statx_t, error) {
+ var stat unix.Statx_t
+ if err := unix.Statx(unix.AT_FDCWD, file, unix.AT_STATX_DONT_SYNC, 0, &stat); err != nil {
+ if err == unix.ENOSYS {
+ return stat, errStatxNotSupport
+ }
+
+ return stat, err
+ }
+
+ return stat, nil
+}
+
+func (mounter *Mounter) isLikelyNotMountPointStat(file string) (bool, error) {
stat, err := os.Stat(file)
if err != nil {
return true, err
@@ -351,6 +467,56 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, nil
}
+func (mounter *Mounter) isLikelyNotMountPointStatx(file string) (bool, error) {
+ var stat, rootStat unix.Statx_t
+ var err error
+
+ if stat, err = statx(file); err != nil {
+ return true, err
+ }
+
+ if stat.Attributes_mask != 0 {
+ if stat.Attributes_mask&unix.STATX_ATTR_MOUNT_ROOT != 0 {
+ if stat.Attributes&unix.STATX_ATTR_MOUNT_ROOT != 0 {
+ // file is a mountpoint
+ return false, nil
+ } else {
+ // no need to check rootStat if unix.STATX_ATTR_MOUNT_ROOT supported
+ return true, nil
+ }
+ }
+ }
+
+ root := filepath.Dir(strings.TrimSuffix(file, "/"))
+ if rootStat, err = statx(root); err != nil {
+ return true, err
+ }
+
+ return (stat.Dev_major == rootStat.Dev_major && stat.Dev_minor == rootStat.Dev_minor), nil
+}
+
+// IsLikelyNotMountPoint determines if a directory is not a mountpoint.
+// It is fast but not necessarily ALWAYS correct. If the path is in fact
+// a bind mount from one part of a mount to another it will not be detected.
+// It also can not distinguish between mountpoints and symbolic links.
+// mkdir /tmp/a /tmp/b; mount --bind /tmp/a /tmp/b; IsLikelyNotMountPoint("/tmp/b")
+// will return true. When in fact /tmp/b is a mount point. If this situation
+// is of interest to you, don't use this function...
+func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
+ notMountPoint, err := mounter.isLikelyNotMountPointStatx(file)
+ if errors.Is(err, errStatxNotSupport) {
+ // fall back to isLikelyNotMountPointStat
+ return mounter.isLikelyNotMountPointStat(file)
+ }
+
+ return notMountPoint, err
+}
+
+// CanSafelySkipMountPointCheck relies on the detected behavior of umount when given a target that is not a mount point.
+func (mounter *Mounter) CanSafelySkipMountPointCheck() bool {
+ return mounter.withSafeNotMountedBehavior
+}
+
// GetMountRefs finds all mount references to pathname, returns a
// list of paths. Path could be a mountpoint or a normal
// directory (for bind mount).
@@ -387,13 +553,15 @@ func (mounter *SafeFormatAndMount) checkAndRepairFilesystem(source string) error
return NewMountError(HasFilesystemErrors, "'fsck' found errors on device %s but could not correct them: %s", source, string(out))
case isExitError && ee.ExitStatus() > fsckErrorsUncorrected:
klog.Infof("`fsck` error %s", string(out))
+ default:
+ klog.Warningf("fsck on device %s failed with error %v, output: %v", source, err, string(out))
}
}
return nil
}
// formatAndMount uses unix utils to format and mount the given disk
-func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error {
+func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string, formatOptions []string) error {
readOnly := false
for _, option := range options {
if option == "ro" {
@@ -445,15 +613,17 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target
source,
}
}
+ args = append(formatOptions, args...)
klog.Infof("Disk %q appears to be unformatted, attempting to format as type: %q with options: %v", source, fstype, args)
- output, err := mounter.Exec.Command("mkfs."+fstype, args...).CombinedOutput()
+
+ output, err := mounter.format(fstype, args)
if err != nil {
// Do not log sensitiveOptions only options
sensitiveOptionsLog := sanitizedOptionsForLogging(options, sensitiveOptions)
detailedErr := fmt.Sprintf("format of disk %q failed: type:(%q) target:(%q) options:(%q) errcode:(%v) output:(%v) ", source, fstype, target, sensitiveOptionsLog, err, string(output))
klog.Error(detailedErr)
- return NewMountError(FormatFailed, detailedErr)
+ return NewMountError(FormatFailed, "%s", detailedErr)
}
klog.Infof("Disk successfully formatted (mkfs): %s - %s %s", fstype, source, target)
@@ -461,7 +631,7 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target
if fstype != existingFormat {
// Verify that the disk is formatted with filesystem type we are expecting
mountErrorValue = FilesystemMismatch
- klog.Warningf("Configured to mount disk %s as %s but current format is %s, things might break", source, existingFormat, fstype)
+ klog.Warningf("Configured to mount disk %s as %s but current format is %s, things might break", source, fstype, existingFormat)
}
if !readOnly {
@@ -476,12 +646,35 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target
// Mount the disk
klog.V(4).Infof("Attempting to mount disk %s in %s format at %s", source, fstype, target)
if err := mounter.MountSensitive(source, target, fstype, options, sensitiveOptions); err != nil {
- return NewMountError(mountErrorValue, err.Error())
+ return NewMountError(mountErrorValue, "%s", err.Error())
}
return nil
}
+func (mounter *SafeFormatAndMount) format(fstype string, args []string) ([]byte, error) {
+ if mounter.formatSem != nil {
+ done := make(chan struct{})
+ defer close(done)
+
+ mounter.formatSem <- struct{}{}
+
+ go func() {
+ defer func() { <-mounter.formatSem }()
+
+ timeout := time.NewTimer(mounter.formatTimeout)
+ defer timeout.Stop()
+
+ select {
+ case <-done:
+ case <-timeout.C:
+ }
+ }()
+ }
+
+ return mounter.Exec.Command("mkfs."+fstype, args...).CombinedOutput()
+}
+
func getDiskFormat(exec utilexec.Interface, disk string) (string, error) {
args := []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", disk}
klog.V(4).Infof("Attempting to determine if disk %q is formatted using blkid with args: (%v)", disk, args)
@@ -541,7 +734,7 @@ func (mounter *SafeFormatAndMount) GetDiskFormat(disk string) (string, error) {
// ListProcMounts is shared with NsEnterMounter
func ListProcMounts(mountFilePath string) ([]MountPoint, error) {
- content, err := utilio.ConsistentRead(mountFilePath, maxListTries)
+ content, err := readMountInfo(mountFilePath)
if err != nil {
return nil, err
}
@@ -637,14 +830,71 @@ func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) {
return refs, nil
}
+// IsMountPoint determines if a file is a mountpoint.
+// It first detects bind & any other mountpoints using
+// MountedFast function. If the MountedFast function returns
+// sure as true and err as nil, then a mountpoint is detected
+// successfully. When an error is returned by MountedFast, the
+// following is true:
+// 1. All errors are returned with IsMountPoint as false
+// except os.IsPermission.
+// 2. When os.IsPermission is returned by MountedFast, List()
+// is called to confirm if the given file is a mountpoint are not.
+//
+// os.ErrNotExist should always be returned if a file does not exist
+// as callers have in past relied on this error and not fallback.
+//
+// When MountedFast returns sure as false and err as nil (eg: in
+// case of bindmounts on kernel version 5.10- ); mounter.List()
+// endpoint is called to enumerate all the mountpoints and check if
+// it is mountpoint match or not.
+func (mounter *Mounter) IsMountPoint(file string) (bool, error) {
+ isMnt, sure, isMntErr := mountinfo.MountedFast(file)
+ if sure && isMntErr == nil {
+ return isMnt, nil
+ }
+ if isMntErr != nil {
+ if errors.Is(isMntErr, fs.ErrNotExist) {
+ return false, fs.ErrNotExist
+ }
+ // We were not allowed to do the simple stat() check, e.g. on NFS with
+ // root_squash. Fall back to /proc/mounts check below when
+ // fs.ErrPermission is returned.
+ if !errors.Is(isMntErr, fs.ErrPermission) {
+ return false, isMntErr
+ }
+ }
+ // Resolve any symlinks in file, kernel would do the same and use the resolved path in /proc/mounts.
+ resolvedFile, err := filepath.EvalSymlinks(file)
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ return false, fs.ErrNotExist
+ }
+ return false, err
+ }
+
+ // check all mountpoints since MountedFast is not sure.
+ // is not reliable for some mountpoint types.
+ mountPoints, mountPointsErr := mounter.List()
+ if mountPointsErr != nil {
+ return false, mountPointsErr
+ }
+ for _, mp := range mountPoints {
+ if isMountPointMatch(mp, resolvedFile) {
+ return true, nil
+ }
+ }
+ return false, nil
+}
+
// tryUnmount calls plain "umount" and waits for unmountTimeout for it to finish.
-func tryUnmount(path string, unmountTimeout time.Duration) error {
- klog.V(4).Infof("Unmounting %s", path)
+func tryUnmount(target string, withSafeNotMountedBehavior bool, unmountTimeout time.Duration) error {
+ klog.V(4).Infof("Unmounting %s", target)
ctx, cancel := context.WithTimeout(context.Background(), unmountTimeout)
defer cancel()
- cmd := exec.CommandContext(ctx, "umount", path)
- out, cmderr := cmd.CombinedOutput()
+ command := exec.CommandContext(ctx, "umount", target)
+ output, err := command.CombinedOutput()
// CombinedOutput() does not return DeadlineExceeded, make sure it's
// propagated on timeout.
@@ -652,18 +902,34 @@ func tryUnmount(path string, unmountTimeout time.Duration) error {
return ctx.Err()
}
- if cmderr != nil {
- return fmt.Errorf("unmount failed: %v\nUnmounting arguments: %s\nOutput: %s", cmderr, path, string(out))
+ if err != nil {
+ return checkUmountError(target, command, output, err, withSafeNotMountedBehavior)
}
return nil
}
-func forceUmount(path string) error {
- cmd := exec.Command("umount", "-f", path)
- out, cmderr := cmd.CombinedOutput()
-
- if cmderr != nil {
- return fmt.Errorf("unmount failed: %v\nUnmounting arguments: %s\nOutput: %s", cmderr, path, string(out))
+func forceUmount(target string, withSafeNotMountedBehavior bool) error {
+ command := exec.Command("umount", "-f", target)
+ output, err := command.CombinedOutput()
+ if err != nil {
+ return checkUmountError(target, command, output, err, withSafeNotMountedBehavior)
}
return nil
}
+
+// checkUmountError checks a result of umount command and determine a return value.
+func checkUmountError(target string, command *exec.Cmd, output []byte, err error, withSafeNotMountedBehavior bool) error {
+ if err.Error() == errNoChildProcesses {
+ if command.ProcessState.Success() {
+ // We don't consider errNoChildProcesses an error if the process itself succeeded (see - k/k issue #103753).
+ return nil
+ }
+ // Rewrite err with the actual exit error of the process.
+ err = &exec.ExitError{ProcessState: command.ProcessState}
+ }
+ if withSafeNotMountedBehavior && strings.Contains(string(output), errNotMounted) {
+ klog.V(4).Infof("ignoring 'not mounted' error for %s", target)
+ return nil
+ }
+ return fmt.Errorf("unmount failed: %v\nUnmounting arguments: %s\nOutput: %s", err, target, string(output))
+}
diff --git a/vendor/k8s.io/mount-utils/mount_unsupported.go b/vendor/k8s.io/mount-utils/mount_unsupported.go
index 93ba9b2e3..0345904a0 100644
--- a/vendor/k8s.io/mount-utils/mount_unsupported.go
+++ b/vendor/k8s.io/mount-utils/mount_unsupported.go
@@ -74,15 +74,32 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, errUnsupported
}
+// CanSafelySkipMountPointCheck always returns false on unsupported platforms
+func (mounter *Mounter) CanSafelySkipMountPointCheck() bool {
+ return false
+}
+
+// IsMountPoint determines if a directory is a mountpoint.
+// It always returns an error on unsupported platforms.
+func (mounter *Mounter) IsMountPoint(file string) (bool, error) {
+ return false, errUnsupported
+}
+
// GetMountRefs always returns an error on unsupported platforms
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
return nil, errUnsupported
}
-func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error {
+func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string, formatOptions []string) error {
return mounter.Interface.Mount(source, target, fstype, options)
}
func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) {
return true, errUnsupported
}
+
+// IsMountPoint determines if a directory is a mountpoint.
+// It always returns an error on unsupported platforms.
+func (mounter *SafeFormatAndMount) IsMountPoint(file string) (bool, error) {
+ return false, errUnsupported
+}
diff --git a/vendor/k8s.io/mount-utils/mount_windows.go b/vendor/k8s.io/mount-utils/mount_windows.go
index 3286a69c4..9c8ad054f 100644
--- a/vendor/k8s.io/mount-utils/mount_windows.go
+++ b/vendor/k8s.io/mount-utils/mount_windows.go
@@ -82,11 +82,11 @@ func (mounter *Mounter) MountSensitive(source string, target string, fstype stri
if source == "tmpfs" {
klog.V(3).Infof("mounting source (%q), target (%q), with options (%q)", source, target, sanitizedOptionsForLogging)
- return os.MkdirAll(target, 0755)
+ return os.MkdirAll(target, 0o755)
}
parentDir := filepath.Dir(target)
- if err := os.MkdirAll(parentDir, 0755); err != nil {
+ if err := os.MkdirAll(parentDir, 0o755); err != nil {
return err
}
@@ -150,12 +150,12 @@ func (mounter *Mounter) MountSensitive(source string, target string, fstype stri
mklinkSource = mklinkSource + "\\"
}
- output, err := exec.Command("cmd", "/c", "mklink", "/D", target, mklinkSource).CombinedOutput()
+ err := os.Symlink(mklinkSource, target)
if err != nil {
- klog.Errorf("mklink failed: %v, source(%q) target(%q) output: %q", err, mklinkSource, target, string(output))
+ klog.Errorf("symlink failed: %v, source(%q) target(%q)", err, mklinkSource, target)
return err
}
- klog.V(2).Infof("mklink source(%q) on target(%q) successfully, output: %q", mklinkSource, target, string(output))
+ klog.V(2).Infof("symlink source(%q) on target(%q) successfully", mklinkSource, target)
return nil
}
@@ -164,7 +164,7 @@ func (mounter *Mounter) MountSensitive(source string, target string, fstype stri
// return (output, error)
func newSMBMapping(username, password, remotepath string) (string, error) {
if username == "" || password == "" || remotepath == "" {
- return "", fmt.Errorf("invalid parameter(username: %s, password: %s, remoteapth: %s)", username, sensitiveOptionsRemoved, remotepath)
+ return "", fmt.Errorf("invalid parameter(username: %s, password: %s, remotepath: %s)", username, sensitiveOptionsRemoved, remotepath)
}
// use PowerShell Environment Variables to store user input string to prevent command line injection
@@ -193,8 +193,8 @@ func isSMBMappingExist(remotepath string) bool {
// check whether remotepath is valid
// return (true, nil) if remotepath is valid
func isValidPath(remotepath string) (bool, error) {
- cmd := exec.Command("powershell", "/c", `Test-Path $Env:remoteapth`)
- cmd.Env = append(os.Environ(), fmt.Sprintf("remoteapth=%s", remotepath))
+ cmd := exec.Command("powershell", "/c", `Test-Path $Env:remotepath`)
+ cmd.Env = append(os.Environ(), fmt.Sprintf("remotepath=%s", remotepath))
output, err := cmd.CombinedOutput()
if err != nil {
return false, fmt.Errorf("returned output: %s, error: %v", string(output), err)
@@ -219,8 +219,9 @@ func removeSMBMapping(remotepath string) (string, error) {
func (mounter *Mounter) Unmount(target string) error {
klog.V(4).Infof("Unmount target (%q)", target)
target = NormalizeWindowsPath(target)
- if output, err := exec.Command("cmd", "/c", "rmdir", target).CombinedOutput(); err != nil {
- klog.Errorf("rmdir failed: %v, output: %q", err, string(output))
+
+ if err := os.Remove(target); err != nil {
+ klog.Errorf("removing directory %s failed: %v", target, err)
return err
}
return nil
@@ -244,6 +245,20 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, nil
}
+// CanSafelySkipMountPointCheck always returns false on Windows
+func (mounter *Mounter) CanSafelySkipMountPointCheck() bool {
+ return false
+}
+
+// IsMountPoint: determines if a directory is a mountpoint.
+func (mounter *Mounter) IsMountPoint(file string) (bool, error) {
+ isNotMnt, err := mounter.IsLikelyNotMountPoint(file)
+ if err != nil {
+ return false, err
+ }
+ return !isNotMnt, nil
+}
+
// GetMountRefs : empty implementation here since there is no place to query all mount points on Windows
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
windowsPath := NormalizeWindowsPath(pathname)
@@ -259,7 +274,7 @@ func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
return []string{pathname}, nil
}
-func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error {
+func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string, formatOptions []string) error {
// Try to mount the disk
klog.V(4).Infof("Attempting to formatAndMount disk: %s %s %s", fstype, source, target)
@@ -273,34 +288,40 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target
fstype = "NTFS"
}
- // format disk if it is unformatted(raw)
- cmd := fmt.Sprintf("Get-Disk -Number %s | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru"+
- " | New-Partition -UseMaximumSize | Format-Volume -FileSystem %s -Confirm:$false", source, fstype)
- if output, err := mounter.Exec.Command("powershell", "/c", cmd).CombinedOutput(); err != nil {
+ if len(formatOptions) > 0 {
+ return fmt.Errorf("diskMount: formatOptions are not supported on Windows")
+ }
+
+ cmdString := "Get-Disk -Number $env:source | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru" +
+ " | New-Partition -UseMaximumSize | Format-Volume -FileSystem $env:fstype -Confirm:$false"
+ cmd := mounter.Exec.Command("powershell", "/c", cmdString)
+ env := append(os.Environ(),
+ fmt.Sprintf("source=%s", source),
+ fmt.Sprintf("fstype=%s", fstype),
+ )
+ cmd.SetEnv(env)
+ klog.V(8).Infof("Executing command: %q", cmdString)
+ if output, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("diskMount: format disk failed, error: %v, output: %q", err, string(output))
}
klog.V(4).Infof("diskMount: Disk successfully formatted, disk: %q, fstype: %q", source, fstype)
- volumeIds, err := listVolumesOnDisk(source)
+ volumeIds, err := ListVolumesOnDisk(source)
if err != nil {
return err
}
driverPath := volumeIds[0]
- target = NormalizeWindowsPath(target)
- output, err := mounter.Exec.Command("cmd", "/c", "mklink", "/D", target, driverPath).CombinedOutput()
- if err != nil {
- klog.Errorf("mklink(%s, %s) failed: %v, output: %q", target, driverPath, err, string(output))
- return err
- }
- klog.V(2).Infof("formatAndMount disk(%s) fstype(%s) on(%s) with output(%s) successfully", driverPath, fstype, target, string(output))
- return nil
+ return mounter.MountSensitive(driverPath, target, fstype, options, sensitiveOptions)
}
// ListVolumesOnDisk - returns back list of volumes(volumeIDs) in the disk (requested in diskID).
-func listVolumesOnDisk(diskID string) (volumeIDs []string, err error) {
- cmd := fmt.Sprintf("(Get-Disk -DeviceId %s | Get-Partition | Get-Volume).UniqueId", diskID)
- output, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
- klog.V(4).Infof("listVolumesOnDisk id from %s: %s", diskID, string(output))
+func ListVolumesOnDisk(diskID string) (volumeIDs []string, err error) {
+ // If a Disk has multiple volumes, Get-Volume may not return items in the same order.
+ cmd := exec.Command("powershell", "/c", "(Get-Disk -DeviceId $env:diskID | Get-Partition | Get-Volume | Sort-Object -Property UniqueId).UniqueId")
+ cmd.Env = append(os.Environ(), fmt.Sprintf("diskID=%s", diskID))
+ klog.V(8).Infof("Executing command: %q", cmd.String())
+ output, err := cmd.CombinedOutput()
+ klog.V(4).Infof("ListVolumesOnDisk id from %s: %s", diskID, string(output))
if err != nil {
return []string{}, fmt.Errorf("error list volumes on disk. cmd: %s, output: %s, error: %v", cmd, string(output), err)
}
diff --git a/vendor/k8s.io/mount-utils/resizefs_linux.go b/vendor/k8s.io/mount-utils/resizefs_linux.go
index 929d061e5..3a5fa1be7 100644
--- a/vendor/k8s.io/mount-utils/resizefs_linux.go
+++ b/vendor/k8s.io/mount-utils/resizefs_linux.go
@@ -28,6 +28,10 @@ import (
utilexec "k8s.io/utils/exec"
)
+const (
+ blockDev = "blockdev"
+)
+
// ResizeFs Provides support for resizing file systems
type ResizeFs struct {
exec utilexec.Interface
@@ -41,7 +45,6 @@ func NewResizeFs(exec utilexec.Interface) *ResizeFs {
// Resize perform resize of file system
func (resizefs *ResizeFs) Resize(devicePath string, deviceMountPath string) (bool, error) {
format, err := getDiskFormat(resizefs.exec, devicePath)
-
if err != nil {
formatErr := fmt.Errorf("ResizeFS.Resize - error checking format for device %s: %v", devicePath, err)
return false, formatErr
@@ -74,7 +77,6 @@ func (resizefs *ResizeFs) extResize(devicePath string) (bool, error) {
resizeError := fmt.Errorf("resize of device %s failed: %v. resize2fs output: %s", devicePath, err, string(output))
return false, resizeError
-
}
func (resizefs *ResizeFs) xfsResize(deviceMountPath string) (bool, error) {
@@ -104,6 +106,17 @@ func (resizefs *ResizeFs) btrfsResize(deviceMountPath string) (bool, error) {
}
func (resizefs *ResizeFs) NeedResize(devicePath string, deviceMountPath string) (bool, error) {
+ // Do nothing if device is mounted as readonly
+ readonly, err := resizefs.getDeviceRO(devicePath)
+ if err != nil {
+ return false, err
+ }
+
+ if readonly {
+ klog.V(3).Infof("ResizeFs.needResize - no resize possible since filesystem %s is readonly", devicePath)
+ return false, nil
+ }
+
deviceSize, err := resizefs.getDeviceSize(devicePath)
if err != nil {
return false, err
@@ -146,8 +159,9 @@ func (resizefs *ResizeFs) NeedResize(devicePath string, deviceMountPath string)
}
return true, nil
}
+
func (resizefs *ResizeFs) getDeviceSize(devicePath string) (uint64, error) {
- output, err := resizefs.exec.Command("blockdev", "--getsize64", devicePath).CombinedOutput()
+ output, err := resizefs.exec.Command(blockDev, "--getsize64", devicePath).CombinedOutput()
outStr := strings.TrimSpace(string(output))
if err != nil {
return 0, fmt.Errorf("failed to read size of device %s: %s: %s", devicePath, err, outStr)
@@ -159,6 +173,22 @@ func (resizefs *ResizeFs) getDeviceSize(devicePath string) (uint64, error) {
return size, nil
}
+func (resizefs *ResizeFs) getDeviceRO(devicePath string) (bool, error) {
+ output, err := resizefs.exec.Command(blockDev, "--getro", devicePath).CombinedOutput()
+ outStr := strings.TrimSpace(string(output))
+ if err != nil {
+ return false, fmt.Errorf("failed to get readonly bit from device %s: %s: %s", devicePath, err, outStr)
+ }
+ switch outStr {
+ case "0":
+ return false, nil
+ case "1":
+ return true, nil
+ default:
+ return false, fmt.Errorf("Failed readonly device check. Expected 1 or 0, got '%s'", outStr)
+ }
+}
+
func (resizefs *ResizeFs) getExtSize(devicePath string) (uint64, uint64, error) {
output, err := resizefs.exec.Command("dumpe2fs", "-h", devicePath).CombinedOutput()
if err != nil {
diff --git a/vendor/k8s.io/mount-utils/resizefs_unsupported.go b/vendor/k8s.io/mount-utils/resizefs_unsupported.go
index 2d08211b4..88b8b2410 100644
--- a/vendor/k8s.io/mount-utils/resizefs_unsupported.go
+++ b/vendor/k8s.io/mount-utils/resizefs_unsupported.go
@@ -39,3 +39,8 @@ func NewResizeFs(exec utilexec.Interface) *ResizeFs {
func (resizefs *ResizeFs) Resize(devicePath string, deviceMountPath string) (bool, error) {
return false, fmt.Errorf("Resize is not supported for this build")
}
+
+// NeedResize check whether mounted volume needs resize
+func (resizefs *ResizeFs) NeedResize(devicePath string, deviceMountPath string) (bool, error) {
+ return false, fmt.Errorf("NeedResize is not supported for this build")
+}
diff --git a/vendor/k8s.io/utils/integer/integer.go b/vendor/k8s.io/utils/integer/integer.go
index e4e740cad..f64d64955 100644
--- a/vendor/k8s.io/utils/integer/integer.go
+++ b/vendor/k8s.io/utils/integer/integer.go
@@ -16,7 +16,10 @@ limitations under the License.
package integer
-// IntMax returns the maximum of the params
+import "math"
+
+// IntMax returns the maximum of the params.
+// Deprecated: for new code, use the max() builtin instead.
func IntMax(a, b int) int {
if b > a {
return b
@@ -24,7 +27,8 @@ func IntMax(a, b int) int {
return a
}
-// IntMin returns the minimum of the params
+// IntMin returns the minimum of the params.
+// Deprecated: for new code, use the min() builtin instead.
func IntMin(a, b int) int {
if b < a {
return b
@@ -32,7 +36,8 @@ func IntMin(a, b int) int {
return a
}
-// Int32Max returns the maximum of the params
+// Int32Max returns the maximum of the params.
+// Deprecated: for new code, use the max() builtin instead.
func Int32Max(a, b int32) int32 {
if b > a {
return b
@@ -40,7 +45,8 @@ func Int32Max(a, b int32) int32 {
return a
}
-// Int32Min returns the minimum of the params
+// Int32Min returns the minimum of the params.
+// Deprecated: for new code, use the min() builtin instead.
func Int32Min(a, b int32) int32 {
if b < a {
return b
@@ -48,7 +54,8 @@ func Int32Min(a, b int32) int32 {
return a
}
-// Int64Max returns the maximum of the params
+// Int64Max returns the maximum of the params.
+// Deprecated: for new code, use the max() builtin instead.
func Int64Max(a, b int64) int64 {
if b > a {
return b
@@ -56,7 +63,8 @@ func Int64Max(a, b int64) int64 {
return a
}
-// Int64Min returns the minimum of the params
+// Int64Min returns the minimum of the params.
+// Deprecated: for new code, use the min() builtin instead.
func Int64Min(a, b int64) int64 {
if b < a {
return b
@@ -65,9 +73,7 @@ func Int64Min(a, b int64) int64 {
}
// RoundToInt32 rounds floats into integer numbers.
+// Deprecated: use math.Round() and a cast directly.
func RoundToInt32(a float64) int32 {
- if a < 0 {
- return int32(a - 0.5)
- }
- return int32(a + 0.5)
+ return int32(math.Round(a))
}
diff --git a/vendor/k8s.io/utils/net/multi_listen.go b/vendor/k8s.io/utils/net/multi_listen.go
new file mode 100644
index 000000000..7cb7795be
--- /dev/null
+++ b/vendor/k8s.io/utils/net/multi_listen.go
@@ -0,0 +1,195 @@
+/*
+Copyright 2024 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 net
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "sync"
+)
+
+// connErrPair pairs conn and error which is returned by accept on sub-listeners.
+type connErrPair struct {
+ conn net.Conn
+ err error
+}
+
+// multiListener implements net.Listener
+type multiListener struct {
+ listeners []net.Listener
+ wg sync.WaitGroup
+
+ // connCh passes accepted connections, from child listeners to parent.
+ connCh chan connErrPair
+ // stopCh communicates from parent to child listeners.
+ stopCh chan struct{}
+}
+
+// compile time check to ensure *multiListener implements net.Listener
+var _ net.Listener = &multiListener{}
+
+// MultiListen returns net.Listener which can listen on and accept connections for
+// the given network on multiple addresses. Internally it uses stdlib to create
+// sub-listener and multiplexes connection requests using go-routines.
+// The network must be "tcp", "tcp4" or "tcp6".
+// It follows the semantics of net.Listen that primarily means:
+// 1. If the host is an unspecified/zero IP address with "tcp" network, MultiListen
+// listens on all available unicast and anycast IP addresses of the local system.
+// 2. Use "tcp4" or "tcp6" to exclusively listen on IPv4 or IPv6 family, respectively.
+// 3. The host can accept names (e.g, localhost) and it will create a listener for at
+// most one of the host's IP.
+func MultiListen(ctx context.Context, network string, addrs ...string) (net.Listener, error) {
+ var lc net.ListenConfig
+ return multiListen(
+ ctx,
+ network,
+ addrs,
+ func(ctx context.Context, network, address string) (net.Listener, error) {
+ return lc.Listen(ctx, network, address)
+ })
+}
+
+// multiListen implements MultiListen by consuming stdlib functions as dependency allowing
+// mocking for unit-testing.
+func multiListen(
+ ctx context.Context,
+ network string,
+ addrs []string,
+ listenFunc func(ctx context.Context, network, address string) (net.Listener, error),
+) (net.Listener, error) {
+ if !(network == "tcp" || network == "tcp4" || network == "tcp6") {
+ return nil, fmt.Errorf("network %q not supported", network)
+ }
+ if len(addrs) == 0 {
+ return nil, fmt.Errorf("no address provided to listen on")
+ }
+
+ ml := &multiListener{
+ connCh: make(chan connErrPair),
+ stopCh: make(chan struct{}),
+ }
+ for _, addr := range addrs {
+ l, err := listenFunc(ctx, network, addr)
+ if err != nil {
+ // close all the sub-listeners and exit
+ _ = ml.Close()
+ return nil, err
+ }
+ ml.listeners = append(ml.listeners, l)
+ }
+
+ for _, l := range ml.listeners {
+ ml.wg.Add(1)
+ go func(l net.Listener) {
+ defer ml.wg.Done()
+ for {
+ // Accept() is blocking, unless ml.Close() is called, in which
+ // case it will return immediately with an error.
+ conn, err := l.Accept()
+ // This assumes that ANY error from Accept() will terminate the
+ // sub-listener. We could maybe be more precise, but it
+ // doesn't seem necessary.
+ terminate := err != nil
+
+ select {
+ case ml.connCh <- connErrPair{conn: conn, err: err}:
+ case <-ml.stopCh:
+ // In case we accepted a connection AND were stopped, and
+ // this select-case was chosen, just throw away the
+ // connection. This avoids potentially blocking on connCh
+ // or leaking a connection.
+ if conn != nil {
+ _ = conn.Close()
+ }
+ terminate = true
+ }
+ // Make sure we don't loop on Accept() returning an error and
+ // the select choosing the channel case.
+ if terminate {
+ return
+ }
+ }
+ }(l)
+ }
+ return ml, nil
+}
+
+// Accept implements net.Listener. It waits for and returns a connection from
+// any of the sub-listener.
+func (ml *multiListener) Accept() (net.Conn, error) {
+ // wait for any sub-listener to enqueue an accepted connection
+ connErr, ok := <-ml.connCh
+ if !ok {
+ // The channel will be closed only when Close() is called on the
+ // multiListener. Closing of this channel implies that all
+ // sub-listeners are also closed, which causes a "use of closed
+ // network connection" error on their Accept() calls. We return the
+ // same error for multiListener.Accept() if multiListener.Close()
+ // has already been called.
+ return nil, fmt.Errorf("use of closed network connection")
+ }
+ return connErr.conn, connErr.err
+}
+
+// Close implements net.Listener. It will close all sub-listeners and wait for
+// the go-routines to exit.
+func (ml *multiListener) Close() error {
+ // Make sure this can be called repeatedly without explosions.
+ select {
+ case <-ml.stopCh:
+ return fmt.Errorf("use of closed network connection")
+ default:
+ }
+
+ // Tell all sub-listeners to stop.
+ close(ml.stopCh)
+
+ // Closing the listeners causes Accept() to immediately return an error in
+ // the sub-listener go-routines.
+ for _, l := range ml.listeners {
+ _ = l.Close()
+ }
+
+ // Wait for all the sub-listener go-routines to exit.
+ ml.wg.Wait()
+ close(ml.connCh)
+
+ // Drain any already-queued connections.
+ for connErr := range ml.connCh {
+ if connErr.conn != nil {
+ _ = connErr.conn.Close()
+ }
+ }
+ return nil
+}
+
+// Addr is an implementation of the net.Listener interface. It always returns
+// the address of the first listener. Callers should use conn.LocalAddr() to
+// obtain the actual local address of the sub-listener.
+func (ml *multiListener) Addr() net.Addr {
+ return ml.listeners[0].Addr()
+}
+
+// Addrs is like Addr, but returns the address for all registered listeners.
+func (ml *multiListener) Addrs() []net.Addr {
+ var ret []net.Addr
+ for _, l := range ml.listeners {
+ ret = append(ret, l.Addr())
+ }
+ return ret
+}
diff --git a/vendor/k8s.io/utils/ptr/OWNERS b/vendor/k8s.io/utils/ptr/OWNERS
new file mode 100644
index 000000000..0d6392752
--- /dev/null
+++ b/vendor/k8s.io/utils/ptr/OWNERS
@@ -0,0 +1,10 @@
+# See the OWNERS docs at https://go.k8s.io/owners
+
+approvers:
+- apelisse
+- stewart-yu
+- thockin
+reviewers:
+- apelisse
+- stewart-yu
+- thockin
diff --git a/vendor/k8s.io/utils/ptr/README.md b/vendor/k8s.io/utils/ptr/README.md
new file mode 100644
index 000000000..2ca8073dc
--- /dev/null
+++ b/vendor/k8s.io/utils/ptr/README.md
@@ -0,0 +1,3 @@
+# Pointer
+
+This package provides some functions for pointer-based operations.
diff --git a/vendor/k8s.io/utils/ptr/ptr.go b/vendor/k8s.io/utils/ptr/ptr.go
new file mode 100644
index 000000000..659ed3b9e
--- /dev/null
+++ b/vendor/k8s.io/utils/ptr/ptr.go
@@ -0,0 +1,73 @@
+/*
+Copyright 2023 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 ptr
+
+import (
+ "fmt"
+ "reflect"
+)
+
+// AllPtrFieldsNil tests whether all pointer fields in a struct are nil. This is useful when,
+// for example, an API struct is handled by plugins which need to distinguish
+// "no plugin accepted this spec" from "this spec is empty".
+//
+// This function is only valid for structs and pointers to structs. Any other
+// type will cause a panic. Passing a typed nil pointer will return true.
+func AllPtrFieldsNil(obj interface{}) bool {
+ v := reflect.ValueOf(obj)
+ if !v.IsValid() {
+ panic(fmt.Sprintf("reflect.ValueOf() produced a non-valid Value for %#v", obj))
+ }
+ if v.Kind() == reflect.Ptr {
+ if v.IsNil() {
+ return true
+ }
+ v = v.Elem()
+ }
+ for i := 0; i < v.NumField(); i++ {
+ if v.Field(i).Kind() == reflect.Ptr && !v.Field(i).IsNil() {
+ return false
+ }
+ }
+ return true
+}
+
+// To returns a pointer to the given value.
+func To[T any](v T) *T {
+ return &v
+}
+
+// Deref dereferences ptr and returns the value it points to if no nil, or else
+// returns def.
+func Deref[T any](ptr *T, def T) T {
+ if ptr != nil {
+ return *ptr
+ }
+ return def
+}
+
+// Equal returns true if both arguments are nil or both arguments
+// dereference to the same value.
+func Equal[T comparable](a, b *T) bool {
+ if (a == nil) != (b == nil) {
+ return false
+ }
+ if a == nil {
+ return true
+ }
+ return *a == *b
+}
diff --git a/vendor/k8s.io/utils/trace/trace.go b/vendor/k8s.io/utils/trace/trace.go
index 187eb5d8c..559aebb59 100644
--- a/vendor/k8s.io/utils/trace/trace.go
+++ b/vendor/k8s.io/utils/trace/trace.go
@@ -192,7 +192,7 @@ func (t *Trace) Log() {
t.endTime = &endTime
t.lock.Unlock()
// an explicit logging request should dump all the steps out at the higher level
- if t.parentTrace == nil { // We don't start logging until Log or LogIfLong is called on the root trace
+ if t.parentTrace == nil && klogV(2) { // We don't start logging until Log or LogIfLong is called on the root trace
t.logTrace()
}
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 4d3eb6e01..6e536481f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -49,7 +49,7 @@ github.com/cespare/xxhash/v2
# github.com/container-storage-interface/spec v1.8.0
## explicit; go 1.18
github.com/container-storage-interface/spec/lib/go/csi
-# github.com/davecgh/go-spew v1.1.1
+# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
## explicit
github.com/davecgh/go-spew/spew
# github.com/emicklei/go-restful/v3 v3.11.0
@@ -65,23 +65,25 @@ github.com/felixge/httpsnoop
# github.com/fsnotify/fsnotify v1.7.0
## explicit; go 1.17
github.com/fsnotify/fsnotify
+# github.com/fxamacker/cbor/v2 v2.7.0
+## explicit; go 1.17
+github.com/fxamacker/cbor/v2
# github.com/go-logr/logr v1.4.2
## explicit; go 1.18
github.com/go-logr/logr
github.com/go-logr/logr/funcr
-github.com/go-logr/logr/slogr
# github.com/go-logr/stdr v1.2.2
## explicit; go 1.16
github.com/go-logr/stdr
-# github.com/go-openapi/jsonpointer v0.19.6
-## explicit; go 1.13
+# github.com/go-openapi/jsonpointer v0.21.0
+## explicit; go 1.20
github.com/go-openapi/jsonpointer
# github.com/go-openapi/jsonreference v0.20.2
## explicit; go 1.13
github.com/go-openapi/jsonreference
github.com/go-openapi/jsonreference/internal
-# github.com/go-openapi/swag v0.22.4
-## explicit; go 1.18
+# github.com/go-openapi/swag v0.23.0
+## explicit; go 1.20
github.com/go-openapi/swag
# github.com/gogo/protobuf v1.3.2
## explicit; go 1.15
@@ -194,6 +196,12 @@ github.com/mailru/easyjson/jwriter
# github.com/matttproud/golang_protobuf_extensions v1.0.4
## explicit; go 1.9
github.com/matttproud/golang_protobuf_extensions/pbutil
+# github.com/moby/sys/mountinfo v0.7.2
+## explicit; go 1.17
+github.com/moby/sys/mountinfo
+# github.com/moby/sys/userns v0.1.0
+## explicit; go 1.21
+github.com/moby/sys/userns
# github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
## explicit
github.com/modern-go/concurrent
@@ -232,7 +240,7 @@ github.com/onsi/ginkgo/reporters/stenographer
github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable
github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty
github.com/onsi/ginkgo/types
-# github.com/onsi/gomega v1.34.2
+# github.com/onsi/gomega v1.35.1
## explicit; go 1.22
github.com/onsi/gomega
github.com/onsi/gomega/format
@@ -247,7 +255,7 @@ github.com/onsi/gomega/types
# github.com/pkg/errors v0.9.1
## explicit
github.com/pkg/errors
-# github.com/pmezard/go-difflib v1.0.0
+# github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
## explicit
github.com/pmezard/go-difflib/difflib
# github.com/prashanthpai/sunrpc v0.0.0-20210303180433-689a3880d90a
@@ -290,6 +298,9 @@ github.com/stretchr/objx
## explicit; go 1.17
github.com/stretchr/testify/assert
github.com/stretchr/testify/mock
+# github.com/x448/float16 v0.8.4
+## explicit; go 1.11
+github.com/x448/float16
# go.opencensus.io v0.24.0
## explicit; go 1.13
go.opencensus.io
@@ -636,14 +647,17 @@ k8s.io/api/storage/v1alpha1
k8s.io/api/storage/v1beta1
# k8s.io/apiextensions-apiserver v0.24.1
## explicit; go 1.16
-# k8s.io/apimachinery v0.26.0
-## explicit; go 1.19
+# k8s.io/apimachinery v0.32.0
+## explicit; go 1.23.0
+k8s.io/apimachinery/pkg/api/equality
k8s.io/apimachinery/pkg/api/errors
k8s.io/apimachinery/pkg/api/meta
k8s.io/apimachinery/pkg/api/resource
+k8s.io/apimachinery/pkg/api/validation
k8s.io/apimachinery/pkg/apis/meta/internalversion
k8s.io/apimachinery/pkg/apis/meta/v1
k8s.io/apimachinery/pkg/apis/meta/v1/unstructured
+k8s.io/apimachinery/pkg/apis/meta/v1/validation
k8s.io/apimachinery/pkg/apis/meta/v1beta1
k8s.io/apimachinery/pkg/conversion
k8s.io/apimachinery/pkg/conversion/queryparams
@@ -652,6 +666,8 @@ k8s.io/apimachinery/pkg/labels
k8s.io/apimachinery/pkg/runtime
k8s.io/apimachinery/pkg/runtime/schema
k8s.io/apimachinery/pkg/runtime/serializer
+k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct
+k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes
k8s.io/apimachinery/pkg/runtime/serializer/json
k8s.io/apimachinery/pkg/runtime/serializer/protobuf
k8s.io/apimachinery/pkg/runtime/serializer/recognizer
@@ -661,11 +677,13 @@ k8s.io/apimachinery/pkg/selection
k8s.io/apimachinery/pkg/types
k8s.io/apimachinery/pkg/util/cache
k8s.io/apimachinery/pkg/util/diff
+k8s.io/apimachinery/pkg/util/dump
k8s.io/apimachinery/pkg/util/errors
k8s.io/apimachinery/pkg/util/framer
k8s.io/apimachinery/pkg/util/intstr
k8s.io/apimachinery/pkg/util/json
k8s.io/apimachinery/pkg/util/managedfields
+k8s.io/apimachinery/pkg/util/managedfields/internal
k8s.io/apimachinery/pkg/util/mergepatch
k8s.io/apimachinery/pkg/util/naming
k8s.io/apimachinery/pkg/util/net
@@ -985,8 +1003,8 @@ k8s.io/client-go/util/workqueue
k8s.io/component-base/metrics
k8s.io/component-base/metrics/prometheusextension
k8s.io/component-base/version
-# k8s.io/klog/v2 v2.110.1
-## explicit; go 1.13
+# k8s.io/klog/v2 v2.130.1
+## explicit; go 1.18
k8s.io/klog/v2
k8s.io/klog/v2/internal/buffer
k8s.io/klog/v2/internal/clock
@@ -994,8 +1012,8 @@ k8s.io/klog/v2/internal/dbg
k8s.io/klog/v2/internal/serialize
k8s.io/klog/v2/internal/severity
k8s.io/klog/v2/internal/sloghandler
-# k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00
-## explicit; go 1.19
+# k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f
+## explicit; go 1.20
k8s.io/kube-openapi/pkg/cached
k8s.io/kube-openapi/pkg/common
k8s.io/kube-openapi/pkg/handler3
@@ -1005,15 +1023,15 @@ k8s.io/kube-openapi/pkg/schemaconv
k8s.io/kube-openapi/pkg/spec3
k8s.io/kube-openapi/pkg/util/proto
k8s.io/kube-openapi/pkg/validation/spec
-# k8s.io/mount-utils v0.24.1
-## explicit; go 1.16
+# k8s.io/mount-utils v0.32.0
+## explicit; go 1.23.0
k8s.io/mount-utils
# k8s.io/test-infra v0.0.0-20201007205216-b54c51c3a44a
## explicit; go 1.13
k8s.io/test-infra/prow/config/secret
k8s.io/test-infra/prow/logrusutil
k8s.io/test-infra/prow/version
-# k8s.io/utils v0.0.0-20230726121419-3b25d923346b
+# k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738
## explicit; go 1.18
k8s.io/utils/buffer
k8s.io/utils/clock
@@ -1024,6 +1042,7 @@ k8s.io/utils/internal/third_party/forked/golang/net
k8s.io/utils/io
k8s.io/utils/keymutex
k8s.io/utils/net
+k8s.io/utils/ptr
k8s.io/utils/strings/slices
k8s.io/utils/trace
# sigs.k8s.io/boskos v0.0.0-20201002225104-ae3497d24cd7
@@ -1038,17 +1057,19 @@ sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics
sigs.k8s.io/controller-runtime/pkg/internal/log
sigs.k8s.io/controller-runtime/pkg/log
sigs.k8s.io/controller-runtime/pkg/metrics
-# sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd
-## explicit; go 1.18
+# sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3
+## explicit; go 1.21
sigs.k8s.io/json
sigs.k8s.io/json/internal/golang/encoding/json
-# sigs.k8s.io/structured-merge-diff/v4 v4.4.1
+# sigs.k8s.io/structured-merge-diff/v4 v4.4.2
## explicit; go 1.13
sigs.k8s.io/structured-merge-diff/v4/fieldpath
+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.3.0
+# sigs.k8s.io/yaml v1.4.0
## explicit; go 1.12
sigs.k8s.io/yaml
+sigs.k8s.io/yaml/goyaml.v2
# k8s.io/client-go => k8s.io/client-go v0.26.0
diff --git a/vendor/sigs.k8s.io/json/Makefile b/vendor/sigs.k8s.io/json/Makefile
index 07b8bfa85..fb6cf040f 100644
--- a/vendor/sigs.k8s.io/json/Makefile
+++ b/vendor/sigs.k8s.io/json/Makefile
@@ -19,7 +19,7 @@ vet:
go vet sigs.k8s.io/json
@echo "checking for external dependencies"
- @deps=$$(go mod graph); \
+ @deps=$$(go list -f '{{ if not (or .Standard .Module.Main) }}{{.ImportPath}}{{ end }}' -deps sigs.k8s.io/json/... || true); \
if [ -n "$${deps}" ]; then \
echo "only stdlib dependencies allowed, found:"; \
echo "$${deps}"; \
diff --git a/vendor/sigs.k8s.io/json/OWNERS b/vendor/sigs.k8s.io/json/OWNERS
index 0fadafbdd..a08a434e6 100644
--- a/vendor/sigs.k8s.io/json/OWNERS
+++ b/vendor/sigs.k8s.io/json/OWNERS
@@ -2,5 +2,5 @@
approvers:
- deads2k
- - lavalamp
+ - jpbetz
- liggitt
diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go
index 6a13cf2df..d538ac119 100644
--- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go
+++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go
@@ -21,10 +21,10 @@ import (
// Unmarshal parses the JSON-encoded data and stores the result
// in the value pointed to by v. If v is nil or not a pointer,
-// Unmarshal returns an InvalidUnmarshalError.
+// Unmarshal returns an [InvalidUnmarshalError].
//
// Unmarshal uses the inverse of the encodings that
-// Marshal uses, allocating maps, slices, and pointers as necessary,
+// [Marshal] uses, allocating maps, slices, and pointers as necessary,
// with the following additional rules:
//
// To unmarshal JSON into a pointer, Unmarshal first handles the case of
@@ -33,28 +33,28 @@ import (
// the value pointed at by the pointer. If the pointer is nil, Unmarshal
// allocates a new value for it to point to.
//
-// To unmarshal JSON into a value implementing the Unmarshaler interface,
-// Unmarshal calls that value's UnmarshalJSON method, including
+// To unmarshal JSON into a value implementing [Unmarshaler],
+// Unmarshal calls that value's [Unmarshaler.UnmarshalJSON] method, including
// when the input is a JSON null.
-// Otherwise, if the value implements encoding.TextUnmarshaler
-// and the input is a JSON quoted string, Unmarshal calls that value's
-// UnmarshalText method with the unquoted form of the string.
+// Otherwise, if the value implements [encoding.TextUnmarshaler]
+// and the input is a JSON quoted string, Unmarshal calls
+// [encoding.TextUnmarshaler.UnmarshalText] with the unquoted form of the string.
//
// To unmarshal JSON into a struct, Unmarshal matches incoming object
-// keys to the keys used by Marshal (either the struct field name or its tag),
+// keys to the keys used by [Marshal] (either the struct field name or its tag),
// preferring an exact match but also accepting a case-insensitive match. By
// default, object keys which don't have a corresponding struct field are
-// ignored (see Decoder.DisallowUnknownFields for an alternative).
+// ignored (see [Decoder.DisallowUnknownFields] for an alternative).
//
// To unmarshal JSON into an interface value,
// Unmarshal stores one of these in the interface value:
//
-// bool, for JSON booleans
-// float64, for JSON numbers
-// string, for JSON strings
-// []interface{}, for JSON arrays
-// map[string]interface{}, for JSON objects
-// nil for JSON null
+// - bool, for JSON booleans
+// - float64, for JSON numbers
+// - string, for JSON strings
+// - []interface{}, for JSON arrays
+// - map[string]interface{}, for JSON objects
+// - nil for JSON null
//
// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
// to zero and then appends each element to the slice.
@@ -72,16 +72,15 @@ import (
// use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal
// reuses the existing map, keeping existing entries. Unmarshal then stores
// key-value pairs from the JSON object into the map. The map's key type must
-// either be any string type, an integer, implement json.Unmarshaler, or
-// implement encoding.TextUnmarshaler.
+// either be any string type, an integer, or implement [encoding.TextUnmarshaler].
//
-// If the JSON-encoded data contain a syntax error, Unmarshal returns a SyntaxError.
+// If the JSON-encoded data contain a syntax error, Unmarshal returns a [SyntaxError].
//
// If a JSON value is not appropriate for a given target type,
// or if a JSON number overflows the target type, Unmarshal
// skips that field and completes the unmarshaling as best it can.
// If no more serious errors are encountered, Unmarshal returns
-// an UnmarshalTypeError describing the earliest such error. In any
+// an [UnmarshalTypeError] describing the earliest such error. In any
// case, it's not guaranteed that all the remaining fields following
// the problematic one will be unmarshaled into the target object.
//
@@ -119,7 +118,7 @@ func Unmarshal(data []byte, v any, opts ...UnmarshalOpt) error {
// a JSON value. UnmarshalJSON must copy the JSON data
// if it wishes to retain the data after returning.
//
-// By convention, to approximate the behavior of Unmarshal itself,
+// By convention, to approximate the behavior of [Unmarshal] itself,
// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.
type Unmarshaler interface {
UnmarshalJSON([]byte) error
@@ -157,8 +156,8 @@ func (e *UnmarshalFieldError) Error() string {
return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String()
}
-// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
-// (The argument to Unmarshal must be a non-nil pointer.)
+// An InvalidUnmarshalError describes an invalid argument passed to [Unmarshal].
+// (The argument to [Unmarshal] must be a non-nil pointer.)
type InvalidUnmarshalError struct {
Type reflect.Type
}
@@ -573,17 +572,10 @@ func (d *decodeState) array(v reflect.Value) error {
break
}
- // Get element of array, growing if necessary.
+ // Expand slice length, growing the slice if necessary.
if v.Kind() == reflect.Slice {
- // Grow slice if necessary
if i >= v.Cap() {
- newcap := v.Cap() + v.Cap()/2
- if newcap < 4 {
- newcap = 4
- }
- newv := reflect.MakeSlice(v.Type(), v.Len(), newcap)
- reflect.Copy(newv, v)
- v.Set(newv)
+ v.Grow(1)
}
if i >= v.Len() {
v.SetLen(i + 1)
@@ -620,13 +612,11 @@ func (d *decodeState) array(v reflect.Value) error {
if i < v.Len() {
if v.Kind() == reflect.Array {
- // Array. Zero the rest.
- z := reflect.Zero(v.Type().Elem())
for ; i < v.Len(); i++ {
- v.Index(i).Set(z)
+ v.Index(i).SetZero() // zero remainder of array
}
} else {
- v.SetLen(i)
+ v.SetLen(i) // truncate the slice
}
}
if i == 0 && v.Kind() == reflect.Slice {
@@ -636,7 +626,7 @@ func (d *decodeState) array(v reflect.Value) error {
}
var nullLiteral = []byte("null")
-var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+var textUnmarshalerType = reflect.TypeFor[encoding.TextUnmarshaler]()
// object consumes an object from d.data[d.off-1:], decoding into v.
// The first byte ('{') of the object has been read already.
@@ -776,7 +766,7 @@ func (d *decodeState) object(v reflect.Value) error {
if !mapElem.IsValid() {
mapElem = reflect.New(elemType).Elem()
} else {
- mapElem.Set(reflect.Zero(elemType))
+ mapElem.SetZero()
}
subv = mapElem
if checkDuplicateField != nil {
@@ -784,28 +774,14 @@ func (d *decodeState) object(v reflect.Value) error {
}
d.appendStrictFieldStackKey(string(key))
} else {
- var f *field
- if i, ok := fields.nameIndex[string(key)]; ok {
- // Found an exact name match.
- f = &fields.list[i]
- if checkDuplicateField != nil {
- checkDuplicateField(i, f.name)
- }
- } else if !d.caseSensitive {
- // Fall back to the expensive case-insensitive
- // linear search.
- for i := range fields.list {
- ff := &fields.list[i]
- if ff.equalFold(ff.nameBytes, key) {
- f = ff
- if checkDuplicateField != nil {
- checkDuplicateField(i, f.name)
- }
- break
- }
- }
+ f := fields.byExactName[string(key)]
+ if f == nil && !d.caseSensitive {
+ f = fields.byFoldedName[string(foldName(key))]
}
if f != nil {
+ if checkDuplicateField != nil {
+ checkDuplicateField(f.listIndex, f.name)
+ }
subv = v
destring = f.quoted
for _, i := range f.index {
@@ -874,33 +850,35 @@ func (d *decodeState) object(v reflect.Value) error {
if v.Kind() == reflect.Map {
kt := t.Key()
var kv reflect.Value
- switch {
- case reflect.PointerTo(kt).Implements(textUnmarshalerType):
+ if reflect.PointerTo(kt).Implements(textUnmarshalerType) {
kv = reflect.New(kt)
if err := d.literalStore(item, kv, true); err != nil {
return err
}
kv = kv.Elem()
- case kt.Kind() == reflect.String:
- kv = reflect.ValueOf(key).Convert(kt)
- default:
+ } else {
switch kt.Kind() {
+ case reflect.String:
+ kv = reflect.New(kt).Elem()
+ kv.SetString(string(key))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
s := string(key)
n, err := strconv.ParseInt(s, 10, 64)
- if err != nil || reflect.Zero(kt).OverflowInt(n) {
+ if err != nil || kt.OverflowInt(n) {
d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
break
}
- kv = reflect.ValueOf(n).Convert(kt)
+ kv = reflect.New(kt).Elem()
+ kv.SetInt(n)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
s := string(key)
n, err := strconv.ParseUint(s, 10, 64)
- if err != nil || reflect.Zero(kt).OverflowUint(n) {
+ if err != nil || kt.OverflowUint(n) {
d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
break
}
- kv = reflect.ValueOf(n).Convert(kt)
+ kv = reflect.New(kt).Elem()
+ kv.SetUint(n)
default:
panic("json: Unexpected key type") // should never occur
}
@@ -950,12 +928,12 @@ func (d *decodeState) convertNumber(s string) (any, error) {
f, err := strconv.ParseFloat(s, 64)
if err != nil {
- return nil, &UnmarshalTypeError{Value: "number " + s, Type: reflect.TypeOf(0.0), Offset: int64(d.off)}
+ return nil, &UnmarshalTypeError{Value: "number " + s, Type: reflect.TypeFor[float64](), Offset: int64(d.off)}
}
return f, nil
}
-var numberType = reflect.TypeOf(Number(""))
+var numberType = reflect.TypeFor[Number]()
// literalStore decodes a literal stored in item into v.
//
@@ -965,7 +943,7 @@ var numberType = reflect.TypeOf(Number(""))
func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) error {
// Check for unmarshaler.
if len(item) == 0 {
- //Empty string given
+ // Empty string given.
d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
return nil
}
@@ -1012,7 +990,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
}
switch v.Kind() {
case reflect.Interface, reflect.Pointer, reflect.Map, reflect.Slice:
- v.Set(reflect.Zero(v.Type()))
+ v.SetZero()
// otherwise, ignore null for primitives/string
}
case 't', 'f': // true, false
@@ -1064,10 +1042,11 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
}
v.SetBytes(b[:n])
case reflect.String:
- if v.Type() == numberType && !isValidNumber(string(s)) {
+ t := string(s)
+ if v.Type() == numberType && !isValidNumber(t) {
return fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item)
}
- v.SetString(string(s))
+ v.SetString(t)
case reflect.Interface:
if v.NumMethod() == 0 {
v.Set(reflect.ValueOf(string(s)))
@@ -1083,13 +1062,12 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
}
panic(phasePanicMsg)
}
- s := string(item)
switch v.Kind() {
default:
if v.Kind() == reflect.String && v.Type() == numberType {
// s must be a valid number, because it's
// already been tokenized.
- v.SetString(s)
+ v.SetString(string(item))
break
}
if fromQuoted {
@@ -1097,7 +1075,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
}
d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())})
case reflect.Interface:
- n, err := d.convertNumber(s)
+ n, err := d.convertNumber(string(item))
if err != nil {
d.saveError(err)
break
@@ -1109,25 +1087,25 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
v.Set(reflect.ValueOf(n))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- n, err := strconv.ParseInt(s, 10, 64)
+ n, err := strconv.ParseInt(string(item), 10, 64)
if err != nil || v.OverflowInt(n) {
- d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
+ d.saveError(&UnmarshalTypeError{Value: "number " + string(item), Type: v.Type(), Offset: int64(d.readIndex())})
break
}
v.SetInt(n)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- n, err := strconv.ParseUint(s, 10, 64)
+ n, err := strconv.ParseUint(string(item), 10, 64)
if err != nil || v.OverflowUint(n) {
- d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
+ d.saveError(&UnmarshalTypeError{Value: "number " + string(item), Type: v.Type(), Offset: int64(d.readIndex())})
break
}
v.SetUint(n)
case reflect.Float32, reflect.Float64:
- n, err := strconv.ParseFloat(s, v.Type().Bits())
+ n, err := strconv.ParseFloat(string(item), v.Type().Bits())
if err != nil || v.OverflowFloat(n) {
- d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
+ d.saveError(&UnmarshalTypeError{Value: "number " + string(item), Type: v.Type(), Offset: int64(d.readIndex())})
break
}
v.SetFloat(n)
diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go
index 5b67251fb..eb73bff58 100644
--- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go
+++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go
@@ -12,12 +12,13 @@ package json
import (
"bytes"
+ "cmp"
"encoding"
"encoding/base64"
"fmt"
"math"
"reflect"
- "sort"
+ "slices"
"strconv"
"strings"
"sync"
@@ -28,29 +29,30 @@ import (
// Marshal returns the JSON encoding of v.
//
// Marshal traverses the value v recursively.
-// If an encountered value implements the Marshaler interface
-// and is not a nil pointer, Marshal calls its MarshalJSON method
-// to produce JSON. If no MarshalJSON method is present but the
-// value implements encoding.TextMarshaler instead, Marshal calls
-// its MarshalText method and encodes the result as a JSON string.
+// If an encountered value implements [Marshaler]
+// and is not a nil pointer, Marshal calls [Marshaler.MarshalJSON]
+// to produce JSON. If no [Marshaler.MarshalJSON] method is present but the
+// value implements [encoding.TextMarshaler] instead, Marshal calls
+// [encoding.TextMarshaler.MarshalText] and encodes the result as a JSON string.
// The nil pointer exception is not strictly necessary
// but mimics a similar, necessary exception in the behavior of
-// UnmarshalJSON.
+// [Unmarshaler.UnmarshalJSON].
//
// Otherwise, Marshal uses the following type-dependent default encodings:
//
// Boolean values encode as JSON booleans.
//
-// Floating point, integer, and Number values encode as JSON numbers.
+// Floating point, integer, and [Number] values encode as JSON numbers.
+// NaN and +/-Inf values will return an [UnsupportedValueError].
//
// String values encode as JSON strings coerced to valid UTF-8,
// replacing invalid bytes with the Unicode replacement rune.
// So that the JSON will be safe to embed inside HTML