diff --git a/go.mod b/go.mod
index d8be74454..a15790d63 100644
--- a/go.mod
+++ b/go.mod
@@ -1,8 +1,6 @@
module github.com/NVIDIA/k8s-device-plugin
-go 1.24.0
-
-toolchain go1.24.5
+go 1.25.0
require (
github.com/NVIDIA/go-gpuallocator v0.6.0
@@ -18,16 +16,16 @@ require (
github.com/stretchr/testify v1.11.1
github.com/urfave/cli/v2 v2.27.7
golang.org/x/mod v0.29.0
- google.golang.org/grpc v1.69.0
- k8s.io/api v0.32.3
- k8s.io/apimachinery v0.32.3
- k8s.io/client-go v0.32.3
+ google.golang.org/grpc v1.75.1
+ k8s.io/api v0.34.1
+ k8s.io/apimachinery v0.34.1
+ k8s.io/client-go v0.34.1
k8s.io/klog/v2 v2.130.1
- k8s.io/kubelet v0.32.3
- k8s.io/mount-utils v0.32.3
- sigs.k8s.io/node-feature-discovery v0.17.3
+ k8s.io/kubelet v0.34.1
+ k8s.io/mount-utils v0.34.1
+ sigs.k8s.io/node-feature-discovery v0.18.3
sigs.k8s.io/node-feature-discovery/api/nfd v0.17.3
- sigs.k8s.io/yaml v1.4.0
+ sigs.k8s.io/yaml v1.6.0
tags.cncf.io/container-device-interface v1.0.1
tags.cncf.io/container-device-interface/specs-go v1.0.0
)
@@ -35,47 +33,47 @@ require (
require (
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
- github.com/emicklei/go-restful/v3 v3.11.3 // indirect
- github.com/fxamacker/cbor/v2 v2.7.0 // indirect
- github.com/go-logr/logr v1.4.2 // indirect
+ github.com/emicklei/go-restful/v3 v3.12.2 // indirect
+ github.com/fxamacker/cbor/v2 v2.9.0 // indirect
+ github.com/go-logr/logr v1.4.3 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
- github.com/golang/protobuf v1.5.4 // indirect
- github.com/google/gnostic-models v0.6.8 // indirect
+ github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
- github.com/google/gofuzz v1.2.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // 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/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opencontainers/runtime-spec v1.2.1 // indirect
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
+ github.com/spf13/pflag v1.0.9 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
- golang.org/x/net v0.38.0 // indirect
- golang.org/x/oauth2 v0.27.0 // indirect
+ go.yaml.in/yaml/v2 v2.4.2 // indirect
+ go.yaml.in/yaml/v3 v3.0.4 // indirect
+ golang.org/x/net v0.44.0 // indirect
+ golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sys v0.37.0 // indirect
- golang.org/x/term v0.30.0 // indirect
- golang.org/x/text v0.23.0 // indirect
- golang.org/x/time v0.8.0 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
- google.golang.org/protobuf v1.35.1 // indirect
+ golang.org/x/term v0.35.0 // indirect
+ golang.org/x/text v0.29.0 // indirect
+ golang.org/x/time v0.13.0 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
+ google.golang.org/protobuf v1.36.8 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
- k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
- sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
- sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
+ k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
+ k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
+ sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
+ sigs.k8s.io/randfill v1.0.0 // indirect
+ sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
)
diff --git a/go.sum b/go.sum
index fff043c14..d895decee 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,5 @@
+github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
+github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/NVIDIA/go-gpuallocator v0.6.0 h1:2PA2swx59gJYREPkZNTGtyCP6Pnz3WEgnYsXlRkyvkk=
github.com/NVIDIA/go-gpuallocator v0.6.0/go.mod h1:c+Yspg+/QxWOmoSQeuI48Z/7nS+mMPtxyj1NYUTwewY=
github.com/NVIDIA/go-nvlib v0.8.1 h1:OPEHVvn3zcV5OXB68A7WRpeCnYMRSPl7LdeJH/d3gZI=
@@ -14,14 +16,14 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/emicklei/go-restful/v3 v3.11.3 h1:yagOQz/38xJmcNeZJtrUcKjkHRltIaIFXKWeG1SkWGE=
-github.com/emicklei/go-restful/v3 v3.11.3/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
+github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
-github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
-github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
-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/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
+github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
@@ -36,16 +38,13 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
-github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
-github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
+github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
-github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
-github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY=
+github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U=
github.com/google/renameio v1.0.1 h1:Lh/jXZmvZxb0BBeSY5VKEfidcbcbenKjZFzM/q0fSeU=
github.com/google/renameio v1.0.1/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -71,20 +70,19 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
+github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
-github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
-github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
-github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
+github.com/onsi/ginkgo/v2 v2.25.3 h1:Ty8+Yi/ayDAGtk4XxmmfUy4GabvM+MegeB4cDLRi6nw=
+github.com/onsi/ginkgo/v2 v2.25.3/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE=
+github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
+github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
@@ -100,16 +98,18 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
-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/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
+github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -133,21 +133,29 @@ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGC
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
-go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
-go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
-go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
-go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
-go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
-go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
-go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
-go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
-go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
+go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
+go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
+go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
+go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
+go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
+go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
+go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
+go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
+go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
+go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
+go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
+go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
+go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
+go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-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/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
@@ -156,10 +164,10 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
-golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
-golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
-golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
+golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
+golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
+golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
+golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -171,14 +179,14 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
-golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
-golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
+golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
+golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
-golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
-golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
-golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
+golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
+golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI=
+golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -189,12 +197,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
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=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
-google.golang.org/grpc v1.69.0 h1:quSiOM1GJPmPH5XtU+BCoVXcDVJJAzNcoyfC2cCjGkI=
-google.golang.org/grpc v1.69.0/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
-google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
-google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
+gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
+gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
+google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
+google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
+google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
+google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@@ -206,32 +216,34 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls=
-k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k=
-k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
-k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
-k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU=
-k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY=
+k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM=
+k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk=
+k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4=
+k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
+k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY=
+k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8=
k8s.io/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-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
-k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
-k8s.io/kubelet v0.32.3 h1:B9HzW4yB67flx8tN2FYuDwZvxnmK3v5EjxxFvOYjmc8=
-k8s.io/kubelet v0.32.3/go.mod h1:yyAQSCKC+tjSlaFw4HQG7Jein+vo+GeKBGdXdQGvL1U=
-k8s.io/mount-utils v0.32.3 h1:ZPXXHblfBhYP89OnaozpFg9Ojl6HhDfxBLcdWNkaxW8=
-k8s.io/mount-utils v0.32.3/go.mod h1:Kun5c2svjAPx0nnvJKYQWhfeNW+O0EpzHgRhDcYoSY0=
-k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
-k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-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/node-feature-discovery v0.17.3 h1:CArk8De9LBP5bj3Z6Bz/mpnC8kDNfBhDAu0xJp4u/A8=
-sigs.k8s.io/node-feature-discovery v0.17.3/go.mod h1:N7lJLSoLzbTbliRtfBLXf12av2MjBiFM8dEaq8FESag=
+k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=
+k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
+k8s.io/kubelet v0.34.1 h1:doAaTA9/Yfzbdq/u/LveZeONp96CwX9giW6b+oHn4m4=
+k8s.io/kubelet v0.34.1/go.mod h1:PtV3Ese8iOM19gSooFoQT9iyRisbmJdAPuDImuccbbA=
+k8s.io/mount-utils v0.34.1 h1:zMBEFav8Rxwm54S8srzy5FxAc4KQ3X4ZcjnqTCzHmZk=
+k8s.io/mount-utils v0.34.1/go.mod h1:MIjjYlqJ0ziYQg0MO09kc9S96GIcMkhF/ay9MncF0GA=
+k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
+k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
+sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
+sigs.k8s.io/node-feature-discovery v0.18.3 h1:q5/qpyxrasI/F6838lflFNGAUszpMNRuFwornPLYdxQ=
+sigs.k8s.io/node-feature-discovery v0.18.3/go.mod h1:E1TicxB7ndDiZvQdtG6Gx6VjoDJvegXqU7e5dCTUT7s=
sigs.k8s.io/node-feature-discovery/api/nfd v0.17.3 h1:BJMNJ5ggnmlvzsANrxk6xPZISw1HSY0o7gL55EYu4Xc=
sigs.k8s.io/node-feature-discovery/api/nfd v0.17.3/go.mod h1:XzGgUqDUyV/X+qkXEwG+CgfTUUeZix5iuobsmLoT0Ck=
-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/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
-sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
+sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
+sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
+sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
+sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
+sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
+sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
tags.cncf.io/container-device-interface v1.0.1 h1:KqQDr4vIlxwfYh0Ed/uJGVgX+CHAkahrgabg6Q8GYxc=
tags.cncf.io/container-device-interface v1.0.1/go.mod h1:JojJIOeW3hNbcnOH2q0NrWNha/JuHoDZcmYxAZwb2i0=
tags.cncf.io/container-device-interface/specs-go v1.0.0 h1:8gLw29hH1ZQP9K1YtAzpvkHCjjyIxHZYzBAvlQ+0vD8=
diff --git a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md
index e8c65d0f6..6f24dfff5 100644
--- a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md
+++ b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md
@@ -1,5 +1,22 @@
# Change history of go-restful
+## [v3.12.2] - 2025-02-21
+
+- allow empty payloads in post,put,patch, issue #580 ( thanks @liggitt, Jordan Liggitt)
+
+## [v3.12.1] - 2024-05-28
+
+- fix misroute when dealing multiple webservice with regex (#549) (thanks Haitao Chen)
+
+## [v3.12.0] - 2024-03-11
+
+- add Flush method #529 (#538)
+- fix: Improper handling of empty POST requests (#543)
+
+## [v3.11.3] - 2024-01-09
+
+- better not have 2 tags on one commit
+
## [v3.11.1, v3.11.2] - 2024-01-09
- fix by restoring custom JSON handler functions (Mike Beaumont #540)
diff --git a/vendor/github.com/emicklei/go-restful/v3/README.md b/vendor/github.com/emicklei/go-restful/v3/README.md
index 95a05a089..3fb40d198 100644
--- a/vendor/github.com/emicklei/go-restful/v3/README.md
+++ b/vendor/github.com/emicklei/go-restful/v3/README.md
@@ -2,9 +2,8 @@ go-restful
==========
package for building REST-style Web Services using Google Go
-[](https://travis-ci.org/emicklei/go-restful)
[](https://goreportcard.com/report/github.com/emicklei/go-restful)
-[](https://pkg.go.dev/github.com/emicklei/go-restful)
+[](https://pkg.go.dev/github.com/emicklei/go-restful/v3)
[](https://codecov.io/gh/emicklei/go-restful)
- [Code examples use v3](https://github.com/emicklei/go-restful/tree/v3/examples)
diff --git a/vendor/github.com/emicklei/go-restful/v3/compress.go b/vendor/github.com/emicklei/go-restful/v3/compress.go
index 1ff239f99..80adf55fd 100644
--- a/vendor/github.com/emicklei/go-restful/v3/compress.go
+++ b/vendor/github.com/emicklei/go-restful/v3/compress.go
@@ -49,6 +49,16 @@ func (c *CompressingResponseWriter) CloseNotify() <-chan bool {
return c.writer.(http.CloseNotifier).CloseNotify()
}
+// Flush is part of http.Flusher interface. Noop if the underlying writer doesn't support it.
+func (c *CompressingResponseWriter) Flush() {
+ flusher, ok := c.writer.(http.Flusher)
+ if !ok {
+ // writer doesn't support http.Flusher interface
+ return
+ }
+ flusher.Flush()
+}
+
// Close the underlying compressor
func (c *CompressingResponseWriter) Close() error {
if c.isCompressorClosed() {
diff --git a/vendor/github.com/emicklei/go-restful/v3/curly.go b/vendor/github.com/emicklei/go-restful/v3/curly.go
index ba1fc5d5f..6fd2bcd5a 100644
--- a/vendor/github.com/emicklei/go-restful/v3/curly.go
+++ b/vendor/github.com/emicklei/go-restful/v3/curly.go
@@ -46,10 +46,10 @@ func (c CurlyRouter) SelectRoute(
// selectRoutes return a collection of Route from a WebService that matches the path tokens from the request.
func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes {
candidates := make(sortableCurlyRoutes, 0, 8)
- for _, each := range ws.routes {
- matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens, each.hasCustomVerb)
+ for _, eachRoute := range ws.routes {
+ matches, paramCount, staticCount := c.matchesRouteByPathTokens(eachRoute.pathParts, requestTokens, eachRoute.hasCustomVerb)
if matches {
- candidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers?
+ candidates.add(curlyRoute{eachRoute, paramCount, staticCount}) // TODO make sure Routes() return pointers?
}
}
sort.Sort(candidates)
@@ -72,7 +72,7 @@ func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []strin
return false, 0, 0
}
requestToken := requestTokens[i]
- if routeHasCustomVerb && hasCustomVerb(routeToken){
+ if routeHasCustomVerb && hasCustomVerb(routeToken) {
if !isMatchCustomVerb(routeToken, requestToken) {
return false, 0, 0
}
@@ -129,44 +129,52 @@ func (c CurlyRouter) detectRoute(candidateRoutes sortableCurlyRoutes, httpReques
// detectWebService returns the best matching webService given the list of path tokens.
// see also computeWebserviceScore
func (c CurlyRouter) detectWebService(requestTokens []string, webServices []*WebService) *WebService {
- var best *WebService
+ var bestWs *WebService
score := -1
- for _, each := range webServices {
- matches, eachScore := c.computeWebserviceScore(requestTokens, each.pathExpr.tokens)
+ for _, eachWS := range webServices {
+ matches, eachScore := c.computeWebserviceScore(requestTokens, eachWS.pathExpr.tokens)
if matches && (eachScore > score) {
- best = each
+ bestWs = eachWS
score = eachScore
}
}
- return best
+ return bestWs
}
// computeWebserviceScore returns whether tokens match and
// the weighted score of the longest matching consecutive tokens from the beginning.
-func (c CurlyRouter) computeWebserviceScore(requestTokens []string, tokens []string) (bool, int) {
- if len(tokens) > len(requestTokens) {
+func (c CurlyRouter) computeWebserviceScore(requestTokens []string, routeTokens []string) (bool, int) {
+ if len(routeTokens) > len(requestTokens) {
return false, 0
}
score := 0
- for i := 0; i < len(tokens); i++ {
- each := requestTokens[i]
- other := tokens[i]
- if len(each) == 0 && len(other) == 0 {
+ for i := 0; i < len(routeTokens); i++ {
+ eachRequestToken := requestTokens[i]
+ eachRouteToken := routeTokens[i]
+ if len(eachRequestToken) == 0 && len(eachRouteToken) == 0 {
score++
continue
}
- if len(other) > 0 && strings.HasPrefix(other, "{") {
+ if len(eachRouteToken) > 0 && strings.HasPrefix(eachRouteToken, "{") {
// no empty match
- if len(each) == 0 {
+ if len(eachRequestToken) == 0 {
return false, score
}
- score += 1
+ score++
+
+ if colon := strings.Index(eachRouteToken, ":"); colon != -1 {
+ // match by regex
+ matchesToken, _ := c.regularMatchesPathToken(eachRouteToken, colon, eachRequestToken)
+ if matchesToken {
+ score++ // extra score for regex match
+ }
+ }
} else {
// not a parameter
- if each != other {
+ if eachRequestToken != eachRouteToken {
return false, score
}
- score += (len(tokens) - i) * 10 //fuzzy
+ score += (len(routeTokens) - i) * 10 //fuzzy
}
}
return true, score
diff --git a/vendor/github.com/emicklei/go-restful/v3/jsr311.go b/vendor/github.com/emicklei/go-restful/v3/jsr311.go
index 07a0c91e9..7f04bd905 100644
--- a/vendor/github.com/emicklei/go-restful/v3/jsr311.go
+++ b/vendor/github.com/emicklei/go-restful/v3/jsr311.go
@@ -65,7 +65,7 @@ func (RouterJSR311) extractParams(pathExpr *pathExpression, matches []string) ma
return params
}
-// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2
+// https://download.oracle.com/otndocs/jcp/jaxrs-1.1-mrel-eval-oth-JSpec/
func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*Route, error) {
candidates := make([]*Route, 0, 8)
for i, each := range routes {
@@ -126,9 +126,7 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R
if trace {
traceLogger.Printf("no Route found (from %d) that matches HTTP Content-Type: %s\n", len(previous), contentType)
}
- if httpRequest.ContentLength > 0 {
- return nil, NewError(http.StatusUnsupportedMediaType, "415: Unsupported Media Type")
- }
+ return nil, NewError(http.StatusUnsupportedMediaType, "415: Unsupported Media Type")
}
// accept
@@ -151,20 +149,9 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R
for _, candidate := range previous {
available = append(available, candidate.Produces...)
}
- // if POST,PUT,PATCH without body
- method, length := httpRequest.Method, httpRequest.Header.Get("Content-Length")
- if (method == http.MethodPost ||
- method == http.MethodPut ||
- method == http.MethodPatch) && length == "" {
- return nil, NewError(
- http.StatusUnsupportedMediaType,
- fmt.Sprintf("415: Unsupported Media Type\n\nAvailable representations: %s", strings.Join(available, ", ")),
- )
- }
return nil, NewError(
http.StatusNotAcceptable,
- fmt.Sprintf("406: Not Acceptable\n\nAvailable representations: %s", strings.Join(available, ", ")),
- )
+ fmt.Sprintf("406: Not Acceptable\n\nAvailable representations: %s", strings.Join(available, ", ")))
}
// return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil
return candidates[0], nil
diff --git a/vendor/github.com/emicklei/go-restful/v3/route.go b/vendor/github.com/emicklei/go-restful/v3/route.go
index 306c44be7..a2056e2ac 100644
--- a/vendor/github.com/emicklei/go-restful/v3/route.go
+++ b/vendor/github.com/emicklei/go-restful/v3/route.go
@@ -111,6 +111,8 @@ func (r Route) matchesAccept(mimeTypesWithQuality string) bool {
}
// Return whether this Route can consume content with a type specified by mimeTypes (can be empty).
+// If the route does not specify Consumes then return true (*/*).
+// If no content type is set then return true for GET,HEAD,OPTIONS,DELETE and TRACE.
func (r Route) matchesContentType(mimeTypes string) bool {
if len(r.Consumes) == 0 {
diff --git a/vendor/github.com/fxamacker/cbor/v2/README.md b/vendor/github.com/fxamacker/cbor/v2/README.md
index af0a79507..d072b81c7 100644
--- a/vendor/github.com/fxamacker/cbor/v2/README.md
+++ b/vendor/github.com/fxamacker/cbor/v2/README.md
@@ -1,30 +1,31 @@
-# CBOR Codec in Go
-
-
+
CBOR Codec 
[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).
+`fxamacker/cbor` is used in projects by Arm Ltd., EdgeX Foundry, Flow Foundation, Fraunhofer‑AISEC, IBM, Kubernetes[*](https://github.com/search?q=org%3Akubernetes%20fxamacker%2Fcbor&type=code), Let's Encrypt, Linux Foundation, Microsoft, Oasis Protocol, Red Hat[*](https://github.com/search?q=org%3Aopenshift+fxamacker%2Fcbor&type=code), Tailscale[*](https://github.com/search?q=org%3Atailscale+fxamacker%2Fcbor&type=code), Veraison[*](https://github.com/search?q=org%3Averaison+fxamacker%2Fcbor&type=code), [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.
+See [Quick Start](#quick-start) and [Releases](https://github.com/fxamacker/cbor/releases/). 🆕 `UnmarshalFirst` and `DiagnoseFirst` can decode CBOR Sequences. `MarshalToBuffer` and `UserBufferEncMode` accepts user-specified buffer.
## fxamacker/cbor
[](https://github.com/fxamacker/cbor/actions?query=workflow%3Aci)
-[](https://github.com/fxamacker/cbor/actions?query=workflow%3A%22cover+%E2%89%A596%25%22)
+[](https://github.com/fxamacker/cbor/actions?query=workflow%3A%22cover+%E2%89%A597%25%22)
[](https://github.com/fxamacker/cbor/actions/workflows/codeql-analysis.yml)
[](#fuzzing-and-code-coverage)
[](https://goreportcard.com/report/github.com/fxamacker/cbor)
+[](https://github.com/fxamacker/cbor#fuzzing-and-code-coverage)
`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.
+API is mostly same as `encoding/json`, plus interfaces that simplify concurrency and CBOR options.
+
Design balances trade-offs between security, speed, concurrency, encoded data size, usability, etc.
-Highlights
+ 🔎 Highlights
__🚀 Speed__
@@ -38,7 +39,7 @@ Codec passed multiple confidential security assessments in 2022. No vulnerabili
__🗜️ Data Size__
-Struct tags (`toarray`, `keyasint`, `omitempty`) automatically reduce size of encoded structs. Encoding optionally shrinks float64→32→16 when values fit.
+Struct tag options (`toarray`, `keyasint`, `omitempty`, `omitzero`) and field tag "-" automatically reduce size of encoded structs. Encoding optionally shrinks float64→32→16 when values fit.
__:jigsaw: Usability__
@@ -58,164 +59,205 @@ Features include CBOR [extension points](https://www.rfc-editor.org/rfc/rfc8949.
`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:
+Notably, `fxamacker/cbor` is fast at rejecting malformed CBOR data.
+
+> [!NOTE]
+> Benchmarks rejecting 10 bytes of malicious CBOR data decoding to `[]byte`:
+>
+> | Codec | Speed (ns/op) | Memory | Allocs |
+> | :---- | ------------: | -----: | -----: |
+> | fxamacker/cbor 2.7.0 | 47 ± 7% | 32 B/op | 2 allocs/op |
+> | ugorji/go 1.2.12 | 5878187 ± 3% | 67111556 B/op | 13 allocs/op |
+>
+> Faster hardware (overclocked DDR4 or DDR5) can reduce speed difference.
+>
+> 🔎 Benchmark details
+>
+> Latest comparison for decoding CBOR data to Go `[]byte`:
+> - Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}`
+> - go1.22.7, linux/amd64, i5-13600K (DDR4-2933, disabled e-cores)
+> - 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
+>
+>
+
+In contrast, some codecs can crash or use excessive resources while decoding bad data.
+
+> [!WARNING]
+> Go's `encoding/gob` is [not designed to be hardened against adversarial inputs](https://pkg.go.dev/encoding/gob#hdr-Security).
+>
+> 🔎 gob fatal error (out of memory) 💥 decoding 181 bytes
+>
+> ```Go
+> // Example of encoding/gob having "fatal error: runtime: out of memory"
+> // while decoding 181 bytes (all Go versions as of Dec. 8, 2024).
+> 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.")
+> }
+> ```
+>
+>
+>
+
+### Smaller Encodings with Struct Tag Options
+
+Struct tags automatically reduce encoded size of structs and improve speed.
+
+We can write less code by using struct tag options:
+- `toarray`: encode without field names (decode back to original struct)
+- `keyasint`: encode field names as integers (decode back to original struct)
+- `omitempty`: omit empty field when encoding
+- `omitzero`: omit zero-value field when encoding
+
+As a special case, struct field tag "-" omits the field.
+
+NOTE: When a struct uses `toarray`, the encoder will ignore `omitempty` and `omitzero` to prevent position of encoded array elements from changing. This allows decoder to match encoded elements to their Go struct field.

-API is mostly same as `encoding/json`, plus interfaces that simplify concurrency for CBOR options.
+> [!NOTE]
+> `fxamacker/cbor` can encode a 3-level nested Go struct to 1 byte!
+> - `encoding/json`: 18 bytes of JSON
+> - `fxamacker/cbor`: 1 byte of CBOR
+>
+> 🔎 Encoding 3-level nested Go struct with omitempty
+>
+> 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":{}}}
+> ```
+>
+>
+
## Quick Start
__Install__: `go get github.com/fxamacker/cbor/v2` and `import "github.com/fxamacker/cbor/v2"`.
+> [!TIP]
+>
+> Tinygo users can try beta/experimental branch [feature/cbor-tinygo-beta](https://github.com/fxamacker/cbor/tree/feature/cbor-tinygo-beta).
+>
+> 🔎 More about tinygo feature branch
+>
+> ### Tinygo
+>
+> Branch [feature/cbor-tinygo-beta](https://github.com/fxamacker/cbor/tree/feature/cbor-tinygo-beta) is based on fxamacker/cbor v2.7.0 and it can be compiled using tinygo v0.33 (also compiles with golang/go).
+>
+> It passes unit tests (with both go1.22 and tinygo v0.33) and is considered beta/experimental for tinygo.
+>
+> :warning: The `feature/cbor-tinygo-beta` branch does not get fuzz tested yet.
+>
+> Changes in this feature branch only affect tinygo compiled software. Summary of changes:
+> - default `DecOptions.MaxNestedLevels` is reduced to 16 (was 32). User can specify higher limit but 24+ crashes tests when compiled with tinygo v0.33.
+> - disabled decoding CBOR tag data to Go interface because tinygo v0.33 is missing needed feature.
+> - encoding error message can be different when encoding function type.
+>
+> Related tinygo issues:
+> - https://github.com/tinygo-org/tinygo/issues/4277
+> - https://github.com/tinygo-org/tinygo/issues/4458
+>
+>
+
+
### Key Points
This library can encode and decode CBOR (RFC 8949) and CBOR Sequences (RFC 8742).
@@ -252,16 +294,17 @@ 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.
+// NOTE: Unmarshal() returns ExtraneousDataError if there are remaining bytes, but
+// UnmarshalFirst() and DiagnoseFirst() allow trailing bytes.
```
-__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.
+> [!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
@@ -312,9 +355,63 @@ err = em.MarshalToBuffer(v, &buf) // encode v to provided buf
### Struct Tags
-Struct tags (`toarray`, `keyasint`, `omitempty`) reduce encoded size of structs.
+Struct tag options (`toarray`, `keyasint`, `omitempty`, `omitzero`) reduce encoded size of structs.
+
+As a special case, struct field tag "-" omits the field.
+
+ 🔎 Example encoding with struct field tag "-"
+
+https://go.dev/play/p/aWEIFxd7InX
+
+```Go
+// https://github.com/fxamacker/cbor/issues/652
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/fxamacker/cbor/v2"
+)
+
+// The `cbor:"-"` tag omits the Type field when encoding to CBOR.
+type Entity struct {
+ _ struct{} `cbor:",toarray"`
+ ID uint64 `json:"id"`
+ Type string `cbor:"-" json:"typeOf"`
+ Name string `json:"name"`
+}
+
+func main() {
+ entity := Entity{
+ ID: 1,
+ Type: "int64",
+ Name: "Identifier",
+ }
+
+ c, _ := cbor.Marshal(entity)
+ diag, _ := cbor.Diagnose(c)
+ fmt.Printf("CBOR in hex: %x\n", c)
+ fmt.Printf("CBOR in edn: %s\n", diag)
+
+ j, _ := json.Marshal(entity)
+ fmt.Printf("JSON: %s\n", string(j))
+
+ fmt.Printf("JSON encoding is %d bytes\n", len(j))
+ fmt.Printf("CBOR encoding is %d bytes\n", len(c))
+
+ // Output:
+ // CBOR in hex: 82016a4964656e746966696572
+ // CBOR in edn: [1, "Identifier"]
+ // JSON: {"id":1,"typeOf":"int64","name":"Identifier"}
+ // JSON encoding is 45 bytes
+ // CBOR encoding is 13 bytes
+}
+```
+
+
-Example encoding 3-level nested Go struct to 1 byte CBOR
+ 🔎 Example encoding 3-level nested Go struct to 1 byte CBOR
https://go.dev/play/p/YxwvfPdFQG2
@@ -382,13 +479,13 @@ JSON: {"Foo":{"Qux":{}}}
-Example using several struct tags
+ 🔎 Example using struct tag options

-Struct tags simplify use of CBOR-based protocols that require CBOR arrays or maps with integer keys.
+Struct tag options simplify use of CBOR-based protocols that require CBOR arrays or maps with integer keys.
### CBOR Tags
@@ -404,7 +501,7 @@ 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
+ 🔎 Example using TagSet and TagOptions
```go
// Use signedCWT struct defined in "Decoding CWT" example.
@@ -430,16 +527,149 @@ if err := dm.Unmarshal(data, &v); err != nil {
em, _ := cbor.EncOptions{}.EncModeWithTags(tags)
// Marshal signedCWT with tag number.
-if data, err := cbor.Marshal(v); err != nil {
+if data, err := em.Marshal(v); err != nil {
return err
}
```
+👉 `fxamacker/cbor` allows user apps to use almost any current or future CBOR tag number by implementing `cbor.Marshaler` and `cbor.Unmarshaler` interfaces.
+
+Basically, `MarshalCBOR` and `UnmarshalCBOR` functions can be implemented by user apps and those functions will automatically be called by this CBOR codec's `Marshal`, `Unmarshal`, etc.
+
+The following [example](https://github.com/fxamacker/cbor/blob/master/example_embedded_json_tag_for_cbor_test.go) shows how to encode and decode a tagged CBOR data item with tag number 262. The tag content is a JSON object "embedded" as a CBOR byte string (major type 2).
+
+ 🔎 Example using Embedded JSON Tag for CBOR (tag 262)
+
+```go
+// https://github.com/fxamacker/cbor/issues/657
+
+package cbor_test
+
+// NOTE: RFC 8949 does not mention tag number 262. IANA assigned
+// CBOR tag number 262 as "Embedded JSON Object" specified by the
+// document Embedded JSON Tag for CBOR:
+//
+// "Tag 262 can be applied to a byte string (major type 2) to indicate
+// that the byte string is a JSON Object. The length of the byte string
+// indicates the content."
+//
+// For more info, see Embedded JSON Tag for CBOR at:
+// https://github.com/toravir/CBOR-Tag-Specs/blob/master/embeddedJSON.md
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+
+ "github.com/fxamacker/cbor/v2"
+)
+
+// cborTagNumForEmbeddedJSON is the CBOR tag number 262.
+const cborTagNumForEmbeddedJSON = 262
+
+// EmbeddedJSON represents a Go value to be encoded as a tagged CBOR data item
+// with tag number 262 and the tag content is a JSON object "embedded" as a
+// CBOR byte string (major type 2).
+type EmbeddedJSON struct {
+ any
+}
+
+func NewEmbeddedJSON(val any) EmbeddedJSON {
+ return EmbeddedJSON{val}
+}
+
+// MarshalCBOR encodes EmbeddedJSON to a tagged CBOR data item with the
+// tag number 262 and the tag content is a JSON object that is
+// "embedded" as a CBOR byte string.
+func (v EmbeddedJSON) MarshalCBOR() ([]byte, error) {
+ // Encode v to JSON object.
+ data, err := json.Marshal(v)
+ if err != nil {
+ return nil, err
+ }
+
+ // Create cbor.Tag representing a tagged CBOR data item.
+ tag := cbor.Tag{
+ Number: cborTagNumForEmbeddedJSON,
+ Content: data,
+ }
+
+ // Marshal to a tagged CBOR data item.
+ return cbor.Marshal(tag)
+}
+
+// UnmarshalCBOR decodes a tagged CBOR data item to EmbeddedJSON.
+// The byte slice provided to this function must contain a single
+// tagged CBOR data item with the tag number 262 and tag content
+// must be a JSON object "embedded" as a CBOR byte string.
+func (v *EmbeddedJSON) UnmarshalCBOR(b []byte) error {
+ // Unmarshal tagged CBOR data item.
+ var tag cbor.Tag
+ if err := cbor.Unmarshal(b, &tag); err != nil {
+ return err
+ }
+
+ // Check tag number.
+ if tag.Number != cborTagNumForEmbeddedJSON {
+ return fmt.Errorf("got tag number %d, expect tag number %d", tag.Number, cborTagNumForEmbeddedJSON)
+ }
+
+ // Check tag content.
+ jsonData, isByteString := tag.Content.([]byte)
+ if !isByteString {
+ return fmt.Errorf("got tag content type %T, expect tag content []byte", tag.Content)
+ }
+
+ // Unmarshal JSON object.
+ return json.Unmarshal(jsonData, v)
+}
+
+// MarshalJSON encodes EmbeddedJSON to a JSON object.
+func (v EmbeddedJSON) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.any)
+}
+
+// UnmarshalJSON decodes a JSON object.
+func (v *EmbeddedJSON) UnmarshalJSON(b []byte) error {
+ dec := json.NewDecoder(bytes.NewReader(b))
+ dec.UseNumber()
+ return dec.Decode(&v.any)
+}
+
+func Example_embeddedJSONTagForCBOR() {
+ value := NewEmbeddedJSON(map[string]any{
+ "name": "gopher",
+ "id": json.Number("42"),
+ })
+
+ data, err := cbor.Marshal(value)
+ if err != nil {
+ panic(err)
+ }
+
+ fmt.Printf("cbor: %x\n", data)
+
+ var v EmbeddedJSON
+ err = cbor.Unmarshal(data, &v)
+ if err != nil {
+ panic(err)
+ }
+
+ fmt.Printf("%+v\n", v.any)
+ for k, v := range v.any.(map[string]any) {
+ fmt.Printf(" %s: %v (%T)\n", k, v, v)
+ }
+}
+```
+
+
+
+
### Functions and Interfaces
-Functions and interfaces at a glance
+ 🔎 Functions and interfaces at a glance
Common functions with same API as `encoding/json`:
- `Marshal`, `Unmarshal`
@@ -453,7 +683,7 @@ because RFC 8949 treats CBOR data item with remaining bytes as malformed.
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.
+- `Wellformed` returns true if the CBOR data item is well-formed.
Interfaces identical or comparable to Go `encoding` packages include:
`Marshaler`, `Unmarshaler`, `BinaryMarshaler`, and `BinaryUnmarshaler`.
@@ -472,15 +702,28 @@ Default limits may need to be increased for systems handling very large data (e.
## 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.
+[v2.9.0](https://github.com/fxamacker/cbor/releases/tag/v2.9.0) (Jul 13, 2025) improved interoperability/transcoding between CBOR & JSON, refactored tests, and improved docs.
+- Add opt-in support for `encoding.TextMarshaler` and `encoding.TextUnmarshaler` to encode and decode from CBOR text string.
+- Add opt-in support for `json.Marshaler` and `json.Unmarshaler` via user-provided transcoding function.
+- Update docs for TimeMode, Tag, RawTag, and add example for Embedded JSON Tag for CBOR.
+
+v2.9.0 passed fuzz tests and is production quality.
+
+The minimum version of Go required to build:
+- v2.8.0 and newer releases require go 1.20+.
+- v2.7.1 and older releases require go 1.17+.
For more details, see [release notes](https://github.com/fxamacker/cbor/releases).
-### Prior Release
+### Prior Releases
+
+[v2.8.0](https://github.com/fxamacker/cbor/releases/tag/v2.8.0) (March 30, 2025) is a small release primarily to add `omitzero` option to struct field tags and fix bugs. It passed fuzz tests (billions of executions) and is production quality.
+
+[v2.7.0](https://github.com/fxamacker/cbor/releases/tag/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.
[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).
+[v2.5.0](https://github.com/fxamacker/cbor/releases/tag/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.
@@ -489,7 +732,7 @@ See [v2.5.0 release notes](https://github.com/fxamacker/cbor/releases/tag/v2.5.0
See ["Version and API Changes"](https://github.com/fxamacker/cbor#versions-and-api-changes) section for more info about version numbering, etc.
+
+- [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests
+- [Kubernetes Contributor Guide](https://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](https://git.k8s.io/community/contributors/guide#contributing)
+- [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet) - Common resources for existing developers
+
+## Mentorship
+
+- [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers!
+
+
+
+## Project Management
+
+The [maintainers](https://github.com/kubernetes-sigs/randfill/blob/main/OWNERS_ALIASES#L12) of this project (and often others who have official positions on the [contributor ladder](https://github.com/kubernetes-sigs/randfill/blob/main/OWNERS_ALIASES)) are responsible for performing project management which oversees development and maintenance of the API, tests, tools, e.t.c. While we try to be generally flexible when it comes to the management of individual pieces (such as Issues or PRs), we have some rules and guidelines which help us plan, coordinate and reduce waste. In this section you'll find some rules/guidelines for contributors related to project management which may extend or go beyond what you would find in the standard [Kubernetes Contributor Guide](https://git.k8s.io/community/contributors/guide).
+
+### Bumping stale and closed Issues & PRs
+
+Maintainers are ultimately responsible for triaging new issues and PRs, accepting or declining them, deciding priority and fitting them into milestones intended for future releases. Bots are responsible for marking issues and PRs which stagnate as stale, or closing them if progress does not continue for a long period of time. Due to the nature of this community-driven development effort (we do not have dedicated engineering resources, we rely on the community which is effectively "volunteer time") **not all issues can be accepted, prioritized or completed**.
+
+You may find times when an issue you're subscribed to and interested in seems to stagnate, or perhaps gets auto-closed. Prior to bumping or directly re-opening issues yourself, we generally ask that you bring these up for discussion on the agenda for one of our community syncs if possible, or bring them up for discussion in Slack or the mailing list as this gives us a better opportunity to discuss the issue and determine viability and logistics. If feasible we **highly recommend being ready to contribute directly** to any stale or unprioritized effort that you want to see move forward, as **the best way to ensure progress is to engage with the community and personally invest time**.
+
+We (the community) aren't opposed to making exceptions in some cases, but when in doubt please follow the above guidelines before bumping closed or stale issues if you're not ready to personally invest time in them. We are responsible for managing these and without further context or engagement we may set these back to how they were previously organized.
diff --git a/vendor/github.com/google/gofuzz/LICENSE b/vendor/sigs.k8s.io/randfill/LICENSE
similarity index 99%
rename from vendor/github.com/google/gofuzz/LICENSE
rename to vendor/sigs.k8s.io/randfill/LICENSE
index d64569567..9dd29274c 100644
--- a/vendor/github.com/google/gofuzz/LICENSE
+++ b/vendor/sigs.k8s.io/randfill/LICENSE
@@ -1,4 +1,3 @@
-
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
@@ -179,7 +178,7 @@
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 "[]"
+ 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
@@ -187,7 +186,8 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright 2014 The gofuzz Authors
+ Copyright 2025 The Kubernetes Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/vendor/sigs.k8s.io/randfill/NOTICE b/vendor/sigs.k8s.io/randfill/NOTICE
new file mode 100644
index 000000000..6984e71f6
--- /dev/null
+++ b/vendor/sigs.k8s.io/randfill/NOTICE
@@ -0,0 +1,24 @@
+When donating the randfill project to the CNCF, we could not reach all the
+gofuzz contributors to sign the CNCF CLA. As such, according to the CNCF rules
+to donate a repository, we must add a NOTICE referencing section 7 of the CLA
+with a list of developers who could not be reached.
+
+`7. Should You wish to submit work that is not Your original creation, You may
+submit it to the Foundation separately from any Contribution, identifying the
+complete details of its source and of any license or other restriction
+(including, but not limited to, related patents, trademarks, and license
+agreements) of which you are personally aware, and conspicuously marking the
+work as "Submitted on behalf of a third-party: [named here]".`
+
+Submitted on behalf of a third-party: @dnephin (Daniel Nephin)
+Submitted on behalf of a third-party: @AlekSi (Alexey Palazhchenko)
+Submitted on behalf of a third-party: @bbigras (Bruno Bigras)
+Submitted on behalf of a third-party: @samirkut (Samir)
+Submitted on behalf of a third-party: @posener (Eyal Posener)
+Submitted on behalf of a third-party: @Ashikpaul (Ashik Paul)
+Submitted on behalf of a third-party: @kwongtailau (Kwongtai)
+Submitted on behalf of a third-party: @ericcornelissen (Eric Cornelissen)
+Submitted on behalf of a third-party: @eclipseo (Robert-André Mauchin)
+Submitted on behalf of a third-party: @yanzhoupan (Andrew Pan)
+Submitted on behalf of a third-party: @STRRL (Zhiqiang ZHOU)
+Submitted on behalf of a third-party: @disconnect3d (Disconnect3d)
diff --git a/vendor/sigs.k8s.io/randfill/OWNERS b/vendor/sigs.k8s.io/randfill/OWNERS
new file mode 100644
index 000000000..59f6a50f6
--- /dev/null
+++ b/vendor/sigs.k8s.io/randfill/OWNERS
@@ -0,0 +1,8 @@
+# See the OWNERS docs at https://go.k8s.io/owners
+# See the OWNERS_ALIASES file at https://github.com/kubernetes-sigs/randfill/blob/main/OWNERS_ALIASES for a list of members for each alias.
+
+approvers:
+ - sig-testing-leads
+ - thockin
+
+reviewers: []
diff --git a/vendor/sigs.k8s.io/randfill/OWNERS_ALIASES b/vendor/sigs.k8s.io/randfill/OWNERS_ALIASES
new file mode 100644
index 000000000..927f1209b
--- /dev/null
+++ b/vendor/sigs.k8s.io/randfill/OWNERS_ALIASES
@@ -0,0 +1,14 @@
+# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md
+# This file should be kept in sync with k/org.
+
+aliases:
+ # Reference: https://github.com/kubernetes/org/blob/main/OWNERS_ALIASES
+ sig-testing-leads:
+ - BenTheElder
+ - alvaroaleman
+ - aojea
+ - cjwagner
+ - jbpratt
+ - michelle192837
+ - pohly
+ - xmcqueen
diff --git a/vendor/github.com/google/gofuzz/README.md b/vendor/sigs.k8s.io/randfill/README.md
similarity index 53%
rename from vendor/github.com/google/gofuzz/README.md
rename to vendor/sigs.k8s.io/randfill/README.md
index b503aae7d..d892fc9f5 100644
--- a/vendor/github.com/google/gofuzz/README.md
+++ b/vendor/sigs.k8s.io/randfill/README.md
@@ -1,39 +1,46 @@
-gofuzz
+randfill
======
-gofuzz is a library for populating go objects with random values.
+randfill is a library for populating go objects with random values.
-[](https://godoc.org/github.com/google/gofuzz)
-[](https://travis-ci.org/google/gofuzz)
+This is a fork of github.com/google/gofuzz, which was archived.
+
+NOTE: This repo is supported only for use within Kubernetes. It is not our
+intention to support general use. That said, if it works for you, that's
+great! If you have a problem, please feel free to file an issue, but be aware
+that it may not be a priority for us to fix it unless it is affecting
+Kubernetes. PRs are welcome, within reason.
+
+[](https://godoc.org/sigs.k8s.io/randfill)
This is useful for testing:
* Do your project's objects really serialize/unserialize correctly in all cases?
* Is there an incorrectly formatted object that will cause your project to panic?
-Import with ```import "github.com/google/gofuzz"```
+Import with ```import "sigs.k8s.io/randfill"```
You can use it on single variables:
```go
-f := fuzz.New()
+f := randfill.New()
var myInt int
-f.Fuzz(&myInt) // myInt gets a random value.
+f.Fill(&myInt) // myInt gets a random value.
```
You can use it on maps:
```go
-f := fuzz.New().NilChance(0).NumElements(1, 1)
+f := randfill.New().NilChance(0).NumElements(1, 1)
var myMap map[ComplexKeyType]string
-f.Fuzz(&myMap) // myMap will have exactly one element.
+f.Fill(&myMap) // myMap will have exactly one element.
```
Customize the chance of getting a nil pointer:
```go
-f := fuzz.New().NilChance(.5)
+f := randfill.New().NilChance(.5)
var fancyStruct struct {
A, B, C, D *string
}
-f.Fuzz(&fancyStruct) // About half the pointers should be set.
+f.Fill(&fancyStruct) // About half the pointers should be set.
```
You can even customize the randomization completely if needed:
@@ -49,25 +56,27 @@ type MyInfo struct {
BInfo *string
}
-f := fuzz.New().NilChance(0).Funcs(
- func(e *MyInfo, c fuzz.Continue) {
+f := randfill.New().NilChance(0).Funcs(
+ func(e *MyInfo, c randfill.Continue) {
switch c.Intn(2) {
case 0:
e.Type = A
- c.Fuzz(&e.AInfo)
+ c.Fill(&e.AInfo)
case 1:
e.Type = B
- c.Fuzz(&e.BInfo)
+ c.Fill(&e.BInfo)
}
},
)
var myObject MyInfo
-f.Fuzz(&myObject) // Type will correspond to whether A or B info is set.
+f.Fill(&myObject) // Type will correspond to whether A or B info is set.
```
See more examples in ```example_test.go```.
+## dvyukov/go-fuzz integration
+
You can use this library for easier [go-fuzz](https://github.com/dvyukov/go-fuzz)ing.
go-fuzz provides the user a byte-slice, which should be converted to different inputs
for the tested function. This library can help convert the byte slice. Consider for
@@ -76,11 +85,11 @@ example a fuzz test for a the function `mypackage.MyFunc` that takes an int argu
// +build gofuzz
package mypackage
-import fuzz "github.com/google/gofuzz"
+import "sigs.k8s.io/randfill"
func Fuzz(data []byte) int {
var i int
- fuzz.NewFromGoFuzz(data).Fuzz(&i)
+ randfill.NewFromGoFuzz(data).Fill(&i)
MyFunc(i)
return 0
}
diff --git a/vendor/sigs.k8s.io/randfill/SECURITY_CONTACTS b/vendor/sigs.k8s.io/randfill/SECURITY_CONTACTS
new file mode 100644
index 000000000..91d785337
--- /dev/null
+++ b/vendor/sigs.k8s.io/randfill/SECURITY_CONTACTS
@@ -0,0 +1,16 @@
+# Defined below are the security contacts for this repo.
+#
+# They are the contact point for the Product Security Committee to reach out
+# to for triaging and handling of incoming issues.
+#
+# The below names agree to abide by the
+# [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy)
+# and will be removed and replaced if they violate that agreement.
+#
+# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
+# INSTRUCTIONS AT https://kubernetes.io/security/
+
+thockin
+BenTheElder
+aojea
+pohly
diff --git a/vendor/github.com/google/gofuzz/bytesource/bytesource.go b/vendor/sigs.k8s.io/randfill/bytesource/bytesource.go
similarity index 100%
rename from vendor/github.com/google/gofuzz/bytesource/bytesource.go
rename to vendor/sigs.k8s.io/randfill/bytesource/bytesource.go
diff --git a/vendor/sigs.k8s.io/randfill/code-of-conduct.md b/vendor/sigs.k8s.io/randfill/code-of-conduct.md
new file mode 100644
index 000000000..0d15c00cf
--- /dev/null
+++ b/vendor/sigs.k8s.io/randfill/code-of-conduct.md
@@ -0,0 +1,3 @@
+# Kubernetes Community Code of Conduct
+
+Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md)
diff --git a/vendor/sigs.k8s.io/randfill/randfill.go b/vendor/sigs.k8s.io/randfill/randfill.go
new file mode 100644
index 000000000..b73482484
--- /dev/null
+++ b/vendor/sigs.k8s.io/randfill/randfill.go
@@ -0,0 +1,682 @@
+/*
+Copyright 2014 Google Inc. All rights reserved.
+Copyright 2014 The gofuzz Authors.
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package randfill is a library for populating go objects with random values.
+package randfill
+
+import (
+ "fmt"
+ "math/rand"
+ "reflect"
+ "regexp"
+ "sync"
+ "time"
+ "unsafe"
+
+ "strings"
+
+ "sigs.k8s.io/randfill/bytesource"
+)
+
+// funcMap is a map from a type to a function that randfills that type. The
+// function is a reflect.Value because the type being filled is different for
+// each func.
+type funcMap map[reflect.Type]reflect.Value
+
+// Filler knows how to fill any object with random fields.
+type Filler struct {
+ customFuncs funcMap
+ defaultFuncs funcMap
+ r *rand.Rand
+ nilChance float64
+ minElements int
+ maxElements int
+ maxDepth int
+ allowUnexportedFields bool
+ skipFieldPatterns []*regexp.Regexp
+
+ lock sync.Mutex
+}
+
+// New returns a new Filler. Customize your Filler further by calling Funcs,
+// RandSource, NilChance, or NumElements in any order.
+func New() *Filler {
+ return NewWithSeed(time.Now().UnixNano())
+}
+
+func NewWithSeed(seed int64) *Filler {
+ f := &Filler{
+ defaultFuncs: funcMap{
+ reflect.TypeOf(&time.Time{}): reflect.ValueOf(randfillTime),
+ },
+
+ customFuncs: funcMap{},
+ r: rand.New(rand.NewSource(seed)),
+ nilChance: .2,
+ minElements: 1,
+ maxElements: 10,
+ maxDepth: 100,
+ allowUnexportedFields: false,
+ }
+ return f
+}
+
+// NewFromGoFuzz is a helper function that enables using randfill (this
+// project) with go-fuzz (https://github.com/dvyukov/go-fuzz) for continuous
+// fuzzing. Essentially, it enables translating the fuzzing bytes from
+// go-fuzz to any Go object using this library.
+//
+// This implementation promises a constant translation from a given slice of
+// bytes to the fuzzed objects. This promise will remain over future
+// versions of Go and of this library.
+//
+// Note: the returned Filler should not be shared between multiple goroutines,
+// as its deterministic output will no longer be available.
+//
+// Example: use go-fuzz to test the function `MyFunc(int)` in the package
+// `mypackage`. Add the file: "mypackage_fuzz.go" with the content:
+//
+// // +build gofuzz
+// package mypackage
+// import "sigs.k8s.io/randfill"
+//
+// func Fuzz(data []byte) int {
+// var i int
+// randfill.NewFromGoFuzz(data).Fill(&i)
+// MyFunc(i)
+// return 0
+// }
+func NewFromGoFuzz(data []byte) *Filler {
+ return New().RandSource(bytesource.New(data))
+}
+
+// Funcs registers custom fill functions for this Filler.
+//
+// Each entry in customFuncs must be a function taking two parameters.
+// The first parameter must be a pointer or map. It is the variable that
+// function will fill with random data. The second parameter must be a
+// randfill.Continue, which will provide a source of randomness and a way
+// to automatically continue filling smaller pieces of the first parameter.
+//
+// These functions are called sensibly, e.g., if you wanted custom string
+// filling, the function `func(s *string, c randfill.Continue)` would get
+// called and passed the address of strings. Maps and pointers will always
+// be made/new'd for you, ignoring the NilChance option. For slices, it
+// doesn't make much sense to pre-create them--Filler doesn't know how
+// long you want your slice--so take a pointer to a slice, and make it
+// yourself. (If you don't want your map/pointer type pre-made, take a
+// pointer to it, and make it yourself.) See the examples for a range of
+// custom functions.
+//
+// If a function is already registered for a type, and a new function is
+// provided, the previous function will be replaced with the new one.
+func (f *Filler) Funcs(customFuncs ...interface{}) *Filler {
+ for i := range customFuncs {
+ v := reflect.ValueOf(customFuncs[i])
+ if v.Kind() != reflect.Func {
+ panic("Filler.Funcs: all arguments must be functions")
+ }
+ t := v.Type()
+ if t.NumIn() != 2 || t.NumOut() != 0 {
+ panic("Filler.Funcs: all customFuncs must have 2 arguments and 0 returns")
+ }
+ argT := t.In(0)
+ switch argT.Kind() {
+ case reflect.Ptr, reflect.Map:
+ default:
+ panic("Filler.Funcs: customFuncs' first argument must be a pointer or map type")
+ }
+ if t.In(1) != reflect.TypeOf(Continue{}) {
+ panic("Filler.Funcs: customFuncs' second argument must be a randfill.Continue")
+ }
+ f.customFuncs[argT] = v
+ }
+ return f
+}
+
+// RandSource causes this Filler to get values from the given source of
+// randomness. Use this if you want deterministic filling.
+func (f *Filler) RandSource(s rand.Source) *Filler {
+ f.r = rand.New(s)
+ return f
+}
+
+// NilChance sets the probability of creating a nil pointer, map, or slice to
+// 'p'. 'p' should be between 0 (no nils) and 1 (all nils), inclusive.
+func (f *Filler) NilChance(p float64) *Filler {
+ if p < 0 || p > 1 {
+ panic("Filler.NilChance: p must be between 0 and 1, inclusive")
+ }
+ f.nilChance = p
+ return f
+}
+
+// NumElements sets the minimum and maximum number of elements that will be
+// added to a non-nil map or slice.
+func (f *Filler) NumElements(min, max int) *Filler {
+ if min < 0 {
+ panic("Filler.NumElements: min must be >= 0")
+ }
+ if min > max {
+ panic("Filler.NumElements: min must be <= max")
+ }
+ f.minElements = min
+ f.maxElements = max
+ return f
+}
+
+func (f *Filler) genElementCount() int {
+ if f.minElements == f.maxElements {
+ return f.minElements
+ }
+ return f.minElements + f.r.Intn(f.maxElements-f.minElements+1)
+}
+
+func (f *Filler) genShouldFill() bool {
+ return f.r.Float64() >= f.nilChance
+}
+
+// MaxDepth sets the maximum number of recursive fill calls that will be made
+// before stopping. This includes struct members, pointers, and map and slice
+// elements.
+func (f *Filler) MaxDepth(d int) *Filler {
+ f.maxDepth = d
+ return f
+}
+
+// AllowUnexportedFields defines whether to fill unexported fields.
+func (f *Filler) AllowUnexportedFields(flag bool) *Filler {
+ f.allowUnexportedFields = flag
+ return f
+}
+
+// SkipFieldsWithPattern tells this Filler to skip any field whose name matches
+// the supplied pattern. Call this multiple times if needed. This is useful to
+// skip XXX_ fields generated by protobuf.
+func (f *Filler) SkipFieldsWithPattern(pattern *regexp.Regexp) *Filler {
+ f.skipFieldPatterns = append(f.skipFieldPatterns, pattern)
+ return f
+}
+
+// SimpleSelfFiller represents an object that knows how to randfill itself.
+//
+// Unlike NativeSelfFiller, this interface does not cause the type in question
+// to depend on the randfill package. This is most useful for simple types. For
+// more complex types, consider using NativeSelfFiller.
+type SimpleSelfFiller interface {
+ // RandFill fills the current object with random data.
+ RandFill(r *rand.Rand)
+}
+
+// NativeSelfFiller represents an object that knows how to randfill itself.
+//
+// Unlike SimpleSelfFiller, this interface allows for recursive filling of
+// child objects with the same rules as the parent Filler.
+type NativeSelfFiller interface {
+ // RandFill fills the current object with random data.
+ RandFill(c Continue)
+}
+
+// Fill recursively fills all of obj's fields with something random. First
+// this tries to find a custom fill function (see Funcs). If there is no
+// custom function, this tests whether the object implements SimpleSelfFiller
+// or NativeSelfFiller and if so, calls RandFill on it to fill itself. If that
+// fails, this will see if there is a default fill function provided by this
+// package. If all of that fails, this will generate random values for all
+// primitive fields and then recurse for all non-primitives.
+//
+// This is safe for cyclic or tree-like structs, up to a limit. Use the
+// MaxDepth method to adjust how deep you need it to recurse.
+//
+// obj must be a pointer. Exported (public) fields can always be set, and if
+// the AllowUnexportedFields() modifier was called it can try to set unexported
+// (private) fields, too.
+//
+// This is intended for tests, so will panic on bad input or unimplemented
+// types. This method takes a lock for the whole Filler, so it is not
+// reentrant. See Continue.
+func (f *Filler) Fill(obj interface{}) {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ v := reflect.ValueOf(obj)
+ if v.Kind() != reflect.Ptr {
+ panic("Filler.Fill: obj must be a pointer")
+ }
+ v = v.Elem()
+ f.fillWithContext(v, 0)
+}
+
+// FillNoCustom is just like Fill, except that any custom fill function for
+// obj's type will not be called and obj will not be tested for
+// SimpleSelfFiller or NativeSelfFiller. This applies only to obj and not other
+// instances of obj's type or to obj's child fields.
+//
+// obj must be a pointer. Exported (public) fields can always be set, and if
+// the AllowUnexportedFields() modifier was called it can try to set unexported
+// (private) fields, too.
+//
+// This is intended for tests, so will panic on bad input or unimplemented
+// types. This method takes a lock for the whole Filler, so it is not
+// reentrant. See Continue.
+func (f *Filler) FillNoCustom(obj interface{}) {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ v := reflect.ValueOf(obj)
+ if v.Kind() != reflect.Ptr {
+ panic("Filler.FillNoCustom: obj must be a pointer")
+ }
+ v = v.Elem()
+ f.fillWithContext(v, flagNoCustomFill)
+}
+
+const (
+ // Do not try to find a custom fill function. Does not apply recursively.
+ flagNoCustomFill uint64 = 1 << iota
+)
+
+func (f *Filler) fillWithContext(v reflect.Value, flags uint64) {
+ fc := &fillerContext{filler: f}
+ fc.doFill(v, flags)
+}
+
+// fillerContext carries context about a single filling run, which lets Filler
+// be thread-safe.
+type fillerContext struct {
+ filler *Filler
+ curDepth int
+}
+
+func (fc *fillerContext) doFill(v reflect.Value, flags uint64) {
+ if fc.curDepth >= fc.filler.maxDepth {
+ return
+ }
+ fc.curDepth++
+ defer func() { fc.curDepth-- }()
+
+ if !v.CanSet() {
+ if !fc.filler.allowUnexportedFields || !v.CanAddr() {
+ return
+ }
+ v = reflect.NewAt(v.Type(), unsafe.Pointer(v.UnsafeAddr())).Elem()
+ }
+
+ if flags&flagNoCustomFill == 0 {
+ // Check for both pointer and non-pointer custom functions.
+ if v.CanAddr() && fc.tryCustom(v.Addr()) {
+ return
+ }
+ if fc.tryCustom(v) {
+ return
+ }
+ }
+
+ if fn, ok := fillFuncMap[v.Kind()]; ok {
+ fn(v, fc.filler.r)
+ return
+ }
+
+ switch v.Kind() {
+ case reflect.Map:
+ if fc.filler.genShouldFill() {
+ v.Set(reflect.MakeMap(v.Type()))
+ n := fc.filler.genElementCount()
+ for i := 0; i < n; i++ {
+ key := reflect.New(v.Type().Key()).Elem()
+ fc.doFill(key, 0)
+ val := reflect.New(v.Type().Elem()).Elem()
+ fc.doFill(val, 0)
+ v.SetMapIndex(key, val)
+ }
+ return
+ }
+ v.Set(reflect.Zero(v.Type()))
+ case reflect.Ptr:
+ if fc.filler.genShouldFill() {
+ v.Set(reflect.New(v.Type().Elem()))
+ fc.doFill(v.Elem(), 0)
+ return
+ }
+ v.Set(reflect.Zero(v.Type()))
+ case reflect.Slice:
+ if fc.filler.genShouldFill() {
+ n := fc.filler.genElementCount()
+ v.Set(reflect.MakeSlice(v.Type(), n, n))
+ for i := 0; i < n; i++ {
+ fc.doFill(v.Index(i), 0)
+ }
+ return
+ }
+ v.Set(reflect.Zero(v.Type()))
+ case reflect.Array:
+ if fc.filler.genShouldFill() {
+ n := v.Len()
+ for i := 0; i < n; i++ {
+ fc.doFill(v.Index(i), 0)
+ }
+ return
+ }
+ v.Set(reflect.Zero(v.Type()))
+ case reflect.Struct:
+ for i := 0; i < v.NumField(); i++ {
+ skipField := false
+ fieldName := v.Type().Field(i).Name
+ for _, pattern := range fc.filler.skipFieldPatterns {
+ if pattern.MatchString(fieldName) {
+ skipField = true
+ break
+ }
+ }
+ if !skipField {
+ fc.doFill(v.Field(i), 0)
+ }
+ }
+ case reflect.Chan:
+ fallthrough
+ case reflect.Func:
+ fallthrough
+ case reflect.Interface:
+ fallthrough
+ default:
+ panic(fmt.Sprintf("can't fill type %v, kind %v", v.Type(), v.Kind()))
+ }
+}
+
+// tryCustom searches for custom handlers, and returns true iff it finds a match
+// and successfully randomizes v.
+func (fc *fillerContext) tryCustom(v reflect.Value) bool {
+ // First: see if we have a fill function for it.
+ doCustom, ok := fc.filler.customFuncs[v.Type()]
+ if !ok {
+ // Second: see if it can fill itself.
+ if v.CanInterface() {
+ intf := v.Interface()
+ if fillable, ok := intf.(SimpleSelfFiller); ok {
+ fillable.RandFill(fc.filler.r)
+ return true
+ }
+ if fillable, ok := intf.(NativeSelfFiller); ok {
+ fillable.RandFill(Continue{fc: fc, Rand: fc.filler.r})
+ return true
+ }
+ }
+ // Finally: see if there is a default fill function.
+ doCustom, ok = fc.filler.defaultFuncs[v.Type()]
+ if !ok {
+ return false
+ }
+ }
+
+ switch v.Kind() {
+ case reflect.Ptr:
+ if v.IsNil() {
+ if !v.CanSet() {
+ return false
+ }
+ v.Set(reflect.New(v.Type().Elem()))
+ }
+ case reflect.Map:
+ if v.IsNil() {
+ if !v.CanSet() {
+ return false
+ }
+ v.Set(reflect.MakeMap(v.Type()))
+ }
+ default:
+ return false
+ }
+
+ doCustom.Call([]reflect.Value{
+ v,
+ reflect.ValueOf(Continue{
+ fc: fc,
+ Rand: fc.filler.r,
+ }),
+ })
+ return true
+}
+
+// Continue can be passed to custom fill functions to allow them to use
+// the correct source of randomness and to continue filling their members.
+type Continue struct {
+ fc *fillerContext
+
+ // For convenience, Continue implements rand.Rand via embedding.
+ // Use this for generating any randomness if you want your filling
+ // to be repeatable for a given seed.
+ *rand.Rand
+}
+
+// Fill continues filling obj. obj must be a pointer or a reflect.Value of a
+// pointer. See Filler.Fill.
+func (c Continue) Fill(obj interface{}) {
+ v, ok := obj.(reflect.Value)
+ if !ok {
+ v = reflect.ValueOf(obj)
+ }
+ if v.Kind() != reflect.Ptr {
+ panic("Continue.Fill: obj must be a pointer")
+ }
+ v = v.Elem()
+ c.fc.doFill(v, 0)
+}
+
+// FillNoCustom continues filling obj, except that any custom fill function for
+// obj's type will not be called and obj will not be tested for
+// SimpleSelfFiller or NativeSelfFiller. See Filler.FillNoCustom.
+func (c Continue) FillNoCustom(obj interface{}) {
+ v, ok := obj.(reflect.Value)
+ if !ok {
+ v = reflect.ValueOf(obj)
+ }
+ if v.Kind() != reflect.Ptr {
+ panic("Continue.FillNoCustom: obj must be a pointer")
+ }
+ v = v.Elem()
+ c.fc.doFill(v, flagNoCustomFill)
+}
+
+const defaultStringMaxLen = 20
+
+// String makes a random string up to n characters long. If n is 0, the default
+// size range is [0-20). The returned string may include a variety of (valid)
+// UTF-8 encodings.
+func (c Continue) String(n int) string {
+ return randString(c.Rand, n)
+}
+
+// Uint64 makes random 64 bit numbers.
+// Weirdly, rand doesn't have a function that gives you 64 random bits.
+func (c Continue) Uint64() uint64 {
+ return randUint64(c.Rand)
+}
+
+// Bool returns true or false randomly.
+func (c Continue) Bool() bool {
+ return randBool(c.Rand)
+}
+
+func fillInt(v reflect.Value, r *rand.Rand) {
+ v.SetInt(int64(randUint64(r)))
+}
+
+func fillUint(v reflect.Value, r *rand.Rand) {
+ v.SetUint(randUint64(r))
+}
+
+func randfillTime(t *time.Time, c Continue) {
+ var sec, nsec int64
+ // Allow for about 1000 years of random time values, which keeps things
+ // like JSON parsing reasonably happy.
+ sec = c.Rand.Int63n(1000 * 365 * 24 * 60 * 60)
+ // Nanosecond values greater than 1Bn are technically allowed but result in
+ // time.Time values with invalid timezone offsets.
+ nsec = c.Rand.Int63n(999999999)
+ *t = time.Unix(sec, nsec)
+}
+
+var fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){
+ reflect.Bool: func(v reflect.Value, r *rand.Rand) {
+ v.SetBool(randBool(r))
+ },
+ reflect.Int: fillInt,
+ reflect.Int8: fillInt,
+ reflect.Int16: fillInt,
+ reflect.Int32: fillInt,
+ reflect.Int64: fillInt,
+ reflect.Uint: fillUint,
+ reflect.Uint8: fillUint,
+ reflect.Uint16: fillUint,
+ reflect.Uint32: fillUint,
+ reflect.Uint64: fillUint,
+ reflect.Uintptr: fillUint,
+ reflect.Float32: func(v reflect.Value, r *rand.Rand) {
+ v.SetFloat(float64(r.Float32()))
+ },
+ reflect.Float64: func(v reflect.Value, r *rand.Rand) {
+ v.SetFloat(r.Float64())
+ },
+ reflect.Complex64: func(v reflect.Value, r *rand.Rand) {
+ v.SetComplex(complex128(complex(r.Float32(), r.Float32())))
+ },
+ reflect.Complex128: func(v reflect.Value, r *rand.Rand) {
+ v.SetComplex(complex(r.Float64(), r.Float64()))
+ },
+ reflect.String: func(v reflect.Value, r *rand.Rand) {
+ v.SetString(randString(r, 0))
+ },
+ reflect.UnsafePointer: func(v reflect.Value, r *rand.Rand) {
+ panic("filling of UnsafePointers is not implemented")
+ },
+}
+
+// randBool returns true or false randomly.
+func randBool(r *rand.Rand) bool {
+ return r.Int31()&(1<<30) == 0
+}
+
+type int63nPicker interface {
+ Int63n(int64) int64
+}
+
+// UnicodeRange describes a sequential range of unicode characters.
+// Last must be numerically greater than First.
+type UnicodeRange struct {
+ First, Last rune
+}
+
+// UnicodeRanges describes an arbitrary number of sequential ranges of unicode characters.
+// To be useful, each range must have at least one character (First <= Last) and
+// there must be at least one range.
+type UnicodeRanges []UnicodeRange
+
+// choose returns a random unicode character from the given range, using the
+// given randomness source.
+func (ur UnicodeRange) choose(r int63nPicker) rune {
+ count := int64(ur.Last - ur.First + 1)
+ return ur.First + rune(r.Int63n(count))
+}
+
+// CustomStringFillFunc constructs a FillFunc which produces random strings.
+// Each character is selected from the range ur. If there are no characters
+// in the range (cr.Last < cr.First), this will panic.
+func (ur UnicodeRange) CustomStringFillFunc(n int) func(s *string, c Continue) {
+ ur.check()
+ return func(s *string, c Continue) {
+ *s = ur.randString(c.Rand, n)
+ }
+}
+
+// check is a function that used to check whether the first of ur(UnicodeRange)
+// is greater than the last one.
+func (ur UnicodeRange) check() {
+ if ur.Last < ur.First {
+ panic("UnicodeRange.check: the last encoding must be greater than the first")
+ }
+}
+
+// randString of UnicodeRange makes a random string up to 20 characters long.
+// Each character is selected form ur(UnicodeRange).
+func (ur UnicodeRange) randString(r *rand.Rand, max int) string {
+ if max == 0 {
+ max = defaultStringMaxLen
+ }
+ n := r.Intn(max)
+ sb := strings.Builder{}
+ sb.Grow(n)
+ for i := 0; i < n; i++ {
+ sb.WriteRune(ur.choose(r))
+ }
+ return sb.String()
+}
+
+// defaultUnicodeRanges sets a default unicode range when users do not set
+// CustomStringFillFunc() but want to fill strings.
+var defaultUnicodeRanges = UnicodeRanges{
+ {' ', '~'}, // ASCII characters
+ {'\u00a0', '\u02af'}, // Multi-byte encoded characters
+ {'\u4e00', '\u9fff'}, // Common CJK (even longer encodings)
+}
+
+// CustomStringFillFunc constructs a FillFunc which produces random strings.
+// Each character is selected from one of the ranges of ur(UnicodeRanges).
+// Each range has an equal probability of being chosen. If there are no ranges,
+// or a selected range has no characters (.Last < .First), this will panic.
+// Do not modify any of the ranges in ur after calling this function.
+func (ur UnicodeRanges) CustomStringFillFunc(n int) func(s *string, c Continue) {
+ // Check unicode ranges slice is empty.
+ if len(ur) == 0 {
+ panic("UnicodeRanges is empty")
+ }
+ // if not empty, each range should be checked.
+ for i := range ur {
+ ur[i].check()
+ }
+ return func(s *string, c Continue) {
+ *s = ur.randString(c.Rand, n)
+ }
+}
+
+// randString of UnicodeRanges makes a random string up to 20 characters long.
+// Each character is selected form one of the ranges of ur(UnicodeRanges),
+// and each range has an equal probability of being chosen.
+func (ur UnicodeRanges) randString(r *rand.Rand, max int) string {
+ if max == 0 {
+ max = defaultStringMaxLen
+ }
+ n := r.Intn(max)
+ sb := strings.Builder{}
+ sb.Grow(n)
+ for i := 0; i < n; i++ {
+ sb.WriteRune(ur[r.Intn(len(ur))].choose(r))
+ }
+ return sb.String()
+}
+
+// randString makes a random string up to 20 characters long. The returned string
+// may include a variety of (valid) UTF-8 encodings.
+func randString(r *rand.Rand, max int) string {
+ return defaultUnicodeRanges.randString(r, max)
+}
+
+// randUint64 makes random 64 bit numbers.
+// Weirdly, rand doesn't have a function that gives you 64 random bits.
+func randUint64(r *rand.Rand) uint64 {
+ return uint64(r.Uint32())<<32 | uint64(r.Uint32())
+}
diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/LICENSE b/vendor/sigs.k8s.io/structured-merge-diff/v6/LICENSE
similarity index 100%
rename from vendor/sigs.k8s.io/yaml/goyaml.v2/LICENSE
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/LICENSE
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/doc.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/doc.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/doc.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/doc.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/element.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/element.go
similarity index 78%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/element.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/element.go
index 1578f64c0..73436912c 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/element.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/element.go
@@ -18,10 +18,11 @@ package fieldpath
import (
"fmt"
+ "iter"
"sort"
"strings"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
// PathElement describes how to select a child field given a containing object.
@@ -47,6 +48,36 @@ type PathElement struct {
Index *int
}
+// FieldNameElement creates a new FieldName PathElement.
+func FieldNameElement(name string) PathElement {
+ return PathElement{FieldName: &name}
+}
+
+// KeyElement creates a new Key PathElement with the key fields.
+func KeyElement(fields ...value.Field) PathElement {
+ l := value.FieldList(fields)
+ return PathElement{Key: &l}
+}
+
+// KeyElementByFields creates a new Key PathElement from names and values.
+// `nameValues` must have an even number of entries, alternating
+// names (type must be string) with values (type must be value.Value). If these
+// conditions are not met, KeyByFields will panic--it's intended for static
+// construction and shouldn't have user-produced values passed to it.
+func KeyElementByFields(nameValues ...any) PathElement {
+ return PathElement{Key: KeyByFields(nameValues...)}
+}
+
+// ValueElement creates a new Value PathElement.
+func ValueElement(value value.Value) PathElement {
+ return PathElement{Value: &value}
+}
+
+// IndexElement creates a new Index PathElement.
+func IndexElement(index int) PathElement {
+ return PathElement{Index: &index}
+}
+
// Less provides an order for path elements.
func (e PathElement) Less(rhs PathElement) bool {
return e.Compare(rhs) < 0
@@ -156,6 +187,25 @@ func (e PathElement) String() string {
}
}
+// Copy returns a copy of the PathElement.
+// This is not a full deep copy as any contained value.Value is not copied.
+func (e PathElement) Copy() PathElement {
+ if e.FieldName != nil {
+ return PathElement{FieldName: e.FieldName}
+ }
+ if e.Key != nil {
+ c := e.Key.Copy()
+ return PathElement{Key: &c}
+ }
+ if e.Value != nil {
+ return PathElement{Value: e.Value}
+ }
+ if e.Index != nil {
+ return PathElement{Index: e.Index}
+ }
+ return e // zero value
+}
+
// KeyByFields is a helper function which constructs a key for an associative
// list type. `nameValues` must have an even number of entries, alternating
// names (type must be string) with values (type must be value.Value). If these
@@ -193,6 +243,16 @@ func (spe sortedPathElements) Len() int { return len(spe) }
func (spe sortedPathElements) Less(i, j int) bool { return spe[i].Less(spe[j]) }
func (spe sortedPathElements) Swap(i, j int) { spe[i], spe[j] = spe[j], spe[i] }
+// Copy returns a copy of the PathElementSet.
+// This is not a full deep copy as any contained value.Value is not copied.
+func (s PathElementSet) Copy() PathElementSet {
+ out := make(sortedPathElements, len(s.members))
+ for i := range s.members {
+ out[i] = s.members[i].Copy()
+ }
+ return PathElementSet{members: out}
+}
+
// Insert adds pe to the set.
func (s *PathElementSet) Insert(pe PathElement) {
loc := sort.Search(len(s.members), func(i int) bool {
@@ -315,3 +375,14 @@ func (s *PathElementSet) Iterate(f func(PathElement)) {
f(pe)
}
}
+
+// All iterates over each PathElement in the set. The order is deterministic.
+func (s *PathElementSet) All() iter.Seq[PathElement] {
+ return func(yield func(element PathElement) bool) {
+ for _, pe := range s.members {
+ if !yield(pe) {
+ return
+ }
+ }
+ }
+}
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/fromvalue.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/fromvalue.go
similarity index 98%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/fromvalue.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/fromvalue.go
index 20775ee02..78383e401 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/fromvalue.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/fromvalue.go
@@ -17,7 +17,7 @@ limitations under the License.
package fieldpath
import (
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
// SetFromValue creates a set containing every leaf field mentioned in v.
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/managers.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/managers.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/managers.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/managers.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/path.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/path.go
similarity index 98%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/path.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/path.go
index 0413130bd..a865ec425 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/path.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/path.go
@@ -20,7 +20,7 @@ import (
"fmt"
"strings"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
// Path describes how to select a potentially deeply-nested child field given a
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/pathelementmap.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/pathelementmap.go
similarity index 98%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/pathelementmap.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/pathelementmap.go
index 41fc2474a..ff7ee510c 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/pathelementmap.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/pathelementmap.go
@@ -19,7 +19,7 @@ package fieldpath
import (
"sort"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
// PathElementValueMap is a map from PathElement to value.Value.
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/serialize-pe.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize-pe.go
similarity index 84%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/serialize-pe.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize-pe.go
index cb18e7b1c..f4b00c2ee 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/serialize-pe.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize-pe.go
@@ -24,7 +24,7 @@ import (
"strings"
jsoniter "github.com/json-iterator/go"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
var ErrUnknownPathElementType = errors.New("unknown path element type")
@@ -54,6 +54,24 @@ var (
peSepBytes = []byte(peSeparator)
)
+// readJSONIter reads a Value from a JSON iterator.
+// DO NOT EXPORT
+// TODO: eliminate this https://github.com/kubernetes-sigs/structured-merge-diff/issues/202
+func readJSONIter(iter *jsoniter.Iterator) (value.Value, error) {
+ v := iter.Read()
+ if iter.Error != nil && iter.Error != io.EOF {
+ return nil, iter.Error
+ }
+ return value.NewValueInterface(v), nil
+}
+
+// writeJSONStream writes a value into a JSON stream.
+// DO NOT EXPORT
+// TODO: eliminate this https://github.com/kubernetes-sigs/structured-merge-diff/issues/202
+func writeJSONStream(v value.Value, stream *jsoniter.Stream) {
+ stream.WriteVal(v.Unstructured())
+}
+
// DeserializePathElement parses a serialized path element
func DeserializePathElement(s string) (PathElement, error) {
b := []byte(s)
@@ -75,7 +93,7 @@ func DeserializePathElement(s string) (PathElement, error) {
case peValueSepBytes[0]:
iter := readPool.BorrowIterator(b)
defer readPool.ReturnIterator(iter)
- v, err := value.ReadJSONIter(iter)
+ v, err := readJSONIter(iter)
if err != nil {
return PathElement{}, err
}
@@ -86,7 +104,7 @@ func DeserializePathElement(s string) (PathElement, error) {
fields := value.FieldList{}
iter.ReadObjectCB(func(iter *jsoniter.Iterator, key string) bool {
- v, err := value.ReadJSONIter(iter)
+ v, err := readJSONIter(iter)
if err != nil {
iter.Error = err
return false
@@ -141,14 +159,14 @@ func serializePathElementToWriter(w io.Writer, pe PathElement) error {
stream.WriteMore()
}
stream.WriteObjectField(field.Name)
- value.WriteJSONStream(field.Value, stream)
+ writeJSONStream(field.Value, stream)
}
stream.WriteObjectEnd()
case pe.Value != nil:
if _, err := stream.Write(peValueSepBytes); err != nil {
return err
}
- value.WriteJSONStream(*pe.Value, stream)
+ writeJSONStream(*pe.Value, stream)
case pe.Index != nil:
if _, err := stream.Write(peIndexSepBytes); err != nil {
return err
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/serialize.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/serialize.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/set.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/set.go
similarity index 95%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/set.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/set.go
index 77ae25116..d2d8c8a42 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/set.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/set.go
@@ -18,11 +18,13 @@ package fieldpath
import (
"fmt"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "iter"
"sort"
"strings"
- "sigs.k8s.io/structured-merge-diff/v4/schema"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
+
+ "sigs.k8s.io/structured-merge-diff/v6/schema"
)
// Set identifies a set of fields.
@@ -46,6 +48,15 @@ func NewSet(paths ...Path) *Set {
return s
}
+// Copy returns a copy of the Set.
+// This is not a full deep copy as any contained value.Value is not copied.
+func (s *Set) Copy() *Set {
+ return &Set{
+ Members: s.Members.Copy(),
+ Children: s.Children.Copy(),
+ }
+}
+
// Insert adds the field identified by `p` to the set. Important: parent fields
// are NOT added to the set; if that is desired, they must be added separately.
func (s *Set) Insert(p Path) {
@@ -385,6 +396,15 @@ func (s *Set) Iterate(f func(Path)) {
s.iteratePrefix(Path{}, f)
}
+// All iterates over each Path in the set (preorder DFS).
+func (s *Set) All() iter.Seq[Path] {
+ return func(yield func(Path) bool) {
+ s.Iterate(func(p Path) {
+ yield(p)
+ })
+ }
+}
+
func (s *Set) iteratePrefix(prefix Path, f func(Path)) {
s.Members.Iterate(func(pe PathElement) { f(append(prefix, pe)) })
s.Children.iteratePrefix(prefix, f)
@@ -454,6 +474,16 @@ func (s sortedSetNode) Len() int { return len(s) }
func (s sortedSetNode) Less(i, j int) bool { return s[i].pathElement.Less(s[j].pathElement) }
func (s sortedSetNode) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+// Copy returns a copy of the SetNodeMap.
+// This is not a full deep copy as any contained value.Value is not copied.
+func (s *SetNodeMap) Copy() SetNodeMap {
+ out := make(sortedSetNode, len(s.members))
+ for i, v := range s.members {
+ out[i] = setNode{pathElement: v.pathElement.Copy(), set: v.set.Copy()}
+ }
+ return SetNodeMap{members: out}
+}
+
// Descend adds pe to the set if necessary, returning the associated subset.
func (s *SetNodeMap) Descend(pe PathElement) *Set {
loc := sort.Search(len(s.members), func(i int) bool {
@@ -704,6 +734,15 @@ func (s *SetNodeMap) Iterate(f func(PathElement)) {
}
}
+// All iterates over each PathElement in the set.
+func (s *SetNodeMap) All() iter.Seq[PathElement] {
+ return func(yield func(PathElement) bool) {
+ s.Iterate(func(pe PathElement) {
+ yield(pe)
+ })
+ }
+}
+
func (s *SetNodeMap) iteratePrefix(prefix Path, f func(Path)) {
for _, n := range s.members {
pe := n.pathElement
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/merge/conflict.go
similarity index 98%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/merge/conflict.go
index f1aa25860..dea64707b 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/merge/conflict.go
@@ -21,7 +21,7 @@ import (
"sort"
"strings"
- "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v6/fieldpath"
)
// Conflict is a conflict on a specific field with the current manager of
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/merge/update.go
similarity index 88%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/merge/update.go
index 34ab2d6fb..99d722f87 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/merge/update.go
@@ -15,9 +15,10 @@ package merge
import (
"fmt"
- "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
- "sigs.k8s.io/structured-merge-diff/v4/typed"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+
+ "sigs.k8s.io/structured-merge-diff/v6/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v6/typed"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
// Converter is an interface to the conversion logic. The converter
@@ -33,6 +34,9 @@ type UpdaterBuilder struct {
Converter Converter
IgnoreFilter map[fieldpath.APIVersion]fieldpath.Filter
+ // IgnoredFields provides a set of fields to ignore for each
+ IgnoredFields map[fieldpath.APIVersion]*fieldpath.Set
+
// Stop comparing the new object with old object after applying.
// This was initially used to avoid spurious etcd update, but
// since that's vastly inefficient, we've come-up with a better
@@ -46,6 +50,7 @@ func (u *UpdaterBuilder) BuildUpdater() *Updater {
return &Updater{
Converter: u.Converter,
IgnoreFilter: u.IgnoreFilter,
+ IgnoredFields: u.IgnoredFields,
returnInputOnNoop: u.ReturnInputOnNoop,
}
}
@@ -56,6 +61,9 @@ type Updater struct {
// Deprecated: This will eventually become private.
Converter Converter
+ // Deprecated: This will eventually become private.
+ IgnoredFields map[fieldpath.APIVersion]*fieldpath.Set
+
// Deprecated: This will eventually become private.
IgnoreFilter map[fieldpath.APIVersion]fieldpath.Filter
@@ -70,8 +78,19 @@ func (s *Updater) update(oldObject, newObject *typed.TypedValue, version fieldpa
return nil, nil, fmt.Errorf("failed to compare objects: %v", err)
}
- versions := map[fieldpath.APIVersion]*typed.Comparison{
- version: compare.FilterFields(s.IgnoreFilter[version]),
+ var versions map[fieldpath.APIVersion]*typed.Comparison
+
+ if s.IgnoredFields != nil && s.IgnoreFilter != nil {
+ return nil, nil, fmt.Errorf("IgnoreFilter and IgnoreFilter may not both be set")
+ }
+ if s.IgnoredFields != nil {
+ versions = map[fieldpath.APIVersion]*typed.Comparison{
+ version: compare.ExcludeFields(s.IgnoredFields[version]),
+ }
+ } else {
+ versions = map[fieldpath.APIVersion]*typed.Comparison{
+ version: compare.FilterFields(s.IgnoreFilter[version]),
+ }
}
for manager, managerSet := range managers {
@@ -101,7 +120,12 @@ func (s *Updater) update(oldObject, newObject *typed.TypedValue, version fieldpa
if err != nil {
return nil, nil, fmt.Errorf("failed to compare objects: %v", err)
}
- versions[managerSet.APIVersion()] = compare.FilterFields(s.IgnoreFilter[managerSet.APIVersion()])
+
+ if s.IgnoredFields != nil {
+ versions[managerSet.APIVersion()] = compare.ExcludeFields(s.IgnoredFields[managerSet.APIVersion()])
+ } else {
+ versions[managerSet.APIVersion()] = compare.FilterFields(s.IgnoreFilter[managerSet.APIVersion()])
+ }
}
conflictSet := managerSet.Set().Intersection(compare.Modified.Union(compare.Added))
@@ -154,7 +178,16 @@ func (s *Updater) Update(liveObject, newObject *typed.TypedValue, version fieldp
managers[manager] = fieldpath.NewVersionedSet(fieldpath.NewSet(), version, false)
}
set := managers[manager].Set().Difference(compare.Removed).Union(compare.Modified).Union(compare.Added)
- ignoreFilter := s.IgnoreFilter[version]
+
+ if s.IgnoredFields != nil && s.IgnoreFilter != nil {
+ return nil, nil, fmt.Errorf("IgnoreFilter and IgnoreFilter may not both be set")
+ }
+ var ignoreFilter fieldpath.Filter
+ if s.IgnoredFields != nil {
+ ignoreFilter = fieldpath.NewExcludeSetFilter(s.IgnoredFields[version])
+ } else {
+ ignoreFilter = s.IgnoreFilter[version]
+ }
if ignoreFilter != nil {
set = ignoreFilter.Filter(set)
}
@@ -189,7 +222,15 @@ func (s *Updater) Apply(liveObject, configObject *typed.TypedValue, version fiel
return nil, fieldpath.ManagedFields{}, fmt.Errorf("failed to get field set: %v", err)
}
- ignoreFilter := s.IgnoreFilter[version]
+ if s.IgnoredFields != nil && s.IgnoreFilter != nil {
+ return nil, nil, fmt.Errorf("IgnoreFilter and IgnoreFilter may not both be set")
+ }
+ var ignoreFilter fieldpath.Filter
+ if s.IgnoredFields != nil {
+ ignoreFilter = fieldpath.NewExcludeSetFilter(s.IgnoredFields[version])
+ } else {
+ ignoreFilter = s.IgnoreFilter[version]
+ }
if ignoreFilter != nil {
set = ignoreFilter.Filter(set)
}
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/doc.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/doc.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/schema/doc.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/schema/doc.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/compare.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/compare.go
similarity index 98%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/typed/compare.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/typed/compare.go
index 5fffa5e2c..488251f64 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/compare.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/compare.go
@@ -20,9 +20,9 @@ import (
"fmt"
"strings"
- "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
- "sigs.k8s.io/structured-merge-diff/v4/schema"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v6/schema"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
// Comparison is the return value of a TypedValue.Compare() operation.
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/doc.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/doc.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/typed/doc.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/typed/doc.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/helpers.go
similarity index 93%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/typed/helpers.go
index 78fdb0e75..8a9c0b50e 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/helpers.go
@@ -21,9 +21,9 @@ import (
"fmt"
"strings"
- "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
- "sigs.k8s.io/structured-merge-diff/v4/schema"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v6/schema"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
// ValidationError reports an error about a particular field
@@ -217,9 +217,16 @@ func keyedAssociativeListItemToPathElement(a value.Allocator, s *schema.Schema,
} else if def != nil {
keyMap = append(keyMap, value.Field{Name: fieldName, Value: value.NewValueInterface(def)})
} else {
- return pe, fmt.Errorf("associative list with keys has an element that omits key field %q (and doesn't have default value)", fieldName)
+ // Don't add the key to the key field list.
+ // A key field list where it is set then represents a different entry
+ // in the associate list.
}
}
+
+ if len(list.Keys) > 0 && len(keyMap) == 0 {
+ return pe, fmt.Errorf("associative list with keys has an element that omits all key fields %q (and doesn't have default values for any key fields)", list.Keys)
+ }
+
keyMap.Sort()
pe.Key = &keyMap
return pe, nil
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/merge.go
similarity index 98%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/typed/merge.go
index fa227ac40..f8ca9aba8 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/merge.go
@@ -17,9 +17,9 @@ limitations under the License.
package typed
import (
- "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
- "sigs.k8s.io/structured-merge-diff/v4/schema"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v6/schema"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
type mergingWalker struct {
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/parser.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/parser.go
similarity index 97%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/typed/parser.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/typed/parser.go
index 0e9f7cc7e..c46e69f21 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/parser.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/parser.go
@@ -19,9 +19,9 @@ package typed
import (
"fmt"
- "sigs.k8s.io/structured-merge-diff/v4/schema"
- "sigs.k8s.io/structured-merge-diff/v4/value"
- yaml "sigs.k8s.io/yaml/goyaml.v2"
+ yaml "go.yaml.in/yaml/v2"
+ "sigs.k8s.io/structured-merge-diff/v6/schema"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
// YAMLObject is an object encoded in YAML.
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/reconcile_schema.go
similarity index 98%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/typed/reconcile_schema.go
index 6a7697e3b..9b20e54aa 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/reconcile_schema.go
@@ -20,8 +20,8 @@ import (
"fmt"
"sync"
- "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
- "sigs.k8s.io/structured-merge-diff/v4/schema"
+ "sigs.k8s.io/structured-merge-diff/v6/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v6/schema"
)
var fmPool = sync.Pool{
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/remove.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/remove.go
similarity index 97%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/typed/remove.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/typed/remove.go
index ad071ee8f..86de5105d 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/remove.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/remove.go
@@ -14,9 +14,9 @@ limitations under the License.
package typed
import (
- "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
- "sigs.k8s.io/structured-merge-diff/v4/schema"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v6/schema"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
type removingWalker struct {
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/tofieldset.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/tofieldset.go
similarity index 96%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/typed/tofieldset.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/typed/tofieldset.go
index d563a87ee..a52e342e0 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/tofieldset.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/tofieldset.go
@@ -19,9 +19,9 @@ package typed
import (
"sync"
- "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
- "sigs.k8s.io/structured-merge-diff/v4/schema"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v6/schema"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
var tPool = sync.Pool{
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/typed.go
similarity index 81%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/typed/typed.go
index 9be902828..0f9968fd9 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/typed.go
@@ -19,9 +19,9 @@ package typed
import (
"sync"
- "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
- "sigs.k8s.io/structured-merge-diff/v4/schema"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v6/schema"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
// ValidationOptions is the list of all the options available when running the validation.
@@ -32,6 +32,21 @@ const (
AllowDuplicates ValidationOptions = iota
)
+// extractItemsOptions is the options available when extracting items.
+type extractItemsOptions struct {
+ appendKeyFields bool
+}
+
+type ExtractItemsOption func(*extractItemsOptions)
+
+// WithAppendKeyFields configures ExtractItems to include key fields.
+// It is exported for use in configuring ExtractItems.
+func WithAppendKeyFields() ExtractItemsOption {
+ return func(opts *extractItemsOptions) {
+ opts.appendKeyFields = true
+ }
+}
+
// AsTyped accepts a value and a type and returns a TypedValue. 'v' must have
// type 'typeName' in the schema. An error is returned if the v doesn't conform
// to the schema.
@@ -187,7 +202,37 @@ func (tv TypedValue) RemoveItems(items *fieldpath.Set) *TypedValue {
}
// ExtractItems returns a value with only the provided list or map items extracted from the value.
-func (tv TypedValue) ExtractItems(items *fieldpath.Set) *TypedValue {
+func (tv TypedValue) ExtractItems(items *fieldpath.Set, opts ...ExtractItemsOption) *TypedValue {
+ options := &extractItemsOptions{}
+ for _, opt := range opts {
+ opt(options)
+ }
+ if options.appendKeyFields {
+ tvPathSet, err := tv.ToFieldSet()
+ if err == nil {
+ keyFieldPathSet := fieldpath.NewSet()
+ items.Iterate(func(path fieldpath.Path) {
+ if !tvPathSet.Has(path) {
+ return
+ }
+ for i, pe := range path {
+ if pe.Key == nil {
+ continue
+ }
+ for _, keyField := range *pe.Key {
+ keyName := keyField.Name
+ // Create a new slice with the same elements as path[:i+1], but set its capacity to len(path[:i+1]).
+ // This ensures that appending to keyFieldPath creates a new underlying array, avoiding accidental
+ // modification of the original slice (path).
+ keyFieldPath := append(path[:i+1:i+1], fieldpath.PathElement{FieldName: &keyName})
+ keyFieldPathSet.Insert(keyFieldPath)
+ }
+ }
+ })
+ items = items.Union(keyFieldPathSet)
+ }
+ }
+
tv.value = removeItemsWithSchema(tv.value, items, tv.schema, tv.typeRef, true)
return &tv
}
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/validate.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/validate.go
similarity index 96%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/typed/validate.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/typed/validate.go
index 652e24c81..3371f87b9 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/validate.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/validate.go
@@ -19,9 +19,9 @@ package typed
import (
"sync"
- "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
- "sigs.k8s.io/structured-merge-diff/v4/schema"
- "sigs.k8s.io/structured-merge-diff/v4/value"
+ "sigs.k8s.io/structured-merge-diff/v6/fieldpath"
+ "sigs.k8s.io/structured-merge-diff/v6/schema"
+ "sigs.k8s.io/structured-merge-diff/v6/value"
)
var vPool = sync.Pool{
@@ -157,7 +157,7 @@ func (v *validatingObjectWalker) visitListItems(t *schema.List, list value.List)
func (v *validatingObjectWalker) doList(t *schema.List) (errs ValidationErrors) {
list, err := listValue(v.allocator, v.value)
if err != nil {
- return errorf(err.Error())
+ return errorf("%v", err)
}
if list == nil {
@@ -193,7 +193,7 @@ func (v *validatingObjectWalker) visitMapItems(t *schema.Map, m value.Map) (errs
func (v *validatingObjectWalker) doMap(t *schema.Map) (errs ValidationErrors) {
m, err := mapValue(v.allocator, v.value)
if err != nil {
- return errorf(err.Error())
+ return errorf("%v", err)
}
if m == nil {
return nil
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/allocator.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/allocator.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/allocator.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/allocator.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/doc.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/doc.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/doc.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/doc.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/fields.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/fields.go
similarity index 92%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/fields.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/fields.go
index be3c67249..042b04873 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/fields.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/fields.go
@@ -31,6 +31,14 @@ type Field struct {
// have a different name.
type FieldList []Field
+// Copy returns a copy of the FieldList.
+// Values are not copied.
+func (f FieldList) Copy() FieldList {
+ c := make(FieldList, len(f))
+ copy(c, f)
+ return c
+}
+
// Sort sorts the field list by Name.
func (f FieldList) Sort() {
if len(f) < 2 {
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/jsontagutil.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/jsontagutil.go
similarity index 57%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/jsontagutil.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/jsontagutil.go
index d4adb8fc9..3aadceb22 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/jsontagutil.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/jsontagutil.go
@@ -22,22 +22,77 @@ import (
"strings"
)
+type isZeroer interface {
+ IsZero() bool
+}
+
+var isZeroerType = reflect.TypeOf((*isZeroer)(nil)).Elem()
+
+func reflectIsZero(dv reflect.Value) bool {
+ return dv.IsZero()
+}
+
+// OmitZeroFunc returns a function for a type for a given struct field
+// which determines if the value for that field is a zero value, matching
+// how the stdlib JSON implementation.
+func OmitZeroFunc(t reflect.Type) func(reflect.Value) bool {
+ // Provide a function that uses a type's IsZero method.
+ // This matches the go 1.24 custom IsZero() implementation matching
+ switch {
+ case t.Kind() == reflect.Interface && t.Implements(isZeroerType):
+ return func(v reflect.Value) bool {
+ // Avoid panics calling IsZero on a nil interface or
+ // non-nil interface with nil pointer.
+ return safeIsNil(v) ||
+ (v.Elem().Kind() == reflect.Pointer && v.Elem().IsNil()) ||
+ v.Interface().(isZeroer).IsZero()
+ }
+ case t.Kind() == reflect.Pointer && t.Implements(isZeroerType):
+ return func(v reflect.Value) bool {
+ // Avoid panics calling IsZero on nil pointer.
+ return safeIsNil(v) || v.Interface().(isZeroer).IsZero()
+ }
+ case t.Implements(isZeroerType):
+ return func(v reflect.Value) bool {
+ return v.Interface().(isZeroer).IsZero()
+ }
+ case reflect.PointerTo(t).Implements(isZeroerType):
+ return func(v reflect.Value) bool {
+ if !v.CanAddr() {
+ // Temporarily box v so we can take the address.
+ v2 := reflect.New(v.Type()).Elem()
+ v2.Set(v)
+ v = v2
+ }
+ return v.Addr().Interface().(isZeroer).IsZero()
+ }
+ default:
+ // default to the reflect.IsZero implementation
+ return reflectIsZero
+ }
+}
+
// TODO: This implements the same functionality as https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/converter.go#L236
// but is based on the highly efficient approach from https://golang.org/src/encoding/json/encode.go
-func lookupJsonTags(f reflect.StructField) (name string, omit bool, inline bool, omitempty bool) {
+func lookupJsonTags(f reflect.StructField) (name string, omit bool, inline bool, omitempty bool, omitzero func(reflect.Value) bool) {
tag := f.Tag.Get("json")
if tag == "-" {
- return "", true, false, false
+ return "", true, false, false, nil
}
name, opts := parseTag(tag)
if name == "" {
name = f.Name
}
- return name, false, opts.Contains("inline"), opts.Contains("omitempty")
+
+ if opts.Contains("omitzero") {
+ omitzero = OmitZeroFunc(f.Type)
+ }
+
+ return name, false, opts.Contains("inline"), opts.Contains("omitempty"), omitzero
}
-func isZero(v reflect.Value) bool {
+func isEmpty(v reflect.Value) bool {
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == 0
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/list.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/list.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/list.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/list.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/listreflect.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/listreflect.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/listreflect.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/listreflect.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/listunstructured.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/listunstructured.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/listunstructured.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/listunstructured.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/map.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/map.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/map.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/map.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapreflect.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/mapreflect.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapreflect.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/mapreflect.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapunstructured.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/mapunstructured.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapunstructured.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/mapunstructured.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/reflectcache.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/reflectcache.go
similarity index 97%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/reflectcache.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/reflectcache.go
index 88693b87e..3b4a402ee 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/reflectcache.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/reflectcache.go
@@ -59,6 +59,8 @@ type FieldCacheEntry struct {
JsonName string
// isOmitEmpty is true if the field has the json 'omitempty' tag.
isOmitEmpty bool
+ // omitzero is set if the field has the json 'omitzero' tag.
+ omitzero func(reflect.Value) bool
// fieldPath is a list of field indices (see FieldByIndex) to lookup the value of
// a field in a reflect.Value struct. The field indices in the list form a path used
// to traverse through intermediary 'inline' fields.
@@ -69,7 +71,13 @@ type FieldCacheEntry struct {
}
func (f *FieldCacheEntry) CanOmit(fieldVal reflect.Value) bool {
- return f.isOmitEmpty && (safeIsNil(fieldVal) || isZero(fieldVal))
+ if f.isOmitEmpty && (safeIsNil(fieldVal) || isEmpty(fieldVal)) {
+ return true
+ }
+ if f.omitzero != nil && f.omitzero(fieldVal) {
+ return true
+ }
+ return false
}
// GetFrom returns the field identified by this FieldCacheEntry from the provided struct.
@@ -147,7 +155,7 @@ func typeReflectEntryOf(cm reflectCacheMap, t reflect.Type, updates reflectCache
func buildStructCacheEntry(t reflect.Type, infos map[string]*FieldCacheEntry, fieldPath [][]int) {
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
- jsonName, omit, isInline, isOmitempty := lookupJsonTags(field)
+ jsonName, omit, isInline, isOmitempty, omitzero := lookupJsonTags(field)
if omit {
continue
}
@@ -161,7 +169,7 @@ func buildStructCacheEntry(t reflect.Type, infos map[string]*FieldCacheEntry, fi
}
continue
}
- info := &FieldCacheEntry{JsonName: jsonName, isOmitEmpty: isOmitempty, fieldPath: append(fieldPath, field.Index), fieldType: field.Type}
+ info := &FieldCacheEntry{JsonName: jsonName, isOmitEmpty: isOmitempty, omitzero: omitzero, fieldPath: append(fieldPath, field.Index), fieldType: field.Type}
infos[jsonName] = info
}
}
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/scalar.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/scalar.go
similarity index 97%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/scalar.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/scalar.go
index c78a4c18d..5824219e5 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/scalar.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/scalar.go
@@ -43,7 +43,7 @@ func IntCompare(lhs, rhs int64) int {
func BoolCompare(lhs, rhs bool) int {
if lhs == rhs {
return 0
- } else if lhs == false {
+ } else if !lhs {
return -1
}
return 1
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/structreflect.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/structreflect.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/structreflect.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/structreflect.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/value.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/value.go
similarity index 94%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/value.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/value.go
index f72e5cd25..140b99038 100644
--- a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/value.go
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/value.go
@@ -23,7 +23,8 @@ import (
"strings"
jsoniter "github.com/json-iterator/go"
- yaml "sigs.k8s.io/yaml/goyaml.v2"
+
+ yaml "go.yaml.in/yaml/v2"
)
var (
@@ -90,7 +91,7 @@ func FromJSON(input []byte) (Value, error) {
func FromJSONFast(input []byte) (Value, error) {
iter := readPool.BorrowIterator(input)
defer readPool.ReturnIterator(iter)
- return ReadJSONIter(iter)
+ return readJSONIter(iter)
}
// ToJSON is a helper function for producing a JSon document.
@@ -98,7 +99,7 @@ func ToJSON(v Value) ([]byte, error) {
buf := bytes.Buffer{}
stream := writePool.BorrowStream(&buf)
defer writePool.ReturnStream(stream)
- WriteJSONStream(v, stream)
+ writeJSONStream(v, stream)
b := stream.Buffer()
err := stream.Flush()
// Help jsoniter manage its buffers--without this, the next
@@ -109,8 +110,10 @@ func ToJSON(v Value) ([]byte, error) {
return buf.Bytes(), err
}
-// ReadJSONIter reads a Value from a JSON iterator.
-func ReadJSONIter(iter *jsoniter.Iterator) (Value, error) {
+// readJSONIter reads a Value from a JSON iterator.
+// DO NOT EXPORT
+// TODO: eliminate this https://github.com/kubernetes-sigs/structured-merge-diff/issues/202
+func readJSONIter(iter *jsoniter.Iterator) (Value, error) {
v := iter.Read()
if iter.Error != nil && iter.Error != io.EOF {
return nil, iter.Error
@@ -118,8 +121,10 @@ func ReadJSONIter(iter *jsoniter.Iterator) (Value, error) {
return NewValueInterface(v), nil
}
-// WriteJSONStream writes a value into a JSON stream.
-func WriteJSONStream(v Value, stream *jsoniter.Stream) {
+// writeJSONStream writes a value into a JSON stream.
+// DO NOT EXPORT
+// TODO: eliminate this https://github.com/kubernetes-sigs/structured-merge-diff/issues/202
+func writeJSONStream(v Value, stream *jsoniter.Stream) {
stream.WriteVal(v.Unstructured())
}
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/valuereflect.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/valuereflect.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/valuereflect.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/valuereflect.go
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/valueunstructured.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/valueunstructured.go
similarity index 100%
rename from vendor/sigs.k8s.io/structured-merge-diff/v4/value/valueunstructured.go
rename to vendor/sigs.k8s.io/structured-merge-diff/v6/value/valueunstructured.go
diff --git a/vendor/sigs.k8s.io/yaml/.travis.yml b/vendor/sigs.k8s.io/yaml/.travis.yml
deleted file mode 100644
index 54ed8f9cb..000000000
--- a/vendor/sigs.k8s.io/yaml/.travis.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-language: go
-arch: arm64
-dist: focal
-go: 1.15.x
-script:
- - diff -u <(echo -n) <(gofmt -d *.go)
- - diff -u <(echo -n) <(golint $(go list -e ./...) | grep -v YAMLToJSON)
- - GO111MODULE=on go vet .
- - GO111MODULE=on go test -v -race ./...
- - git diff --exit-code
-install:
- - GO111MODULE=off go get golang.org/x/lint/golint
diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/OWNERS b/vendor/sigs.k8s.io/yaml/goyaml.v2/OWNERS
deleted file mode 100644
index 73be0a3a9..000000000
--- a/vendor/sigs.k8s.io/yaml/goyaml.v2/OWNERS
+++ /dev/null
@@ -1,24 +0,0 @@
-# See the OWNERS docs at https://go.k8s.io/owners
-
-approvers:
-- dims
-- jpbetz
-- smarterclayton
-- deads2k
-- sttts
-- liggitt
-- natasha41575
-- knverey
-reviewers:
-- dims
-- thockin
-- jpbetz
-- smarterclayton
-- deads2k
-- derekwaynecarr
-- mikedanese
-- liggitt
-- sttts
-- tallclair
-labels:
-- sig/api-machinery
diff --git a/vendor/sigs.k8s.io/yaml/yaml.go b/vendor/sigs.k8s.io/yaml/yaml.go
index fc10246bd..aa01acd45 100644
--- a/vendor/sigs.k8s.io/yaml/yaml.go
+++ b/vendor/sigs.k8s.io/yaml/yaml.go
@@ -24,7 +24,7 @@ import (
"reflect"
"strconv"
- "sigs.k8s.io/yaml/goyaml.v2"
+ "go.yaml.in/yaml/v2"
)
// Marshal marshals obj into JSON using stdlib json.Marshal, and then converts JSON to YAML using JSONToYAML (see that method for more reference)
@@ -92,7 +92,7 @@ func jsonUnmarshal(reader io.Reader, obj interface{}, opts ...JSONOpt) error {
d = opt(d)
}
if err := d.Decode(&obj); err != nil {
- return fmt.Errorf("while decoding JSON: %v", err)
+ return fmt.Errorf("while decoding JSON: %w", err)
}
return nil
}
@@ -417,3 +417,10 @@ func jsonToYAMLValue(j interface{}) interface{} {
}
return j
}
+
+// DisallowUnknownFields configures the JSON decoder to error out if unknown
+// fields come along, instead of dropping them by default.
+func DisallowUnknownFields(d *json.Decoder) *json.Decoder {
+ d.DisallowUnknownFields()
+ return d
+}