From e1a32cf66f6717eb2c5ec5a888389394af3c85c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 12:01:47 +0000 Subject: [PATCH 1/4] Bump sigs.k8s.io/controller-runtime from 0.16.3 to 0.17.0 Bumps [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) from 0.16.3 to 0.17.0. - [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases) - [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md) - [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.16.3...v0.17.0) --- updated-dependencies: - dependency-name: sigs.k8s.io/controller-runtime dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 42 ++++++++++---------- go.sum | 121 ++++++++++++++++++++++++--------------------------------- 2 files changed, 72 insertions(+), 91 deletions(-) diff --git a/go.mod b/go.mod index 7e844a03..8cf6da79 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/michaelklishin/rabbit-hole/v2 v2.16.0 github.com/onsi/ginkgo/v2 v2.15.0 github.com/onsi/gomega v1.31.1 - github.com/rabbitmq/cluster-operator/v2 v2.7.0 + github.com/rabbitmq/cluster-operator/v2 v2.6.0 github.com/sclevine/yj v0.0.0-20200815061347-554173e71934 gopkg.in/ini.v1 v1.67.0 k8s.io/api v0.29.1 @@ -22,9 +22,9 @@ require ( k8s.io/client-go v0.29.1 k8s.io/code-generator v0.29.1 k8s.io/klog/v2 v2.120.1 - k8s.io/kube-openapi v0.0.0-20240105020646-a37d4de58910 - k8s.io/utils v0.0.0-20240102154912-e7106e64919e - sigs.k8s.io/controller-runtime v0.16.3 + k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e + k8s.io/utils v0.0.0-20230726121419-3b25d923346b + sigs.k8s.io/controller-runtime v0.17.0 sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20231121004636-2154ffbc22e2 sigs.k8s.io/controller-tools v0.14.0 sigs.k8s.io/kustomize/kustomize/v5 v5.3.0 @@ -38,28 +38,28 @@ require ( github.com/cenkalti/backoff/v3 v3.0.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.11.1 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.7.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.7.0 // indirect + github.com/evanphx/json-patch/v5 v5.8.0 // indirect github.com/fatih/color v1.16.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-errors/errors v1.5.0 // indirect github.com/go-jose/go-jose/v3 v3.0.1 // indirect github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.20.2 // indirect - github.com/go-openapi/jsonreference v0.20.4 // indirect - github.com/go-openapi/swag v0.22.7 // indirect + github.com/go-openapi/jsonpointer v0.20.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.4 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gobuffalo/flect v1.0.2 // indirect github.com/goccy/go-yaml v1.11.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/certificate-transparency-go v1.1.7 // indirect + github.com/google/certificate-transparency-go v1.1.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect + github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -74,7 +74,7 @@ require ( github.com/huandu/xstrings v1.3.3 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jmoiron/sqlx v1.3.5 // indirect + github.com/jmoiron/sqlx v1.3.3 // 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 @@ -89,7 +89,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml v1.9.4 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect @@ -99,27 +99,27 @@ require ( github.com/spf13/afero v1.6.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/weppos/publicsuffix-go v0.30.2-0.20230730094716-a20f9abcc222 // indirect + github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b // indirect github.com/xlab/treeprint v1.2.0 // indirect - github.com/zmap/zcrypto v0.0.0-20231219022726-a1f61fb1661c // indirect - github.com/zmap/zlint/v3 v3.6.0 // indirect + github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc // indirect + github.com/zmap/zlint/v3 v3.1.0 // indirect go.starlark.net v0.0.0-20230912135651-745481cf39ed // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.20.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect + golang.org/x/oauth2 v0.12.0 // indirect golang.org/x/sys v0.16.0 // indirect golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.5.0 // indirect + golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.17.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/protobuf v1.32.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/evanphx/json-patch.v5 v5.6.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index c0bd7a5a..03632287 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,4 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= @@ -7,12 +6,10 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -24,21 +21,21 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cfssl v1.6.4 h1:NMOvfrEjFfC63K3SGXgAnFdsgkmiq4kATme5BfcqrO8= github.com/cloudflare/cfssl v1.6.4/go.mod h1:8b3CQMxfWPAeom3zBnGJ6sd+G1NkL5TXqmDXacb+1J0= -github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/elastic/crd-ref-docs v0.0.10 h1:FAc9oCxxY4+rMCLSLtTGrEaPyuxmp3LNlQ+dZfG9Ujc= github.com/elastic/crd-ref-docs v0.0.10/go.mod h1:zha4djxzWirfx+c4fl/Kmk9Rc7Fv7XBoOi9CL9kne+M= -github.com/emicklei/go-restful/v3 v3.11.1 h1:S+9bSbua1z3FgCnV0KKOSSZ3mDthb5NyEPL5gEpCvyk= -github.com/emicklei/go-restful/v3 v3.11.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= -github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= +github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= @@ -58,16 +55,18 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= -github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8= -github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= +github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= @@ -96,8 +95,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/certificate-transparency-go v1.1.7 h1:IASD+NtgSTJLPdzkthwvAG1ZVbF2WtFg4IvoA68XGSw= -github.com/google/certificate-transparency-go v1.1.7/go.mod h1:FSSBo8fyMVgqptbfF6j5p/XNdgQftAhSmXcIxV9iphE= +github.com/google/certificate-transparency-go v1.1.4 h1:hCyXHDbtqlr/lMXU0D4WgbalXL0Zk4dSWWMbPV8VrqY= +github.com/google/certificate-transparency-go v1.1.4/go.mod h1:D6lvbfwckhNrbM9WVl1EVeMOyzC19mpIjMOI4nxBHtQ= github.com/google/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.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -106,21 +105,18 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github/v50 v50.2.0/go.mod h1:VBY8FB6yPIjrtKhozXv4FQupxKLS6H4m6xFZlT43q8Q= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.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-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ= +github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -160,8 +156,8 @@ github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= -github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/jmoiron/sqlx v1.3.3 h1:j82X0bf7oQ27XeqxicSZsTU5suPwKElg3oyxNn43iTk= +github.com/jmoiron/sqlx v1.3.3/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -177,6 +173,7 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= @@ -217,7 +214,6 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= -github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= 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/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -269,8 +265,8 @@ github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -289,9 +285,9 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rabbitmq/amqp091-go v1.9.0 h1:qrQtyzB4H8BQgEuJwhmVQqVHB9O4+MNDJCCAcpc3Aoo= github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc= -github.com/rabbitmq/cluster-operator/v2 v2.7.0 h1:DqyMucZrzD31hkAnznEiAf1W+KWC0sRdu6bDTtLp7LY= -github.com/rabbitmq/cluster-operator/v2 v2.7.0/go.mod h1:i4J22uZ+nGAPDLtORnF/yfdIL2tQp+bUN+RfY6qj20U= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rabbitmq/cluster-operator/v2 v2.6.0 h1:pr42elurQgi4DVmLTI1cOh8VZRNkfFKZK9+FgQuM/8w= +github.com/rabbitmq/cluster-operator/v2 v2.6.0/go.mod h1:Zryxg5YgbPUFcLSCcKpf10il8kIRAK5HloNo6khhdis= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= @@ -299,10 +295,9 @@ github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIH github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8= github.com/sclevine/yj v0.0.0-20200815061347-554173e71934 h1:HQgRgQK9d7cDKkRTS9zlvd6agG3yg7E4Q1ChdHgPs6Y= github.com/sclevine/yj v0.0.0-20200815061347-554173e71934/go.mod h1:AeGluipFgaqcTzUkgIazjEUPD+xbrS9qmLUE1TO1xpo= -github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= @@ -324,9 +319,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/weppos/publicsuffix-go v0.13.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= -github.com/weppos/publicsuffix-go v0.30.2-0.20230730094716-a20f9abcc222 h1:h2JizvZl9aIj6za9S5AyrkU+OzIS4CetQthH/ejO+lg= -github.com/weppos/publicsuffix-go v0.30.2-0.20230730094716-a20f9abcc222/go.mod h1:s41lQh6dIsDWIC1OWh7ChWJXLH0zkJ9KHZVqA7vHyuQ= +github.com/weppos/publicsuffix-go v0.13.1-0.20210123135404-5fd73613514e/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= +github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b h1:FsyNrX12e5BkplJq7wKOLk0+C6LZ+KGXvuEcKUYm5ss= +github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -334,16 +329,12 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= -github.com/zmap/rc2 v0.0.0-20190804163417-abaa70531248/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= -github.com/zmap/zcertificate v0.0.1/go.mod h1:q0dlN54Jm4NVSSuzisusQY0hqDWvu92C+TWveAxiVWk= -github.com/zmap/zcrypto v0.0.0-20201128221613-3719af1573cf/go.mod h1:aPM7r+JOkfL+9qSB4KbYjtoEzJqUK50EXkkJabeNJDQ= -github.com/zmap/zcrypto v0.0.0-20201211161100-e54a5822fb7e/go.mod h1:aPM7r+JOkfL+9qSB4KbYjtoEzJqUK50EXkkJabeNJDQ= -github.com/zmap/zcrypto v0.0.0-20231219022726-a1f61fb1661c h1:U1b4THKcgOpJ+kILupuznNwPiURtwVW3e9alJvji9+s= -github.com/zmap/zcrypto v0.0.0-20231219022726-a1f61fb1661c/go.mod h1:GSDpFDD4TASObxvfZfvpZZ3OWHIUHMlhVWlkOe4ewVk= -github.com/zmap/zlint/v3 v3.0.0/go.mod h1:paGwFySdHIBEMJ61YjoqT4h7Ge+fdYG4sUQhnTb1lJ8= -github.com/zmap/zlint/v3 v3.6.0 h1:vTEaDRtYN0d/1Ax60T+ypvbLQUHwHxbvYRnUMVr35ug= -github.com/zmap/zlint/v3 v3.6.0/go.mod h1:NVgiIWssgzp0bNl8P4Gz94NHV2ep/4Jyj9V69uTmZyg= +github.com/zmap/zcrypto v0.0.0-20210123152837-9cf5beac6d91/go.mod h1:R/deQh6+tSWlgI9tb4jNmXxn8nSCabl5ZQsBX9//I/E= +github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc h1:zkGwegkOW709y0oiAraH/3D8njopUR/pARHv4tZZ6pw= +github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc/go.mod h1:FM4U1E3NzlNMRnSUTU3P1UdukWhYGifqEsjk9fn7BCk= +github.com/zmap/zlint/v3 v3.1.0 h1:WjVytZo79m/L1+/Mlphl09WBob6YTGljN5IGWZFpAv0= +github.com/zmap/zlint/v3 v3.1.0/go.mod h1:L7t8s3sEKkb0A2BxGy1IWrxt1ZATa1R4QfJZaQOD3zU= go.starlark.net v0.0.0-20230912135651-745481cf39ed h1:kNt8RXSIU6IRBO9MP3m+6q3WpyBHQQXqSktcyVKDPOQ= go.starlark.net v0.0.0-20230912135651-745481cf39ed/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= @@ -359,20 +350,17 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U 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/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -397,11 +385,11 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/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-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -424,9 +412,8 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= +golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -459,7 +446,6 @@ golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -481,7 +467,6 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -499,7 +484,6 @@ golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -508,7 +492,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -520,8 +503,8 @@ golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -555,9 +538,8 @@ gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= @@ -576,9 +558,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -622,12 +603,12 @@ k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAE k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240105020646-a37d4de58910 h1:1Rp/XEKP5uxPs6QrsngEHAxBjaAR78iJRiJq5Fi7LSU= -k8s.io/kube-openapi v0.0.0-20240105020646-a37d4de58910/go.mod h1:Pa1PvrP7ACSkuX6I7KYomY6cmMA0Tx86waBhDUgoKPw= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= -sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= +k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e h1:snPmy96t93RredGRjKfMFt+gvxuVAncqSAyBveJtr4Q= +k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.17.0 h1:fjJQf8Ukya+VjogLO6/bNX9HE6Y2xpsO5+fyS26ur/s= +sigs.k8s.io/controller-runtime v0.17.0/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20231121004636-2154ffbc22e2 h1:S1i08nqcuJsCyUBR0jvmKnMLHEbPb74yrVfUoSeuGew= sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20231121004636-2154ffbc22e2/go.mod h1:TF/lVLWS+JNNaVqJuDDictY2hZSXSsIHCx4FClMvqFg= sigs.k8s.io/controller-tools v0.14.0 h1:rnNoCC5wSXlrNoBKKzL70LNJKIQKEzT6lloG6/LF73A= From 8befae4ff65a007f2c08f30475b4e81ab5d64a22 Mon Sep 17 00:00:00 2001 From: Aitor Perez Cedres Date: Thu, 25 Jan 2024 18:13:14 +0000 Subject: [PATCH 2/4] Implement CustomValidator interface in webhook The interface Validator is deprecated starting in controller-runtime 0.17.0. We have to implement the new interface to avoid future breaking changes. Signed-off-by: Aitor Perez Cedres --- Makefile | 14 ++- api/v1alpha1/superstream_types.go | 6 +- api/v1alpha1/superstream_webhook.go | 50 +++++--- api/v1alpha1/superstream_webhook_test.go | 58 +++++---- api/v1beta1/binding_webhook.go | 57 +++++---- api/v1beta1/binding_webhook_test.go | 73 ++++++----- api/v1beta1/exchange_webhook.go | 56 +++++---- api/v1beta1/exchange_webhook_test.go | 67 ++++++---- api/v1beta1/federation_webhook.go | 40 ++++-- api/v1beta1/federation_webhook_test.go | 73 ++++++----- api/v1beta1/operatorpolicy_webhook.go | 39 +++--- api/v1beta1/operatorpolicy_webhook_test.go | 67 ++++++---- api/v1beta1/permission_webhook.go | 73 ++++++----- api/v1beta1/permission_webhook_test.go | 81 +++++++----- api/v1beta1/policy_webhook.go | 38 +++--- api/v1beta1/policy_webhook_test.go | 67 ++++++---- api/v1beta1/queue_webhook.go | 56 +++++---- api/v1beta1/queue_webhook_test.go | 68 ++++++---- api/v1beta1/rabbitmq_cluster_reference.go | 20 +-- .../rabbitmq_cluster_reference_test.go | 41 ++++--- api/v1beta1/schemareplication_webhook.go | 60 +++++---- api/v1beta1/schemareplication_webhook_test.go | 64 ++++++---- api/v1beta1/shovel_webhook.go | 57 +++++---- api/v1beta1/shovel_webhook_test.go | 116 ++++++++++-------- api/v1beta1/topicpermission_webhook.go | 74 ++++++----- api/v1beta1/topicpermission_webhook_test.go | 100 ++++++++------- api/v1beta1/user_webhook.go | 33 +++-- api/v1beta1/user_webhook_test.go | 46 ++++--- api/v1beta1/vhost_webhook.go | 45 ++++--- api/v1beta1/vhost_webhook_test.go | 59 +++++---- go.sum | 12 ++ .../managedresource_builder.go | 2 +- 32 files changed, 1020 insertions(+), 692 deletions(-) diff --git a/Makefile b/Makefile index 1d3a8dfb..815f5bad 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,17 @@ $(KUBEBUILDER_ASSETS): ### Targets .PHONY: unit-tests -unit-tests: install-tools $(KUBEBUILDER_ASSETS) generate fmt vet vuln manifests ## Run unit tests +unit-tests::install-tools ## Run unit tests +unit-test::$(KUBEBUILDER_ASSETS) +unit-test::generate +unit-test::fmt +unit-test::vet +unit-test::vuln +unit-test::manifests +unit-test::just-unit-tests + +.PHONY: just-unit-tests +just-unit-tests: ginkgo -r --randomize-all api/ internal/ rabbitmqclient/ .PHONY: integration-tests @@ -207,7 +217,7 @@ generate-manifests: # Cert Manager # ################ -CERT_MANAGER_VERSION ?= v1.7.0 +CERT_MANAGER_VERSION ?= v1.12.3 CERT_MANAGER_MANIFEST ?= https://github.com/jetstack/cert-manager/releases/download/$(CERT_MANAGER_VERSION)/cert-manager.yaml CMCTL = $(LOCAL_BIN)/cmctl diff --git a/api/v1alpha1/superstream_types.go b/api/v1alpha1/superstream_types.go index 93ecb477..91234633 100644 --- a/api/v1alpha1/superstream_types.go +++ b/api/v1alpha1/superstream_types.go @@ -70,10 +70,10 @@ type SuperStreamList struct { Items []SuperStream `json:"items"` } -func (q *SuperStream) GroupResource() schema.GroupResource { +func (s *SuperStream) GroupResource() schema.GroupResource { return schema.GroupResource{ - Group: q.GroupVersionKind().Group, - Resource: q.GroupVersionKind().Kind, + Group: s.GroupVersionKind().Group, + Resource: s.GroupVersionKind().Kind, } } diff --git a/api/v1alpha1/superstream_webhook.go b/api/v1alpha1/superstream_webhook.go index 91f73449..e0d8b82c 100644 --- a/api/v1alpha1/superstream_webhook.go +++ b/api/v1alpha1/superstream_webhook.go @@ -10,6 +10,7 @@ This product may include a number of subcomponents with separate copyright notic package v1alpha1 import ( + "context" "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -27,43 +28,52 @@ func (s *SuperStream) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1alpha1-superstream,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=superstreams,versions=v1alpha1,name=vsuperstream.kb.io,sideEffects=none,admissionReviewVersions=v1 -var _ webhook.Validator = &SuperStream{} +var _ webhook.CustomValidator = &SuperStream{} -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type -// either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both -func (s *SuperStream) ValidateCreate() (admission.Warnings, error) { - return s.Spec.RabbitmqClusterReference.ValidateOnCreate(s.GroupResource(), s.Name) +// ValidateCreate - either rabbitmqClusterReference.name or +// rabbitmqClusterReference.connectionSecret must be provided but not both +func (s *SuperStream) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + ss, ok := obj.(*SuperStream) + if !ok { + return nil, fmt.Errorf("expected a RabbitMQ super stream but got a %T", obj) + } + return ss.Spec.RabbitmqClusterReference.ValidateOnCreate(ss.GroupResource(), ss.Name) } // ValidateUpdate returns error type 'forbidden' for updates on superstream name, vhost and rabbitmqClusterReference -func (s *SuperStream) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldSuperStream, ok := old.(*SuperStream) +func (s *SuperStream) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldSuperStream, ok := oldObj.(*SuperStream) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a superstream but got a %T", oldObj)) + } + + newSuperStream, ok := newObj.(*SuperStream) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a superstream but got a %T", old)) + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a superstream but got a %T", newObj)) } - detailMsg := "updates on name, vhost and rabbitmqClusterReference are all forbidden" - if s.Spec.Name != oldSuperStream.Spec.Name { - return nil, apierrors.NewForbidden(s.GroupResource(), s.Name, + const detailMsg = "updates on name, vhost and rabbitmqClusterReference are all forbidden" + if newSuperStream.Spec.Name != oldSuperStream.Spec.Name { + return nil, apierrors.NewForbidden(newSuperStream.GroupResource(), newSuperStream.Name, field.Forbidden(field.NewPath("spec", "name"), detailMsg)) } - if s.Spec.Vhost != oldSuperStream.Spec.Vhost { - return nil, apierrors.NewForbidden(s.GroupResource(), s.Name, + if newSuperStream.Spec.Vhost != oldSuperStream.Spec.Vhost { + return nil, apierrors.NewForbidden(newSuperStream.GroupResource(), newSuperStream.Name, field.Forbidden(field.NewPath("spec", "vhost"), detailMsg)) } - if !oldSuperStream.Spec.RabbitmqClusterReference.Matches(&s.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(s.GroupResource(), s.Name, + if !oldSuperStream.Spec.RabbitmqClusterReference.Matches(&newSuperStream.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newSuperStream.GroupResource(), newSuperStream.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), detailMsg)) } - if !routingKeyUpdatePermitted(oldSuperStream.Spec.RoutingKeys, s.Spec.RoutingKeys) { - return nil, apierrors.NewForbidden(s.GroupResource(), s.Name, + if !routingKeyUpdatePermitted(oldSuperStream.Spec.RoutingKeys, newSuperStream.Spec.RoutingKeys) { + return nil, apierrors.NewForbidden(newSuperStream.GroupResource(), newSuperStream.Name, field.Forbidden(field.NewPath("spec", "routingKeys"), "updates may only add to the existing list of routing keys")) } - if s.Spec.Partitions < oldSuperStream.Spec.Partitions { - return nil, apierrors.NewForbidden(s.GroupResource(), s.Name, + if newSuperStream.Spec.Partitions < oldSuperStream.Spec.Partitions { + return nil, apierrors.NewForbidden(newSuperStream.GroupResource(), newSuperStream.Name, field.Forbidden(field.NewPath("spec", "partitions"), "updates may only increase the partition count, and may not decrease it")) } @@ -71,7 +81,7 @@ func (s *SuperStream) ValidateUpdate(old runtime.Object) (admission.Warnings, er } // ValidateDelete no validation on delete -func (s *SuperStream) ValidateDelete() (admission.Warnings, error) { +func (s *SuperStream) ValidateDelete(_ context.Context, _ runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } diff --git a/api/v1alpha1/superstream_webhook_test.go b/api/v1alpha1/superstream_webhook_test.go index 7e063225..c5bf8889 100644 --- a/api/v1alpha1/superstream_webhook_test.go +++ b/api/v1alpha1/superstream_webhook_test.go @@ -1,6 +1,7 @@ package v1alpha1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" topologyv1beta1 "github.com/rabbitmq/messaging-topology-operator/api/v1beta1" @@ -10,7 +11,11 @@ import ( ) var _ = Describe("superstream webhook", func() { - var superstream = SuperStream{} + var ( + superstream = SuperStream{} + rootCtx = context.Background() + ) + BeforeEach(func() { superstream = SuperStream{ ObjectMeta: metav1.ObjectMeta{ @@ -31,16 +36,16 @@ var _ = Describe("superstream webhook", func() { It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := superstream.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - _, err := notAllowed.ValidateCreate() - Expect(apierrors.IsForbidden(err)).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := superstream.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - _, err := notAllowed.ValidateCreate() - Expect(apierrors.IsForbidden(err)).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) }) @@ -48,15 +53,17 @@ var _ = Describe("superstream webhook", func() { It("does not allow updates on superstream name", func() { newSuperStream := superstream.DeepCopy() newSuperStream.Spec.Name = "new-name" - _, err := newSuperStream.ValidateUpdate(&superstream) - Expect(apierrors.IsForbidden(err)).To(BeTrue()) + _, err := newSuperStream.ValidateUpdate(rootCtx, &superstream, newSuperStream) + Expect(apierrors.IsForbidden(err)).To(BeTrue(), "expected error type to be 'forbidden'") + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on superstream vhost", func() { newSuperStream := superstream.DeepCopy() newSuperStream.Spec.Vhost = "new-vhost" - _, err := newSuperStream.ValidateUpdate(&superstream) - Expect(apierrors.IsForbidden(err)).To(BeTrue()) + _, err := newSuperStream.ValidateUpdate(rootCtx, &superstream, newSuperStream) + Expect(apierrors.IsForbidden(err)).To(BeTrue(), "expected error type to be 'forbidden'") + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on RabbitmqClusterReference", func() { @@ -64,51 +71,56 @@ var _ = Describe("superstream webhook", func() { newSuperStream.Spec.RabbitmqClusterReference = topologyv1beta1.RabbitmqClusterReference{ Name: "new-cluster", } - _, err := newSuperStream.ValidateUpdate(&superstream) - Expect(apierrors.IsForbidden(err)).To(BeTrue()) + _, err := newSuperStream.ValidateUpdate(rootCtx, &superstream, newSuperStream) + Expect(apierrors.IsForbidden(err)).To(BeTrue(), "expected error type to be 'forbidden'") + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { newSuperStream := superstream.DeepCopy() newSuperStream.Spec.RabbitmqClusterReference = topologyv1beta1.RabbitmqClusterReference{ConnectionSecret: &corev1.LocalObjectReference{Name: "a-secret"}} - _, err := newSuperStream.ValidateUpdate(&superstream) - Expect(apierrors.IsForbidden(err)).To(BeTrue()) + _, err := newSuperStream.ValidateUpdate(rootCtx, &superstream, newSuperStream) + Expect(apierrors.IsForbidden(err)).To(BeTrue(), "expected error type to be 'forbidden'") + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on superstream.spec.routingKeys", func() { newSuperStream := superstream.DeepCopy() newSuperStream.Spec.RoutingKeys = []string{"a1", "d6"} - _, err := newSuperStream.ValidateUpdate(&superstream) - Expect(apierrors.IsForbidden(err)).To(BeTrue()) + _, err := newSuperStream.ValidateUpdate(rootCtx, &superstream, newSuperStream) + Expect(apierrors.IsForbidden(err)).To(BeTrue(), "expected error type to be 'forbidden'") + Expect(err).To(MatchError(ContainSubstring("updates may only add to the existing list of routing keys"))) }) - It("if the superstream previously had routing keys and the update only appends, the update succeeds", func() { + Specify("if the superstream previously had routing keys and the update only appends, the update succeeds", func() { newSuperStream := superstream.DeepCopy() newSuperStream.Spec.RoutingKeys = []string{"a1", "b2", "f17", "z66"} - _, err := newSuperStream.ValidateUpdate(&superstream) + _, err := newSuperStream.ValidateUpdate(rootCtx, &superstream, newSuperStream) Expect(err).NotTo(HaveOccurred()) }) - It("if the superstream previously had no routing keys but now does, the update fails", func() { + Specify("if the superstream previously had no routing keys but now does, the update fails", func() { superstream.Spec.RoutingKeys = nil newSuperStream := superstream.DeepCopy() newSuperStream.Spec.RoutingKeys = []string{"a1", "b2", "f17"} - _, err := newSuperStream.ValidateUpdate(&superstream) - Expect(apierrors.IsForbidden(err)).To(BeTrue()) + _, err := newSuperStream.ValidateUpdate(rootCtx, &superstream, newSuperStream) + Expect(apierrors.IsForbidden(err)).To(BeTrue(), "expected error type to be 'forbidden'") + Expect(err).To(MatchError(ContainSubstring("updates may only add to the existing list of routing keys"))) }) It("allows superstream.spec.partitions to be increased", func() { newSuperStream := superstream.DeepCopy() newSuperStream.Spec.Partitions = 1000 - _, err := newSuperStream.ValidateUpdate(&superstream) + _, err := newSuperStream.ValidateUpdate(rootCtx, &superstream, newSuperStream) Expect(err).NotTo(HaveOccurred()) }) It("does not allow superstream.spec.partitions to be decreased", func() { newSuperStream := superstream.DeepCopy() newSuperStream.Spec.Partitions = 1 - _, err := newSuperStream.ValidateUpdate(&superstream) - Expect(apierrors.IsForbidden(err)).To(BeTrue()) + _, err := newSuperStream.ValidateUpdate(rootCtx, &superstream, newSuperStream) + Expect(apierrors.IsForbidden(err)).To(BeTrue(), "expected error type to be 'forbidden'") + Expect(err).To(MatchError(ContainSubstring("updates may only increase the partition count, and may not decrease it"))) }) }) }) diff --git a/api/v1beta1/binding_webhook.go b/api/v1beta1/binding_webhook.go index f6a2de2c..4673a1f4 100644 --- a/api/v1beta1/binding_webhook.go +++ b/api/v1beta1/binding_webhook.go @@ -1,6 +1,7 @@ package v1beta1 import ( + "context" "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -19,70 +20,78 @@ func (b *Binding) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1beta1-binding,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=bindings,versions=v1beta1,name=vbinding.kb.io,sideEffects=none,admissionReviewVersions=v1 -var _ webhook.Validator = &Binding{} +var _ webhook.CustomValidator = &Binding{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type // either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both -func (b *Binding) ValidateCreate() (admission.Warnings, error) { - return b.Spec.RabbitmqClusterReference.ValidateOnCreate(b.GroupResource(), b.Name) +func (b *Binding) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + bi, ok := obj.(*Binding) + if !ok { + return nil, fmt.Errorf("expected a RabbitMQ Binding, but got %T", obj) + } + return nil, b.Spec.RabbitmqClusterReference.validate(bi.RabbitReference()) } -// ValidateUpdate updates on vhost and rabbitmqClusterReference are forbidden -func (b *Binding) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldBinding, ok := old.(*Binding) +func (b *Binding) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldBinding, ok := oldObj.(*Binding) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a binding but got a %T", oldObj)) + } + + newBinding, ok := newObj.(*Binding) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a binding but got a %T", old)) + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a binding but got a %T", oldObj)) } var allErrs field.ErrorList - detailMsg := "updates on vhost and rabbitmqClusterReference are all forbidden" + const detailMsg = "updates on vhost and rabbitmqClusterReference are all forbidden" - if b.Spec.Vhost != oldBinding.Spec.Vhost { - return nil, apierrors.NewForbidden(b.GroupResource(), b.Name, + if newBinding.Spec.Vhost != oldBinding.Spec.Vhost { + return nil, apierrors.NewForbidden(newBinding.GroupResource(), newBinding.Name, field.Forbidden(field.NewPath("spec", "vhost"), detailMsg)) } - if !oldBinding.Spec.RabbitmqClusterReference.Matches(&b.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(b.GroupResource(), b.Name, + if !oldBinding.Spec.RabbitmqClusterReference.Matches(&newBinding.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newBinding.GroupResource(), newBinding.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), detailMsg)) } - if b.Spec.Source != oldBinding.Spec.Source { + if newBinding.Spec.Source != oldBinding.Spec.Source { allErrs = append(allErrs, field.Invalid( field.NewPath("spec", "source"), - b.Spec.Source, + newBinding.Spec.Source, "source cannot be updated", )) } - if b.Spec.Destination != oldBinding.Spec.Destination { + if newBinding.Spec.Destination != oldBinding.Spec.Destination { allErrs = append(allErrs, field.Invalid( field.NewPath("spec", "destination"), - b.Spec.Destination, + newBinding.Spec.Destination, "destination cannot be updated", )) } - if b.Spec.DestinationType != oldBinding.Spec.DestinationType { + if newBinding.Spec.DestinationType != oldBinding.Spec.DestinationType { allErrs = append(allErrs, field.Invalid( field.NewPath("spec", "destinationType"), - b.Spec.DestinationType, + newBinding.Spec.DestinationType, "destinationType cannot be updated", )) } - if b.Spec.RoutingKey != oldBinding.Spec.RoutingKey { + if newBinding.Spec.RoutingKey != oldBinding.Spec.RoutingKey { allErrs = append(allErrs, field.Invalid( field.NewPath("spec", "routingKey"), - b.Spec.RoutingKey, + newBinding.Spec.RoutingKey, "routingKey cannot be updated", )) } - if !reflect.DeepEqual(b.Spec.Arguments, oldBinding.Spec.Arguments) { + if !reflect.DeepEqual(newBinding.Spec.Arguments, oldBinding.Spec.Arguments) { allErrs = append(allErrs, field.Invalid( field.NewPath("spec", "arguments"), - b.Spec.Arguments, + newBinding.Spec.Arguments, "arguments cannot be updated", )) } @@ -91,9 +100,9 @@ func (b *Binding) ValidateUpdate(old runtime.Object) (admission.Warnings, error) return nil, nil } - return nil, apierrors.NewInvalid(GroupVersion.WithKind("Binding").GroupKind(), b.Name, allErrs) + return nil, allErrs.ToAggregate() } -func (b *Binding) ValidateDelete() (admission.Warnings, error) { +func (b *Binding) ValidateDelete(_ context.Context, _ runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } diff --git a/api/v1beta1/binding_webhook_test.go b/api/v1beta1/binding_webhook_test.go index fcf7bc4e..e5f3e2c9 100644 --- a/api/v1beta1/binding_webhook_test.go +++ b/api/v1beta1/binding_webhook_test.go @@ -1,43 +1,51 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) var _ = Describe("Binding webhook", func() { - var oldBinding = Binding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "update-binding", - }, - Spec: BindingSpec{ - Vhost: "/test", - Source: "test", - Destination: "test", - DestinationType: "queue", - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "some-cluster", + var ( + oldBinding = Binding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "update-binding", }, - }, - } + Spec: BindingSpec{ + Vhost: "/test", + Source: "test", + Destination: "test", + DestinationType: "queue", + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "some-cluster", + }, + }, + } + rootCtx = context.Background() + ) Context("ValidateCreate", func() { It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := oldBinding.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err). + To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := oldBinding.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) }) @@ -45,18 +53,21 @@ var _ = Describe("Binding webhook", func() { It("does not allow updates on vhost", func() { newBinding := oldBinding.DeepCopy() newBinding.Spec.Vhost = "/new-vhost" - Expect(apierrors.IsForbidden(ignoreNilWarning(newBinding.ValidateUpdate(&oldBinding)))).To(BeTrue()) + + _, err := newBinding.ValidateUpdate(rootCtx, &oldBinding, newBinding) + Expect(err).To(MatchError(ContainSubstring("updates on vhost and rabbitmqClusterReference are all forbidden"))) }) - It("does not allow updates on RabbitmqClusterReference", func() { + It("does not allow updates on RabbitmqClusterReference name", func() { newBinding := oldBinding.DeepCopy() newBinding.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "new-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newBinding.ValidateUpdate(&oldBinding)))).To(BeTrue()) + _, err := newBinding.ValidateUpdate(rootCtx, &oldBinding, newBinding) + Expect(err).To(MatchError(ContainSubstring("updates on vhost and rabbitmqClusterReference are all forbidden"))) }) - It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { + It("does not allow updates on rabbitmqClusterReference connectionSecret", func() { connectionScr := Binding{ ObjectMeta: metav1.ObjectMeta{ Name: "connect-test-queue", @@ -69,39 +80,45 @@ var _ = Describe("Binding webhook", func() { }, }, } - new := connectionScr.DeepCopy() - new.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" - Expect(apierrors.IsForbidden(ignoreNilWarning(new.ValidateUpdate(&connectionScr)))).To(BeTrue()) + newConnSrc := connectionScr.DeepCopy() + newConnSrc.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" + _, err := newConnSrc.ValidateUpdate(rootCtx, &connectionScr, newConnSrc) + Expect(err).To(MatchError(ContainSubstring("updates on vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on source", func() { newBinding := oldBinding.DeepCopy() newBinding.Spec.Source = "updated-source" - Expect(apierrors.IsInvalid(ignoreNilWarning(newBinding.ValidateUpdate(&oldBinding)))).To(BeTrue()) + _, err := newBinding.ValidateUpdate(rootCtx, &oldBinding, newBinding) + Expect(err).To(MatchError(ContainSubstring("source cannot be updated"))) }) It("does not allow updates on destination", func() { newBinding := oldBinding.DeepCopy() newBinding.Spec.Destination = "updated-des" - Expect(apierrors.IsInvalid(ignoreNilWarning(newBinding.ValidateUpdate(&oldBinding)))).To(BeTrue()) + _, err := newBinding.ValidateUpdate(rootCtx, &oldBinding, newBinding) + Expect(err).To(MatchError(ContainSubstring("destination cannot be updated"))) }) It("does not allow updates on destination type", func() { newBinding := oldBinding.DeepCopy() newBinding.Spec.DestinationType = "exchange" - Expect(apierrors.IsInvalid(ignoreNilWarning(newBinding.ValidateUpdate(&oldBinding)))).To(BeTrue()) + _, err := newBinding.ValidateUpdate(rootCtx, &oldBinding, newBinding) + Expect(err).To(MatchError(ContainSubstring("destinationType cannot be updated"))) }) It("does not allow updates on routing key", func() { newBinding := oldBinding.DeepCopy() newBinding.Spec.RoutingKey = "not-allowed" - Expect(apierrors.IsInvalid(ignoreNilWarning(newBinding.ValidateUpdate(&oldBinding)))).To(BeTrue()) + _, err := newBinding.ValidateUpdate(rootCtx, &oldBinding, newBinding) + Expect(err).To(MatchError(ContainSubstring("routingKey cannot be updated"))) }) It("does not allow updates on binding arguments", func() { newBinding := oldBinding.DeepCopy() newBinding.Spec.Arguments = &runtime.RawExtension{Raw: []byte(`{"new":"new-value"}`)} - Expect(apierrors.IsInvalid(ignoreNilWarning(newBinding.ValidateUpdate(&oldBinding)))).To(BeTrue()) + _, err := newBinding.ValidateUpdate(rootCtx, &oldBinding, newBinding) + Expect(err).To(MatchError(ContainSubstring("arguments cannot be updated"))) }) }) }) diff --git a/api/v1beta1/exchange_webhook.go b/api/v1beta1/exchange_webhook.go index ab545f7a..ff7ee11b 100644 --- a/api/v1beta1/exchange_webhook.go +++ b/api/v1beta1/exchange_webhook.go @@ -1,6 +1,7 @@ package v1beta1 import ( + "context" "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -10,69 +11,78 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) -func (r *Exchange) SetupWebhookWithManager(mgr ctrl.Manager) error { +func (e *Exchange) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). - For(r). + For(e). Complete() } // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1beta1-exchange,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=exchanges,versions=v1beta1,name=vexchange.kb.io,sideEffects=none,admissionReviewVersions=v1 -var _ webhook.Validator = &Exchange{} +var _ webhook.CustomValidator = &Exchange{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type // either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both -func (e *Exchange) ValidateCreate() (admission.Warnings, error) { - return e.Spec.RabbitmqClusterReference.ValidateOnCreate(e.GroupResource(), e.Name) +func (e *Exchange) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + ex, ok := obj.(*Exchange) + if !ok { + return nil, fmt.Errorf("expected an exchange but got a %T", obj) + } + return nil, e.Spec.RabbitmqClusterReference.validate(ex.RabbitReference()) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type // returns error type 'forbidden' for updates that the controller chooses to disallow: exchange name/vhost/rabbitmqClusterReference // returns error type 'invalid' for updates that will be rejected by rabbitmq server: exchange types/autoDelete/durable // exchange.spec.arguments can be updated -func (e *Exchange) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldExchange, ok := old.(*Exchange) +func (e *Exchange) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldExchange, ok := oldObj.(*Exchange) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an exchange but got a %T", oldObj)) + } + + newExchange, ok := newObj.(*Exchange) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an exchange but got a %T", old)) + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an exchange but got a %T", newObj)) } var allErrs field.ErrorList - detailMsg := "updates on name, vhost, and rabbitmqClusterReference are all forbidden" - if e.Spec.Name != oldExchange.Spec.Name { - return nil, apierrors.NewForbidden(e.GroupResource(), e.Name, + const detailMsg = "updates on name, vhost, and rabbitmqClusterReference are all forbidden" + if newExchange.Spec.Name != oldExchange.Spec.Name { + return nil, apierrors.NewForbidden(newExchange.GroupResource(), newExchange.Name, field.Forbidden(field.NewPath("spec", "name"), detailMsg)) } - if e.Spec.Vhost != oldExchange.Spec.Vhost { - return nil, apierrors.NewForbidden(e.GroupResource(), e.Name, + if newExchange.Spec.Vhost != oldExchange.Spec.Vhost { + return nil, apierrors.NewForbidden(newExchange.GroupResource(), newExchange.Name, field.Forbidden(field.NewPath("spec", "vhost"), detailMsg)) } - if !oldExchange.Spec.RabbitmqClusterReference.Matches(&e.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(e.GroupResource(), e.Name, + if !oldExchange.Spec.RabbitmqClusterReference.Matches(&newExchange.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newExchange.GroupResource(), newExchange.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), detailMsg)) } - if e.Spec.Type != oldExchange.Spec.Type { + if newExchange.Spec.Type != oldExchange.Spec.Type { allErrs = append(allErrs, field.Invalid( field.NewPath("spec", "type"), - e.Spec.Type, + newExchange.Spec.Type, "exchange type cannot be updated", )) } - if e.Spec.AutoDelete != oldExchange.Spec.AutoDelete { + if newExchange.Spec.AutoDelete != oldExchange.Spec.AutoDelete { allErrs = append(allErrs, field.Invalid( field.NewPath("spec", "autoDelete"), - e.Spec.AutoDelete, + newExchange.Spec.AutoDelete, "autoDelete cannot be updated", )) } - if e.Spec.Durable != oldExchange.Spec.Durable { + if newExchange.Spec.Durable != oldExchange.Spec.Durable { allErrs = append(allErrs, field.Invalid( field.NewPath("spec", "durable"), - e.Spec.AutoDelete, + newExchange.Spec.AutoDelete, "durable cannot be updated", )) } @@ -81,9 +91,9 @@ func (e *Exchange) ValidateUpdate(old runtime.Object) (admission.Warnings, error return nil, nil } - return nil, apierrors.NewInvalid(GroupVersion.WithKind("Exchange").GroupKind(), e.Name, allErrs) + return nil, allErrs.ToAggregate() } -func (e *Exchange) ValidateDelete() (admission.Warnings, error) { +func (e *Exchange) ValidateDelete(_ context.Context, _ runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } diff --git a/api/v1beta1/exchange_webhook_test.go b/api/v1beta1/exchange_webhook_test.go index 047fcffe..ae606473 100644 --- a/api/v1beta1/exchange_webhook_test.go +++ b/api/v1beta1/exchange_webhook_test.go @@ -1,44 +1,49 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) var _ = Describe("exchange webhook", func() { - var exchange = Exchange{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-exchange", - }, - Spec: ExchangeSpec{ - Name: "test", - Vhost: "/test", - Type: "fanout", - Durable: false, - AutoDelete: true, - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "some-cluster", + var ( + exchange = Exchange{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-exchange", }, - }, - } + Spec: ExchangeSpec{ + Name: "test", + Vhost: "/test", + Type: "fanout", + Durable: false, + AutoDelete: true, + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "some-cluster", + }, + }, + } + rootCtx = context.Background() + ) Context("ValidateCreate", func() { It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := exchange.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := exchange.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) }) @@ -46,13 +51,15 @@ var _ = Describe("exchange webhook", func() { It("does not allow updates on exchange name", func() { newExchange := exchange.DeepCopy() newExchange.Spec.Name = "new-name" - Expect(apierrors.IsForbidden(ignoreNilWarning(newExchange.ValidateUpdate(&exchange)))).To(BeTrue()) + _, err := newExchange.ValidateUpdate(rootCtx, &exchange, newExchange) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost, and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on vhost", func() { newExchange := exchange.DeepCopy() newExchange.Spec.Vhost = "/a-new-vhost" - Expect(apierrors.IsForbidden(ignoreNilWarning(newExchange.ValidateUpdate(&exchange)))).To(BeTrue()) + _, err := newExchange.ValidateUpdate(rootCtx, &exchange, newExchange) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost, and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on RabbitmqClusterReference", func() { @@ -60,7 +67,8 @@ var _ = Describe("exchange webhook", func() { newExchange.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "new-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newExchange.ValidateUpdate(&exchange)))).To(BeTrue()) + _, err := newExchange.ValidateUpdate(rootCtx, &exchange, newExchange) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost, and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { @@ -79,33 +87,38 @@ var _ = Describe("exchange webhook", func() { }, }, } - new := connectionScr.DeepCopy() - new.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" - Expect(apierrors.IsForbidden(ignoreNilWarning(new.ValidateUpdate(&connectionScr)))).To(BeTrue()) + newExchange := connectionScr.DeepCopy() + newExchange.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" + _, err := newExchange.ValidateUpdate(rootCtx, &connectionScr, newExchange) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost, and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on exchange type", func() { newExchange := exchange.DeepCopy() newExchange.Spec.Type = "direct" - Expect(apierrors.IsInvalid(ignoreNilWarning(newExchange.ValidateUpdate(&exchange)))).To(BeTrue()) + _, err := newExchange.ValidateUpdate(rootCtx, &exchange, newExchange) + Expect(err).To(MatchError(ContainSubstring("exchange type cannot be updated"))) }) It("does not allow updates on durable", func() { newExchange := exchange.DeepCopy() newExchange.Spec.Durable = true - Expect(apierrors.IsInvalid(ignoreNilWarning(newExchange.ValidateUpdate(&exchange)))).To(BeTrue()) + _, err := newExchange.ValidateUpdate(rootCtx, &exchange, newExchange) + Expect(err).To(MatchError(ContainSubstring("durable cannot be updated"))) }) It("does not allow updates on autoDelete", func() { newExchange := exchange.DeepCopy() newExchange.Spec.AutoDelete = false - Expect(apierrors.IsInvalid(ignoreNilWarning(newExchange.ValidateUpdate(&exchange)))).To(BeTrue()) + _, err := newExchange.ValidateUpdate(rootCtx, &exchange, newExchange) + Expect(err).To(MatchError(ContainSubstring("autoDelete cannot be updated"))) }) It("allows updates on arguments", func() { newExchange := exchange.DeepCopy() newExchange.Spec.Arguments = &runtime.RawExtension{Raw: []byte(`{"new":"new-value"}`)} - Expect(ignoreNilWarning(newExchange.ValidateUpdate(&exchange))).To(Succeed()) + _, err := newExchange.ValidateUpdate(rootCtx, &exchange, newExchange) + Expect(err).To(Succeed()) }) }) }) diff --git a/api/v1beta1/federation_webhook.go b/api/v1beta1/federation_webhook.go index 9c4b1fd4..e3dad89a 100644 --- a/api/v1beta1/federation_webhook.go +++ b/api/v1beta1/federation_webhook.go @@ -1,11 +1,13 @@ package v1beta1 import ( + "context" "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -15,39 +17,51 @@ func (f *Federation) SetupWebhookWithManager(mgr ctrl.Manager) error { Complete() } +var _ webhook.CustomValidator = &Federation{} + // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1beta1-federation,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=federations,versions=v1beta1,name=vfederation.kb.io,sideEffects=none,admissionReviewVersions=v1 // ValidateCreate implements webhook.Validator so a webhook will be registered for the type // either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both -func (f *Federation) ValidateCreate() (admission.Warnings, error) { - return f.Spec.RabbitmqClusterReference.ValidateOnCreate(f.GroupResource(), f.Name) +func (f *Federation) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + //TODO implement me + fed, ok := obj.(*Federation) + if !ok { + return nil, fmt.Errorf("expected a RabbitMQ Federation, but got %T", obj) + } + return nil, f.Spec.RabbitmqClusterReference.validate(fed.RabbitReference()) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (f *Federation) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldFederation, ok := old.(*Federation) +func (f *Federation) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldFederation, ok := oldObj.(*Federation) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a federation but got a %T", oldObj)) + } + + newFederation, ok := newObj.(*Federation) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a federation but got a %T", old)) + return nil, fmt.Errorf("expected a RabbitMQ Federation, but got %T", newObj) } - detailMsg := "updates on name, vhost and rabbitmqClusterReference are all forbidden" - if f.Spec.Name != oldFederation.Spec.Name { - return nil, apierrors.NewForbidden(f.GroupResource(), f.Name, + const detailMsg = "updates on name, vhost and rabbitmqClusterReference are all forbidden" + if newFederation.Spec.Name != oldFederation.Spec.Name { + return nil, apierrors.NewForbidden(newFederation.GroupResource(), newFederation.Name, field.Forbidden(field.NewPath("spec", "name"), detailMsg)) } - if f.Spec.Vhost != oldFederation.Spec.Vhost { - return nil, apierrors.NewForbidden(f.GroupResource(), f.Name, + if newFederation.Spec.Vhost != oldFederation.Spec.Vhost { + return nil, apierrors.NewForbidden(newFederation.GroupResource(), newFederation.Name, field.Forbidden(field.NewPath("spec", "vhost"), detailMsg)) } - if !oldFederation.Spec.RabbitmqClusterReference.Matches(&f.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(f.GroupResource(), f.Name, + if !oldFederation.Spec.RabbitmqClusterReference.Matches(&newFederation.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newFederation.GroupResource(), newFederation.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), detailMsg)) } return nil, nil } -func (f *Federation) ValidateDelete() (admission.Warnings, error) { +func (f *Federation) ValidateDelete(_ context.Context, _ runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } diff --git a/api/v1beta1/federation_webhook_test.go b/api/v1beta1/federation_webhook_test.go index 654c6f4a..766b1b09 100644 --- a/api/v1beta1/federation_webhook_test.go +++ b/api/v1beta1/federation_webhook_test.go @@ -1,49 +1,55 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var _ = Describe("federation webhook", func() { - var federation = Federation{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - }, - Spec: FederationSpec{ - Name: "test-upstream", - Vhost: "/a-vhost", - UriSecret: &corev1.LocalObjectReference{ - Name: "a-secret", + var ( + federation = Federation{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", }, - Expires: 1000, - MessageTTL: 1000, - MaxHops: 100, - PrefetchCount: 50, - ReconnectDelay: 10, - TrustUserId: true, - Exchange: "an-exchange", - AckMode: "no-ack", - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "a-cluster", + Spec: FederationSpec{ + Name: "test-upstream", + Vhost: "/a-vhost", + UriSecret: &corev1.LocalObjectReference{ + Name: "a-secret", + }, + Expires: 1000, + MessageTTL: 1000, + MaxHops: 100, + PrefetchCount: 50, + ReconnectDelay: 10, + TrustUserId: true, + Exchange: "an-exchange", + AckMode: "no-ack", + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "a-cluster", + }, }, - }, - } + } + rootCtx = context.Background() + ) + Context("ValidateCreate", func() { It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := federation.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := federation.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) }) @@ -51,13 +57,15 @@ var _ = Describe("federation webhook", func() { It("does not allow updates on name", func() { newFederation := federation.DeepCopy() newFederation.Spec.Name = "new-upstream" - Expect(apierrors.IsForbidden(ignoreNilWarning(newFederation.ValidateUpdate(&federation)))).To(BeTrue()) + _, err := newFederation.ValidateUpdate(rootCtx, &federation, newFederation) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on vhost", func() { newFederation := federation.DeepCopy() newFederation.Spec.Vhost = "new-vhost" - Expect(apierrors.IsForbidden(ignoreNilWarning(newFederation.ValidateUpdate(&federation)))).To(BeTrue()) + _, err := newFederation.ValidateUpdate(rootCtx, &federation, newFederation) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on RabbitmqClusterReference", func() { @@ -65,7 +73,8 @@ var _ = Describe("federation webhook", func() { newFederation.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "new-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newFederation.ValidateUpdate(&federation)))).To(BeTrue()) + _, err := newFederation.ValidateUpdate(rootCtx, &federation, newFederation) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { @@ -86,9 +95,10 @@ var _ = Describe("federation webhook", func() { }, }, } - new := connectionScr.DeepCopy() - new.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" - Expect(apierrors.IsForbidden(ignoreNilWarning(new.ValidateUpdate(&connectionScr)))).To(BeTrue()) + newFederation := connectionScr.DeepCopy() + newFederation.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" + _, err := newFederation.ValidateUpdate(rootCtx, &connectionScr, newFederation) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("allows updates on federation configurations", func() { @@ -102,7 +112,8 @@ var _ = Describe("federation webhook", func() { newFederation.Spec.TrustUserId = false newFederation.Spec.Exchange = "new-exchange" newFederation.Spec.AckMode = "no-ack" - Expect(ignoreNilWarning(newFederation.ValidateUpdate(&federation))).To(Succeed()) + _, err := newFederation.ValidateUpdate(rootCtx, &federation, newFederation) + Expect(err).To(Succeed()) }) }) }) diff --git a/api/v1beta1/operatorpolicy_webhook.go b/api/v1beta1/operatorpolicy_webhook.go index 42a1009d..944ccd70 100644 --- a/api/v1beta1/operatorpolicy_webhook.go +++ b/api/v1beta1/operatorpolicy_webhook.go @@ -1,8 +1,8 @@ package v1beta1 import ( + "context" "fmt" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" @@ -19,39 +19,48 @@ func (p *OperatorPolicy) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1beta1-operatorpolicy,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=operatorpolicies,versions=v1beta1,name=voperatorpolicy.kb.io,sideEffects=none,admissionReviewVersions=v1 -var _ webhook.Validator = &OperatorPolicy{} +var _ webhook.CustomValidator = &OperatorPolicy{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type // either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both -func (p *OperatorPolicy) ValidateCreate() (admission.Warnings, error) { - return p.Spec.RabbitmqClusterReference.ValidateOnCreate(p.GroupResource(), p.Name) +func (p *OperatorPolicy) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + op, ok := obj.(*OperatorPolicy) + if !ok { + return nil, fmt.Errorf("expected an operator policy but got %T", obj) + } + return nil, p.Spec.RabbitmqClusterReference.validate(op.RabbitReference()) } // ValidateUpdate returns error type 'forbidden' for updates on operator policy name, vhost and rabbitmqClusterReference -func (p *OperatorPolicy) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldOperatorPolicy, ok := old.(*OperatorPolicy) +func (p *OperatorPolicy) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldOperatorPolicy, ok := oldObj.(*OperatorPolicy) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an operator policy but got a %T", oldObj)) + } + + newOperatorPolicy, ok := newObj.(*OperatorPolicy) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an operator policy but got a %T", old)) + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an operator policy but got a %T", newObj)) } - detailMsg := "updates on name, vhost and rabbitmqClusterReference are all forbidden" - if p.Spec.Name != oldOperatorPolicy.Spec.Name { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + const detailMsg = "updates on name, vhost and rabbitmqClusterReference are all forbidden" + if newOperatorPolicy.Spec.Name != oldOperatorPolicy.Spec.Name { + return nil, apierrors.NewForbidden(newOperatorPolicy.GroupResource(), newOperatorPolicy.Name, field.Forbidden(field.NewPath("spec", "name"), detailMsg)) } - if p.Spec.Vhost != oldOperatorPolicy.Spec.Vhost { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + if newOperatorPolicy.Spec.Vhost != oldOperatorPolicy.Spec.Vhost { + return nil, apierrors.NewForbidden(newOperatorPolicy.GroupResource(), newOperatorPolicy.Name, field.Forbidden(field.NewPath("spec", "vhost"), detailMsg)) } - if !oldOperatorPolicy.Spec.RabbitmqClusterReference.Matches(&p.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + if !oldOperatorPolicy.Spec.RabbitmqClusterReference.Matches(&newOperatorPolicy.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newOperatorPolicy.GroupResource(), newOperatorPolicy.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), detailMsg)) } return nil, nil } -func (p *OperatorPolicy) ValidateDelete() (admission.Warnings, error) { +func (p *OperatorPolicy) ValidateDelete(_ context.Context, _ runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } diff --git a/api/v1beta1/operatorpolicy_webhook_test.go b/api/v1beta1/operatorpolicy_webhook_test.go index 04809d15..cab822a7 100644 --- a/api/v1beta1/operatorpolicy_webhook_test.go +++ b/api/v1beta1/operatorpolicy_webhook_test.go @@ -1,43 +1,48 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) var _ = Describe("policy webhook", func() { - var policy = OperatorPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - }, - Spec: OperatorPolicySpec{ - Name: "test", - Vhost: "/test", - Pattern: "a-pattern", - ApplyTo: "queues", - Priority: 0, - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "a-cluster", + var ( + policy = OperatorPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", }, - }, - } + Spec: OperatorPolicySpec{ + Name: "test", + Vhost: "/test", + Pattern: "a-pattern", + ApplyTo: "queues", + Priority: 0, + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "a-cluster", + }, + }, + } + rootCtx = context.Background() + ) Context("ValidateCreate", func() { It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := policy.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := policy.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) }) @@ -45,13 +50,15 @@ var _ = Describe("policy webhook", func() { It("does not allow updates on operator policy name", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.Name = "new-name" - Expect(apierrors.IsForbidden(ignoreNilWarning(newPolicy.ValidateUpdate(&policy)))).To(BeTrue()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on vhost", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.Vhost = "new-vhost" - Expect(apierrors.IsForbidden(ignoreNilWarning(newPolicy.ValidateUpdate(&policy)))).To(BeTrue()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on RabbitmqClusterReference", func() { @@ -59,7 +66,8 @@ var _ = Describe("policy webhook", func() { newPolicy.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "new-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newPolicy.ValidateUpdate(&policy)))).To(BeTrue()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { @@ -80,33 +88,38 @@ var _ = Describe("policy webhook", func() { }, }, } - new := connectionScr.DeepCopy() - new.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" - Expect(apierrors.IsForbidden(ignoreNilWarning(new.ValidateUpdate(&connectionScr)))).To(BeTrue()) + newOperatorPolicy := connectionScr.DeepCopy() + newOperatorPolicy.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" + _, err := newOperatorPolicy.ValidateUpdate(rootCtx, &connectionScr, newOperatorPolicy) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("allows updates on operator policy.spec.pattern", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.Pattern = "new-pattern" - Expect(ignoreNilWarning(newPolicy.ValidateUpdate(&policy))).To(Succeed()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).To(Succeed()) }) It("allows updates on operator policy.spec.applyTo", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.ApplyTo = "queues" - Expect(ignoreNilWarning(newPolicy.ValidateUpdate(&policy))).To(Succeed()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).To(Succeed()) }) It("allows updates on operator policy.spec.priority", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.Priority = 1000 - Expect(ignoreNilWarning(newPolicy.ValidateUpdate(&policy))).To(Succeed()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).To(Succeed()) }) It("allows updates on operator policy.spec.definition", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.Definition = &runtime.RawExtension{Raw: []byte(`{"key":"new-definition-value"}`)} - Expect(ignoreNilWarning(newPolicy.ValidateUpdate(&policy))).To(Succeed()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).To(Succeed()) }) }) }) diff --git a/api/v1beta1/permission_webhook.go b/api/v1beta1/permission_webhook.go index bb26de08..1b9a3bac 100644 --- a/api/v1beta1/permission_webhook.go +++ b/api/v1beta1/permission_webhook.go @@ -1,6 +1,7 @@ package v1beta1 import ( + "context" "fmt" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -19,72 +20,83 @@ func (p *Permission) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1beta1-permission,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=permissions,versions=v1beta1,name=vpermission.kb.io,sideEffects=none,admissionReviewVersions=v1 -var _ webhook.Validator = &Permission{} +var _ webhook.CustomValidator = &Permission{} // ValidateCreate checks if only one of spec.user and spec.userReference is specified // either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both -func (p *Permission) ValidateCreate() (admission.Warnings, error) { - var errorList field.ErrorList - if p.Spec.User == "" && p.Spec.UserReference == nil { - errorList = append(errorList, field.Required(field.NewPath("spec", "user and userReference"), - "must specify either spec.user or spec.userReference")) - return nil, apierrors.NewInvalid(GroupVersion.WithKind("Permission").GroupKind(), p.Name, errorList) +func (p *Permission) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + pe, ok := obj.(*Permission) + if !ok { + return nil, fmt.Errorf("expected a RabbitMQ permission but got a %T", obj) } - if p.Spec.User != "" && p.Spec.UserReference != nil { - errorList = append(errorList, field.Required(field.NewPath("spec", "user and userReference"), - "cannot specify spec.user and spec.userReference at the same time")) - return nil, apierrors.NewInvalid(GroupVersion.WithKind("Permission").GroupKind(), p.Name, errorList) + if pe.Spec.User == "" && pe.Spec.UserReference == nil { + return nil, field.Required(field.NewPath("spec", "user and userReference"), + "must specify either spec.user or spec.userReference") + } + + if pe.Spec.User != "" && pe.Spec.UserReference != nil { + return nil, field.Required(field.NewPath("spec", "user and userReference"), + "cannot specify spec.user and spec.userReference at the same time") } - return p.Spec.RabbitmqClusterReference.ValidateOnCreate(p.GroupResource(), p.Name) + return nil, pe.Spec.RabbitmqClusterReference.validate(pe.RabbitReference()) } // ValidateUpdate do not allow updates on spec.vhost, spec.user, spec.userReference, and spec.rabbitmqClusterReference // updates on spec.permissions are allowed // only one of spec.user and spec.userReference can be specified -func (p *Permission) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldPermission, ok := old.(*Permission) +func (p *Permission) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldPermission, ok := oldObj.(*Permission) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a permission but got a %T", old)) + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a permission but got a %T", oldObj)) + } + + newPermission, ok := newObj.(*Permission) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a permission but got a %T", newObj)) } var errorList field.ErrorList - if p.Spec.User == "" && p.Spec.UserReference == nil { + if newPermission.Spec.User == "" && newPermission.Spec.UserReference == nil { errorList = append(errorList, field.Required(field.NewPath("spec", "user and userReference"), "must specify either spec.user or spec.userReference")) - return nil, apierrors.NewInvalid(GroupVersion.WithKind("Permission").GroupKind(), p.Name, errorList) + return nil, apierrors.NewInvalid(GroupVersion.WithKind("Permission").GroupKind(), newPermission.Name, errorList) } - if p.Spec.User != "" && p.Spec.UserReference != nil { + if newPermission.Spec.User != "" && newPermission.Spec.UserReference != nil { errorList = append(errorList, field.Required(field.NewPath("spec", "user and userReference"), "cannot specify spec.user and spec.userReference at the same time")) - return nil, apierrors.NewInvalid(GroupVersion.WithKind("Permission").GroupKind(), p.Name, errorList) + return nil, apierrors.NewInvalid(GroupVersion.WithKind("Permission").GroupKind(), newPermission.Name, errorList) } - detailMsg := "updates on user, userReference, vhost and rabbitmqClusterReference are all forbidden" - if p.Spec.User != oldPermission.Spec.User { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + const detailMsg = "updates on user, userReference, vhost and rabbitmqClusterReference are all forbidden" + if newPermission.Spec.User != oldPermission.Spec.User { + return nil, apierrors.NewForbidden(newPermission.GroupResource(), newPermission.Name, field.Forbidden(field.NewPath("spec", "user"), detailMsg)) } - if userReferenceUpdated(p.Spec.UserReference, oldPermission.Spec.UserReference) { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + if userReferenceUpdated(newPermission.Spec.UserReference, oldPermission.Spec.UserReference) { + return nil, apierrors.NewForbidden(newPermission.GroupResource(), newPermission.Name, field.Forbidden(field.NewPath("spec", "userReference"), detailMsg)) } - if p.Spec.Vhost != oldPermission.Spec.Vhost { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + if newPermission.Spec.Vhost != oldPermission.Spec.Vhost { + return nil, apierrors.NewForbidden(newPermission.GroupResource(), newPermission.Name, field.Forbidden(field.NewPath("spec", "vhost"), detailMsg)) } - if !oldPermission.Spec.RabbitmqClusterReference.Matches(&p.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + if !oldPermission.Spec.RabbitmqClusterReference.Matches(&newPermission.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newPermission.GroupResource(), newPermission.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), detailMsg)) } return nil, nil } +func (p *Permission) ValidateDelete(_ context.Context, _ runtime.Object) (warnings admission.Warnings, err error) { + return nil, nil +} + // returns true if userReference, which is a pointer to corev1.LocalObjectReference, has changed func userReferenceUpdated(new, old *corev1.LocalObjectReference) bool { if new == nil && old == nil { @@ -99,8 +111,3 @@ func userReferenceUpdated(new, old *corev1.LocalObjectReference) bool { } return false } - -// ValidateDelete no validation on delete -func (p *Permission) ValidateDelete() (admission.Warnings, error) { - return nil, nil -} diff --git a/api/v1beta1/permission_webhook_test.go b/api/v1beta1/permission_webhook_test.go index 1a5152ac..a0983852 100644 --- a/api/v1beta1/permission_webhook_test.go +++ b/api/v1beta1/permission_webhook_test.go @@ -1,57 +1,64 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var _ = Describe("permission webhook", func() { - var permission = Permission{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - }, - Spec: PermissionSpec{ - User: "test-user", - Vhost: "/a-vhost", - Permissions: VhostPermissions{ - Configure: ".*", - Read: ".*", - Write: ".*", + var ( + permission = Permission{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", }, - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "a-cluster", + Spec: PermissionSpec{ + User: "test-user", + Vhost: "/a-vhost", + Permissions: VhostPermissions{ + Configure: ".*", + Read: ".*", + Write: ".*", + }, + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "a-cluster", + }, }, - }, - } + } + rootCtx = context.Background() + ) Context("ValidateCreate", func() { It("does not allow user and userReference to be specified at the same time", func() { invalidPermission := permission.DeepCopy() invalidPermission.Spec.UserReference = &corev1.LocalObjectReference{Name: "invalid"} invalidPermission.Spec.User = "test-user" - Expect(apierrors.IsInvalid(ignoreNilWarning(invalidPermission.ValidateCreate()))).To(BeTrue()) + _, err := invalidPermission.ValidateCreate(rootCtx, invalidPermission) + Expect(err).To(MatchError(ContainSubstring("cannot specify spec.user and spec.userReference at the same time"))) }) It("does not allow both user and userReference to be unset", func() { invalidPermission := permission.DeepCopy() invalidPermission.Spec.UserReference = nil invalidPermission.Spec.User = "" - Expect(apierrors.IsInvalid(ignoreNilWarning(invalidPermission.ValidateCreate()))).To(BeTrue()) + _, err := invalidPermission.ValidateCreate(rootCtx, invalidPermission) + Expect(err).To(MatchError(ContainSubstring("must specify either spec.user or spec.userReference"))) }) It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := permission.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := permission.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) }) @@ -59,7 +66,8 @@ var _ = Describe("permission webhook", func() { It("does not allow updates on user", func() { newPermission := permission.DeepCopy() newPermission.Spec.User = "new-user" - Expect(apierrors.IsForbidden(ignoreNilWarning(newPermission.ValidateUpdate(&permission)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("updates on user, userReference, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on userReference", func() { @@ -68,13 +76,15 @@ var _ = Describe("permission webhook", func() { permissionWithUserRef.Spec.UserReference = &corev1.LocalObjectReference{Name: "a-user"} newPermission := permissionWithUserRef.DeepCopy() newPermission.Spec.UserReference = &corev1.LocalObjectReference{Name: "a-new-user"} - Expect(apierrors.IsForbidden(ignoreNilWarning(newPermission.ValidateUpdate(permissionWithUserRef)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("updates on user, userReference, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on vhost", func() { newPermission := permission.DeepCopy() newPermission.Spec.Vhost = "new-vhost" - Expect(apierrors.IsForbidden(ignoreNilWarning(newPermission.ValidateUpdate(&permission)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("updates on user, userReference, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on RabbitmqClusterReference", func() { @@ -82,7 +92,8 @@ var _ = Describe("permission webhook", func() { newPermission.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "new-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newPermission.ValidateUpdate(&permission)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("updates on user, userReference, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { @@ -105,40 +116,46 @@ var _ = Describe("permission webhook", func() { }, }, } - new := connectionScr.DeepCopy() - new.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" - Expect(apierrors.IsForbidden(ignoreNilWarning(new.ValidateUpdate(&connectionScr)))).To(BeTrue()) + newPermission := connectionScr.DeepCopy() + newPermission.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" + _, err := newPermission.ValidateUpdate(rootCtx, &connectionScr, newPermission) + Expect(err).To(MatchError(ContainSubstring("updates on user, userReference, vhost and rabbitmqClusterReference are all forbidden"))) }) It("allows updates on permission.spec.permissions.configure", func() { newPermission := permission.DeepCopy() newPermission.Spec.Permissions.Configure = "?" - Expect(ignoreNilWarning(newPermission.ValidateUpdate(&permission))).To(Succeed()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).ToNot(HaveOccurred()) }) It("allows updates on permission.spec.permissions.read", func() { newPermission := permission.DeepCopy() newPermission.Spec.Permissions.Read = "?" - Expect(ignoreNilWarning(newPermission.ValidateUpdate(&permission))).To(Succeed()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).ToNot(HaveOccurred()) }) It("allows updates on permission.spec.permissions.write", func() { newPermission := permission.DeepCopy() newPermission.Spec.Permissions.Write = "?" - Expect(ignoreNilWarning(newPermission.ValidateUpdate(&permission))).To(Succeed()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).ToNot(HaveOccurred()) }) It("does not allow user and userReference to be specified at the same time", func() { newPermission := permission.DeepCopy() newPermission.Spec.UserReference = &corev1.LocalObjectReference{Name: "invalid"} - Expect(apierrors.IsInvalid(ignoreNilWarning(newPermission.ValidateUpdate(&permission)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("cannot specify spec.user and spec.userReference at the same time"))) }) It("does not allow both user and userReference to be unset", func() { newPermission := permission.DeepCopy() newPermission.Spec.User = "" newPermission.Spec.UserReference = nil - Expect(apierrors.IsInvalid(ignoreNilWarning(newPermission.ValidateUpdate(&permission)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("must specify either spec.user or spec.userReference"))) }) }) }) diff --git a/api/v1beta1/policy_webhook.go b/api/v1beta1/policy_webhook.go index deefc6cb..3d4c2cd6 100644 --- a/api/v1beta1/policy_webhook.go +++ b/api/v1beta1/policy_webhook.go @@ -1,6 +1,7 @@ package v1beta1 import ( + "context" "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -18,39 +19,48 @@ func (p *Policy) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1beta1-policy,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=policies,versions=v1beta1,name=vpolicy.kb.io,sideEffects=none,admissionReviewVersions=v1 -var _ webhook.Validator = &Policy{} +var _ webhook.CustomValidator = &Policy{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type // either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both -func (p *Policy) ValidateCreate() (admission.Warnings, error) { - return p.Spec.RabbitmqClusterReference.ValidateOnCreate(p.GroupResource(), p.Name) +func (p *Policy) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + policy, ok := obj.(*Policy) + if !ok { + return nil, fmt.Errorf("expected a RabbitMQ policy but got a %T", obj) + } + return nil, p.Spec.RabbitmqClusterReference.validate(policy.RabbitReference()) } // ValidateUpdate returns error type 'forbidden' for updates on policy name, vhost and rabbitmqClusterReference -func (p *Policy) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldPolicy, ok := old.(*Policy) +func (p *Policy) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldPolicy, ok := oldObj.(*Policy) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a policy but got a %T", oldObj)) + } + + newPolicy, ok := newObj.(*Policy) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a policy but got a %T", old)) + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a policy but got a %T", newObj)) } - detailMsg := "updates on name, vhost and rabbitmqClusterReference are all forbidden" - if p.Spec.Name != oldPolicy.Spec.Name { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + const detailMsg = "updates on name, vhost and rabbitmqClusterReference are all forbidden" + if newPolicy.Spec.Name != oldPolicy.Spec.Name { + return nil, apierrors.NewForbidden(newPolicy.GroupResource(), newPolicy.Name, field.Forbidden(field.NewPath("spec", "name"), detailMsg)) } - if p.Spec.Vhost != oldPolicy.Spec.Vhost { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + if newPolicy.Spec.Vhost != oldPolicy.Spec.Vhost { + return nil, apierrors.NewForbidden(newPolicy.GroupResource(), newPolicy.Name, field.Forbidden(field.NewPath("spec", "vhost"), detailMsg)) } - if !oldPolicy.Spec.RabbitmqClusterReference.Matches(&p.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + if !oldPolicy.Spec.RabbitmqClusterReference.Matches(&newPolicy.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newPolicy.GroupResource(), newPolicy.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), detailMsg)) } return nil, nil } -func (p *Policy) ValidateDelete() (admission.Warnings, error) { +func (p *Policy) ValidateDelete(_ context.Context, _ runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } diff --git a/api/v1beta1/policy_webhook_test.go b/api/v1beta1/policy_webhook_test.go index bcb895b8..c593bab6 100644 --- a/api/v1beta1/policy_webhook_test.go +++ b/api/v1beta1/policy_webhook_test.go @@ -1,43 +1,48 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) var _ = Describe("policy webhook", func() { - var policy = Policy{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - }, - Spec: PolicySpec{ - Name: "test", - Vhost: "/test", - Pattern: "a-pattern", - ApplyTo: "all", - Priority: 0, - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "a-cluster", + var ( + policy = Policy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", }, - }, - } + Spec: PolicySpec{ + Name: "test", + Vhost: "/test", + Pattern: "a-pattern", + ApplyTo: "all", + Priority: 0, + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "a-cluster", + }, + }, + } + rootCtx = context.Background() + ) Context("ValidateCreate", func() { It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := policy.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := policy.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) }) @@ -45,13 +50,15 @@ var _ = Describe("policy webhook", func() { It("does not allow updates on policy name", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.Name = "new-name" - Expect(apierrors.IsForbidden(ignoreNilWarning(newPolicy.ValidateUpdate(&policy)))).To(BeTrue()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on vhost", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.Vhost = "new-vhost" - Expect(apierrors.IsForbidden(ignoreNilWarning(newPolicy.ValidateUpdate(&policy)))).To(BeTrue()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on RabbitmqClusterReference", func() { @@ -59,7 +66,8 @@ var _ = Describe("policy webhook", func() { newPolicy.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "new-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newPolicy.ValidateUpdate(&policy)))).To(BeTrue()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { @@ -80,33 +88,38 @@ var _ = Describe("policy webhook", func() { }, }, } - new := connectionScr.DeepCopy() - new.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" - Expect(apierrors.IsForbidden(ignoreNilWarning(new.ValidateUpdate(&connectionScr)))).To(BeTrue()) + newPolicy := connectionScr.DeepCopy() + newPolicy.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" + _, err := newPolicy.ValidateUpdate(rootCtx, &connectionScr, newPolicy) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("allows updates on policy.spec.pattern", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.Pattern = "new-pattern" - Expect(ignoreNilWarning(newPolicy.ValidateUpdate(&policy))).To(Succeed()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).ToNot(HaveOccurred()) }) It("allows updates on policy.spec.applyTo", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.ApplyTo = "queues" - Expect(ignoreNilWarning(newPolicy.ValidateUpdate(&policy))).To(Succeed()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).ToNot(HaveOccurred()) }) It("allows updates on policy.spec.priority", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.Priority = 1000 - Expect(ignoreNilWarning(newPolicy.ValidateUpdate(&policy))).To(Succeed()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).ToNot(HaveOccurred()) }) It("allows updates on policy.spec.definition", func() { newPolicy := policy.DeepCopy() newPolicy.Spec.Definition = &runtime.RawExtension{Raw: []byte(`{"key":"new-definition-value"}`)} - Expect(ignoreNilWarning(newPolicy.ValidateUpdate(&policy))).To(Succeed()) + _, err := newPolicy.ValidateUpdate(rootCtx, &policy, newPolicy) + Expect(err).ToNot(HaveOccurred()) }) }) }) diff --git a/api/v1beta1/queue_webhook.go b/api/v1beta1/queue_webhook.go index f9c94d97..93b22090 100644 --- a/api/v1beta1/queue_webhook.go +++ b/api/v1beta1/queue_webhook.go @@ -1,6 +1,7 @@ package v1beta1 import ( + "context" "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -18,66 +19,75 @@ func (q *Queue) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1beta1-queue,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=queues,versions=v1beta1,name=vqueue.kb.io,sideEffects=none,admissionReviewVersions=v1sideEffects=none,admissionReviewVersions=v1 -var _ webhook.Validator = &Queue{} +var _ webhook.CustomValidator = &Queue{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type // either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both -func (q *Queue) ValidateCreate() (admission.Warnings, error) { - if q.Spec.Type == "quorum" && q.Spec.Durable == false { - return nil, apierrors.NewForbidden(q.GroupResource(), q.Name, +func (q *Queue) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + inQueue, ok := obj.(*Queue) + if !ok { + return nil, fmt.Errorf("expected RabbitMQ queue, got %T", obj) + } + if inQueue.Spec.Type == "quorum" && inQueue.Spec.Durable == false { + return nil, apierrors.NewForbidden(inQueue.GroupResource(), inQueue.Name, field.Forbidden(field.NewPath("spec", "durable"), "Quorum queues must have durable set to true")) } - return q.Spec.RabbitmqClusterReference.ValidateOnCreate(q.GroupResource(), q.Name) + return nil, q.Spec.RabbitmqClusterReference.validate(inQueue.RabbitReference()) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type // returns error type 'forbidden' for updates that the controller chooses to disallow: queue name/vhost/rabbitmqClusterReference // returns error type 'invalid' for updates that will be rejected by rabbitmq server: queue types/autoDelete/durable // queue arguments not handled because implementation couldn't change -func (q *Queue) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldQueue, ok := old.(*Queue) +func (q *Queue) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldQueue, ok := oldObj.(*Queue) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a queue but got a %T", oldObj)) + } + + newQueue, ok := newObj.(*Queue) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a queue but got a %T", old)) + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a queue but got a %T", newObj)) } var allErrs field.ErrorList - detailMsg := "updates on name, vhost, and rabbitmqClusterReference are all forbidden" - if q.Spec.Name != oldQueue.Spec.Name { - return nil, apierrors.NewForbidden(q.GroupResource(), q.Name, + const detailMsg = "updates on name, vhost, and rabbitmqClusterReference are all forbidden" + if newQueue.Spec.Name != oldQueue.Spec.Name { + return nil, apierrors.NewForbidden(newQueue.GroupResource(), newQueue.Name, field.Forbidden(field.NewPath("spec", "name"), detailMsg)) } - if q.Spec.Vhost != oldQueue.Spec.Vhost { - return nil, apierrors.NewForbidden(q.GroupResource(), q.Name, + if newQueue.Spec.Vhost != oldQueue.Spec.Vhost { + return nil, apierrors.NewForbidden(newQueue.GroupResource(), newQueue.Name, field.Forbidden(field.NewPath("spec", "vhost"), detailMsg)) } - if !oldQueue.Spec.RabbitmqClusterReference.Matches(&q.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(q.GroupResource(), q.Name, + if !oldQueue.Spec.RabbitmqClusterReference.Matches(&newQueue.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newQueue.GroupResource(), newQueue.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), detailMsg)) } - if q.Spec.Type != oldQueue.Spec.Type { + if newQueue.Spec.Type != oldQueue.Spec.Type { allErrs = append(allErrs, field.Invalid( field.NewPath("spec", "type"), - q.Spec.Type, + newQueue.Spec.Type, "queue type cannot be updated", )) } - if q.Spec.AutoDelete != oldQueue.Spec.AutoDelete { + if newQueue.Spec.AutoDelete != oldQueue.Spec.AutoDelete { allErrs = append(allErrs, field.Invalid( field.NewPath("spec", "autoDelete"), - q.Spec.AutoDelete, + newQueue.Spec.AutoDelete, "autoDelete cannot be updated", )) } - if q.Spec.Durable != oldQueue.Spec.Durable { + if newQueue.Spec.Durable != oldQueue.Spec.Durable { allErrs = append(allErrs, field.Invalid( field.NewPath("spec", "durable"), - q.Spec.AutoDelete, + newQueue.Spec.AutoDelete, "durable cannot be updated", )) } @@ -86,9 +96,9 @@ func (q *Queue) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { return nil, nil } - return nil, apierrors.NewInvalid(GroupVersion.WithKind("Queue").GroupKind(), q.Name, allErrs) + return nil, allErrs.ToAggregate() } -func (q *Queue) ValidateDelete() (admission.Warnings, error) { +func (q *Queue) ValidateDelete(_ context.Context, _ runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } diff --git a/api/v1beta1/queue_webhook_test.go b/api/v1beta1/queue_webhook_test.go index 09ba709b..6bbbbe1f 100644 --- a/api/v1beta1/queue_webhook_test.go +++ b/api/v1beta1/queue_webhook_test.go @@ -1,49 +1,57 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var _ = Describe("queue webhook", func() { - var queue = Queue{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-queue", - }, - Spec: QueueSpec{ - Name: "test", - Vhost: "/a-vhost", - Type: "quorum", - Durable: false, - AutoDelete: true, - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "some-cluster", + var ( + queue = Queue{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-queue", }, - }, - } + Spec: QueueSpec{ + Name: "test", + Vhost: "/a-vhost", + Type: "quorum", + Durable: false, + AutoDelete: true, + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "some-cluster", + }, + }, + } + rootCtx = context.Background() + ) Context("ValidateCreate", func() { It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowedQ := queue.DeepCopy() + notAllowedQ.Spec.Durable = true notAllowedQ.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowedQ.ValidateCreate()))).To(BeTrue()) + _, err := notAllowedQ.ValidateCreate(rootCtx, notAllowedQ) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowedQ := queue.DeepCopy() + notAllowedQ.Spec.Durable = true notAllowedQ.Spec.RabbitmqClusterReference.Name = "" notAllowedQ.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowedQ.ValidateCreate()))).To(BeTrue()) + _, err := notAllowedQ.ValidateCreate(rootCtx, notAllowedQ) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) It("does not allow non-durable quorum queues", func() { notAllowedQ := queue.DeepCopy() notAllowedQ.Spec.AutoDelete = false - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowedQ.ValidateCreate()))).To(BeTrue(), "Expected 'forbidden' response for non-durable quorum queue") + _, err := notAllowedQ.ValidateCreate(rootCtx, notAllowedQ) + Expect(err).To(MatchError(ContainSubstring("Quorum queues must have durable set to true"))) }) }) @@ -51,13 +59,15 @@ var _ = Describe("queue webhook", func() { It("does not allow updates on queue name", func() { newQueue := queue.DeepCopy() newQueue.Spec.Name = "new-name" - Expect(apierrors.IsForbidden(ignoreNilWarning(newQueue.ValidateUpdate(&queue)))).To(BeTrue()) + _, err := newQueue.ValidateUpdate(rootCtx, &queue, newQueue) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost, and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on vhost", func() { newQueue := queue.DeepCopy() newQueue.Spec.Vhost = "/new-vhost" - Expect(apierrors.IsForbidden(ignoreNilWarning(newQueue.ValidateUpdate(&queue)))).To(BeTrue()) + _, err := newQueue.ValidateUpdate(rootCtx, &queue, newQueue) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost, and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.name", func() { @@ -65,7 +75,8 @@ var _ = Describe("queue webhook", func() { newQueue.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "new-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newQueue.ValidateUpdate(&queue)))).To(BeTrue()) + _, err := newQueue.ValidateUpdate(rootCtx, &queue, newQueue) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost, and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.namespace", func() { @@ -73,7 +84,8 @@ var _ = Describe("queue webhook", func() { newQueue.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Namespace: "new-ns", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newQueue.ValidateUpdate(&queue)))).To(BeTrue()) + _, err := newQueue.ValidateUpdate(rootCtx, &queue, newQueue) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost, and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { @@ -92,25 +104,29 @@ var _ = Describe("queue webhook", func() { } newQueue := connectionScrQ.DeepCopy() newQueue.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" - Expect(apierrors.IsForbidden(ignoreNilWarning(newQueue.ValidateUpdate(&connectionScrQ)))).To(BeTrue()) + _, err := newQueue.ValidateUpdate(rootCtx, &connectionScrQ, newQueue) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost, and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on queue type", func() { newQueue := queue.DeepCopy() newQueue.Spec.Type = "classic" - Expect(apierrors.IsInvalid(ignoreNilWarning(newQueue.ValidateUpdate(&queue)))).To(BeTrue()) + _, err := newQueue.ValidateUpdate(rootCtx, &queue, newQueue) + Expect(err).To(MatchError(ContainSubstring("queue type cannot be updated"))) }) It("does not allow updates on durable", func() { newQueue := queue.DeepCopy() newQueue.Spec.Durable = true - Expect(apierrors.IsInvalid(ignoreNilWarning(newQueue.ValidateUpdate(&queue)))).To(BeTrue()) + _, err := newQueue.ValidateUpdate(rootCtx, &queue, newQueue) + Expect(err).To(MatchError(ContainSubstring("durable cannot be updated"))) }) It("does not allow updates on autoDelete", func() { newQueue := queue.DeepCopy() newQueue.Spec.AutoDelete = false - Expect(apierrors.IsInvalid(ignoreNilWarning(newQueue.ValidateUpdate(&queue)))).To(BeTrue()) + _, err := newQueue.ValidateUpdate(rootCtx, &queue, newQueue) + Expect(err).To(MatchError(ContainSubstring("autoDelete cannot be updated"))) }) }) }) diff --git a/api/v1beta1/rabbitmq_cluster_reference.go b/api/v1beta1/rabbitmq_cluster_reference.go index 50c45f61..77444dd7 100644 --- a/api/v1beta1/rabbitmq_cluster_reference.go +++ b/api/v1beta1/rabbitmq_cluster_reference.go @@ -1,10 +1,9 @@ package v1beta1 import ( + "errors" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/validation/field" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -49,17 +48,18 @@ func (r *RabbitmqClusterReference) Matches(new *RabbitmqClusterReference) bool { // ValidateOnCreate validates RabbitmqClusterReference on resources create // either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both; else it errors -func (ref *RabbitmqClusterReference) ValidateOnCreate(groupResource schema.GroupResource, name string) (admission.Warnings, error) { +func (r *RabbitmqClusterReference) ValidateOnCreate(_ schema.GroupResource, _ string) (admission.Warnings, error) { + // TODO: make this function private when we deprecate or promote v1alpha1 SuperStreamController + return nil, r.validate(*r) +} + +func (r *RabbitmqClusterReference) validate(ref RabbitmqClusterReference) error { if ref.Name != "" && ref.ConnectionSecret != nil { - return nil, apierrors.NewForbidden(groupResource, name, - field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), - "do not provide both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret")) + return errors.New("invalid RabbitmqClusterReference: do not provide both name and connectionSecret") } if ref.Name == "" && ref.ConnectionSecret == nil { - return nil, apierrors.NewForbidden(groupResource, name, - field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), - "must provide either spec.rabbitmqClusterReference.name or spec.rabbitmqClusterReference.connectionSecret")) + return errors.New("invalid RabbitmqClusterReference: must provide either name or connectionSecret") } - return nil, nil + return nil } diff --git a/api/v1beta1/rabbitmq_cluster_reference_test.go b/api/v1beta1/rabbitmq_cluster_reference_test.go index 79c98a91..a7a0c89d 100644 --- a/api/v1beta1/rabbitmq_cluster_reference_test.go +++ b/api/v1beta1/rabbitmq_cluster_reference_test.go @@ -4,7 +4,6 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" v1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" ) @@ -24,51 +23,51 @@ var _ = Describe("RabbitmqClusterReference", func() { Context("Matches", func() { When("name is different", func() { It("returns false", func() { - new := reference.DeepCopy() - new.Name = "new-name" - Expect(reference.Matches(new)).To(BeFalse()) + newReference := reference.DeepCopy() + newReference.Name = "new-name" + Expect(reference.Matches(newReference)).To(BeFalse()) }) }) When("namespace is different", func() { It("returns false", func() { - new := reference.DeepCopy() - new.Namespace = "new-ns" - Expect(reference.Matches(new)).To(BeFalse()) + newReference := reference.DeepCopy() + newReference.Namespace = "new-ns" + Expect(reference.Matches(newReference)).To(BeFalse()) }) }) When("connectionSecret.name is different", func() { It("returns false", func() { - new := reference.DeepCopy() - new.ConnectionSecret.Name = "new-secret-name" - Expect(reference.Matches(new)).To(BeFalse()) + newReference := reference.DeepCopy() + newReference.ConnectionSecret.Name = "new-secret-name" + Expect(reference.Matches(newReference)).To(BeFalse()) }) }) When("connectionSecret is removed", func() { It("returns false", func() { - new := reference.DeepCopy() - new.ConnectionSecret = nil - Expect(reference.Matches(new)).To(BeFalse()) + newReference := reference.DeepCopy() + newReference.ConnectionSecret = nil + Expect(reference.Matches(newReference)).To(BeFalse()) }) }) When("connectionSecret is added", func() { It("returns false", func() { reference.ConnectionSecret = nil - new := reference.DeepCopy() - new.ConnectionSecret = &v1.LocalObjectReference{ + newReference := reference.DeepCopy() + newReference.ConnectionSecret = &v1.LocalObjectReference{ Name: "a-secret-name", } - Expect(reference.Matches(new)).To(BeFalse()) + Expect(reference.Matches(newReference)).To(BeFalse()) }) }) When("RabbitmqClusterReference stayed the same", func() { It("returns true", func() { - new := reference.DeepCopy() - Expect(reference.Matches(new)).To(BeTrue()) + newReference := reference.DeepCopy() + Expect(reference.Matches(newReference)).To(BeTrue()) }) }) }) @@ -94,7 +93,8 @@ var _ = Describe("RabbitmqClusterReference", func() { It("returns a forbidden api error", func() { reference.Name = "a-cluster" reference.ConnectionSecret = &v1.LocalObjectReference{Name: "a-secret-name"} - Expect(apierrors.IsForbidden(ignoreNilWarning(reference.ValidateOnCreate(schema.GroupResource{}, "a-resource")))).To(BeTrue()) + _, err := reference.ValidateOnCreate(schema.GroupResource{}, "a-resource") + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) }) @@ -102,7 +102,8 @@ var _ = Describe("RabbitmqClusterReference", func() { It("returns a forbidden api error", func() { reference.ConnectionSecret = nil reference.Name = "" - Expect(apierrors.IsForbidden(ignoreNilWarning(reference.ValidateOnCreate(schema.GroupResource{}, "a-resource")))).To(BeTrue()) + _, err := reference.ValidateOnCreate(schema.GroupResource{}, "a-resource") + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) }) }) diff --git a/api/v1beta1/schemareplication_webhook.go b/api/v1beta1/schemareplication_webhook.go index 609af3b3..f38220de 100644 --- a/api/v1beta1/schemareplication_webhook.go +++ b/api/v1beta1/schemareplication_webhook.go @@ -1,6 +1,7 @@ package v1beta1 import ( + "context" "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -18,49 +19,60 @@ func (s *SchemaReplication) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1beta1-schemareplication,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=schemareplications,versions=v1beta1,name=vschemareplication.kb.io,sideEffects=none,admissionReviewVersions=v1 -var _ webhook.Validator = &SchemaReplication{} +var _ webhook.CustomValidator = &SchemaReplication{} -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type. -// either secretBackend.vault.secretPath or upstreamSecret must be provided but not both. -// either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both. -func (s *SchemaReplication) ValidateCreate() (admission.Warnings, error) { - if err := s.validateSecret(); err != nil { +// ValidateCreate - either secretBackend.vault.secretPath or upstreamSecret must +// be provided but not both. Either rabbitmqClusterReference.name or +// rabbitmqClusterReference.connectionSecret must be provided but not both. +func (s *SchemaReplication) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + sch, ok := obj.(*SchemaReplication) + if !ok { + return nil, fmt.Errorf("expected a schema replication type but got a %T", obj) + } + err = sch.validateSecret() + if err != nil { return nil, err } - return s.Spec.RabbitmqClusterReference.ValidateOnCreate(s.GroupResource(), s.Name) + + return nil, s.Spec.RabbitmqClusterReference.validate(sch.RabbitReference()) } -// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. -// either secretBackend.vault.secretPath or upstreamSecret must be provided but not both. -func (s *SchemaReplication) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldReplication, ok := old.(*SchemaReplication) +// ValidateUpdate - either secretBackend.vault.secretPath or upstreamSecret must +// be provided but not both. +func (s *SchemaReplication) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldReplication, ok := oldObj.(*SchemaReplication) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a schema replication type but got a %T", oldObj)) + } + + newReplication, ok := newObj.(*SchemaReplication) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a schema replication type but got a %T", old)) + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a schema replication type but got a %T", newObj)) } - if !oldReplication.Spec.RabbitmqClusterReference.Matches(&s.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(s.GroupResource(), s.Name, + if !oldReplication.Spec.RabbitmqClusterReference.Matches(&newReplication.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newReplication.GroupResource(), newReplication.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), "update on rabbitmqClusterReference is forbidden")) } - return nil, s.validateSecret() + return nil, newReplication.validateSecret() } // ValidateDelete no validation on delete -func (s *SchemaReplication) ValidateDelete() (admission.Warnings, error) { +func (s *SchemaReplication) ValidateDelete(_ context.Context, _ runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } func (s *SchemaReplication) validateSecret() error { - if s.Spec.UpstreamSecret != nil && s.Spec.UpstreamSecret.Name != "" && s.Spec.SecretBackend.Vault != nil && s.Spec.SecretBackend.Vault.SecretPath != "" { - return apierrors.NewForbidden(s.GroupResource(), s.Name, - field.Forbidden(field.NewPath("spec"), - "do not provide both secretBackend.vault.secretPath and upstreamSecret")) + if s.Spec.UpstreamSecret != nil && + s.Spec.UpstreamSecret.Name != "" && + s.Spec.SecretBackend.Vault != nil && + s.Spec.SecretBackend.Vault.SecretPath != "" { + return field.Forbidden(field.NewPath("spec"), "do not provide both secretBackend.vault.secretPath and upstreamSecret") } - if (s.Spec.UpstreamSecret == nil || s.Spec.UpstreamSecret.Name == "") && (s.Spec.SecretBackend.Vault == nil || s.Spec.SecretBackend.Vault.SecretPath == "") { - return apierrors.NewForbidden(s.GroupResource(), s.Name, - field.Forbidden(field.NewPath("spec"), - "must provide either secretBackend.vault.secretPath or upstreamSecret")) + if (s.Spec.UpstreamSecret == nil || s.Spec.UpstreamSecret.Name == "") && + (s.Spec.SecretBackend.Vault == nil || s.Spec.SecretBackend.Vault.SecretPath == "") { + return field.Forbidden(field.NewPath("spec"), "must provide either secretBackend.vault.secretPath or upstreamSecret") } return nil } diff --git a/api/v1beta1/schemareplication_webhook_test.go b/api/v1beta1/schemareplication_webhook_test.go index 192e9fde..0f5a5c86 100644 --- a/api/v1beta1/schemareplication_webhook_test.go +++ b/api/v1beta1/schemareplication_webhook_test.go @@ -1,41 +1,46 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var _ = Describe("schema-replication webhook", func() { - var replication = SchemaReplication{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-replication", - }, - Spec: SchemaReplicationSpec{ - UpstreamSecret: &corev1.LocalObjectReference{ - Name: "a-secret", + var ( + replication = SchemaReplication{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-replication", }, - Endpoints: "abc.rmq.com:1234", - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "a-cluster", + Spec: SchemaReplicationSpec{ + UpstreamSecret: &corev1.LocalObjectReference{ + Name: "a-secret", + }, + Endpoints: "abc.rmq.com:1234", + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "a-cluster", + }, }, - }, - } + } + rootCtx = context.Background() + ) Context("ValidateCreate", func() { It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := replication.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := replication.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) It("does not allow both spec.upstreamSecret and spec.secretBackend.vault.userPath be configured", func() { @@ -45,16 +50,18 @@ var _ = Describe("schema-replication webhook", func() { SecretPath: "not-good", }, } - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("do not provide both secretBackend.vault.secretPath and upstreamSecret"))) }) - It("spec.upstreamSecret and spec.secretBackend.vault.userPath cannot both be not configured", func() { + It("validates that either upstream secret or vault backend are configured", func() { notAllowed := replication.DeepCopy() notAllowed.Spec.SecretBackend = SecretBackend{ Vault: &VaultSpec{}, } notAllowed.Spec.UpstreamSecret.Name = "" - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("must provide either secretBackend.vault.secretPath or upstreamSecret"))) }) }) @@ -64,7 +71,8 @@ var _ = Describe("schema-replication webhook", func() { updated.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "different-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(updated.ValidateUpdate(&replication)))).To(BeTrue()) + _, err := updated.ValidateUpdate(rootCtx, &replication, updated) + Expect(err).To(MatchError(ContainSubstring("update on rabbitmqClusterReference is forbidden"))) }) It("does not allow both spec.upstreamSecret and spec.secretBackend.vault.userPath be configured", func() { @@ -74,7 +82,8 @@ var _ = Describe("schema-replication webhook", func() { SecretPath: "not-good", }, } - Expect(apierrors.IsForbidden(ignoreNilWarning(updated.ValidateUpdate(&replication)))).To(BeTrue()) + _, err := updated.ValidateUpdate(rootCtx, &replication, updated) + Expect(err).To(MatchError(ContainSubstring("do not provide both secretBackend.vault.secretPath and upstreamSecret"))) }) It("spec.upstreamSecret and spec.secretBackend.vault.userPath cannot both be not configured", func() { @@ -83,7 +92,8 @@ var _ = Describe("schema-replication webhook", func() { Vault: &VaultSpec{}, } updated.Spec.UpstreamSecret.Name = "" - Expect(apierrors.IsForbidden(ignoreNilWarning(updated.ValidateUpdate(&replication)))).To(BeTrue()) + _, err := updated.ValidateUpdate(rootCtx, &replication, updated) + Expect(err).To(MatchError(ContainSubstring("must provide either secretBackend.vault.secretPath or upstreamSecret"))) }) It("allows update on spec.secretBackend.vault.userPath", func() { @@ -94,7 +104,8 @@ var _ = Describe("schema-replication webhook", func() { }, } updated.Spec.UpstreamSecret.Name = "" - Expect(ignoreNilWarning(updated.ValidateUpdate(&replication))).To(Succeed()) + _, err := updated.ValidateUpdate(rootCtx, &replication, updated) + Expect(err).ToNot(HaveOccurred()) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { @@ -116,7 +127,8 @@ var _ = Describe("schema-replication webhook", func() { } newObj := connectionScr.DeepCopy() newObj.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "newObj-secret" - Expect(apierrors.IsForbidden(ignoreNilWarning(newObj.ValidateUpdate(&connectionScr)))).To(BeTrue()) + _, err := newObj.ValidateUpdate(rootCtx, &connectionScr, newObj) + Expect(err).To(MatchError(ContainSubstring("update on rabbitmqClusterReference is forbidden"))) }) It("allows updates on spec.upstreamSecret", func() { @@ -124,13 +136,15 @@ var _ = Describe("schema-replication webhook", func() { updated.Spec.UpstreamSecret = &corev1.LocalObjectReference{ Name: "a-different-secret", } - Expect(ignoreNilWarning(updated.ValidateUpdate(&replication))).To(Succeed()) + _, err := updated.ValidateUpdate(rootCtx, &replication, updated) + Expect(err).ToNot(HaveOccurred()) }) It("allows updates on spec.endpoints", func() { updated := replication.DeepCopy() updated.Spec.Endpoints = "abc.new-rmq:1111" - Expect(ignoreNilWarning(updated.ValidateUpdate(&replication))).To(Succeed()) + _, err := updated.ValidateUpdate(rootCtx, &replication, updated) + Expect(err).ToNot(HaveOccurred()) }) }) }) diff --git a/api/v1beta1/shovel_webhook.go b/api/v1beta1/shovel_webhook.go index 247c8b8b..a3f97bf4 100644 --- a/api/v1beta1/shovel_webhook.go +++ b/api/v1beta1/shovel_webhook.go @@ -1,6 +1,7 @@ package v1beta1 import ( + "context" "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -18,61 +19,69 @@ func (s *Shovel) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1beta1-shovel,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=shovels,versions=v1beta1,name=vshovel.kb.io,sideEffects=none,admissionReviewVersions=v1 -var _ webhook.Validator = &Shovel{} +var _ webhook.CustomValidator = &Shovel{} -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type -// either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both -func (s *Shovel) ValidateCreate() (admission.Warnings, error) { - if err := s.amqp10Validate(); err != nil { +// ValidateCreate - either rabbitmqClusterReference.name or +// rabbitmqClusterReference.connectionSecret must be provided, but not both +func (s *Shovel) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + shovel, ok := obj.(*Shovel) + if !ok { + return nil, fmt.Errorf("expected a RabbitMQ shovel but got a %T", obj) + } + if err := shovel.amqp10Validate(); err != nil { return nil, err } - return s.Spec.RabbitmqClusterReference.ValidateOnCreate(s.GroupResource(), s.Name) + + return nil, s.Spec.RabbitmqClusterReference.validate(shovel.RabbitReference()) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (s *Shovel) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldShovel, ok := old.(*Shovel) +func (s *Shovel) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + //TODO implement me + oldShovel, ok := oldObj.(*Shovel) if !ok { return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a shovel but got a %T", oldShovel)) } - if err := s.amqp10Validate(); err != nil { + newShovel, ok := newObj.(*Shovel) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a shovel but got a %T", newObj)) + } + + if err := newShovel.amqp10Validate(); err != nil { return nil, err } - detailMsg := "updates on name, vhost and rabbitmqClusterReference are all forbidden" - if s.Spec.Name != oldShovel.Spec.Name { - return nil, apierrors.NewForbidden(s.GroupResource(), s.Name, + const detailMsg = "updates on name, vhost and rabbitmqClusterReference are all forbidden" + if newShovel.Spec.Name != oldShovel.Spec.Name { + return nil, apierrors.NewForbidden(newShovel.GroupResource(), newShovel.Name, field.Forbidden(field.NewPath("spec", "name"), detailMsg)) } - if s.Spec.Vhost != oldShovel.Spec.Vhost { - return nil, apierrors.NewForbidden(s.GroupResource(), s.Name, + if newShovel.Spec.Vhost != oldShovel.Spec.Vhost { + return nil, apierrors.NewForbidden(newShovel.GroupResource(), newShovel.Name, field.Forbidden(field.NewPath("spec", "vhost"), detailMsg)) } - if !oldShovel.Spec.RabbitmqClusterReference.Matches(&s.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(s.GroupResource(), s.Name, + if !oldShovel.Spec.RabbitmqClusterReference.Matches(&newShovel.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newShovel.GroupResource(), newShovel.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), detailMsg)) } return nil, nil } -func (s *Shovel) ValidateDelete() (admission.Warnings, error) { +func (s *Shovel) ValidateDelete(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } func (s *Shovel) amqp10Validate() error { - var errorList field.ErrorList if s.Spec.SourceProtocol == "amqp10" && s.Spec.SourceAddress == "" { - errorList = append(errorList, field.Required(field.NewPath("spec", "srcAddress"), - "must specify spec.srcAddress when spec.srcProtocol is amqp10")) - return apierrors.NewInvalid(GroupVersion.WithKind("Shovel").GroupKind(), s.Name, errorList) + return field.Required(field.NewPath("spec", "srcAddress"), + "must specify spec.srcAddress when spec.srcProtocol is amqp10") } if s.Spec.DestinationProtocol == "amqp10" && s.Spec.DestinationAddress == "" { - errorList = append(errorList, field.Required(field.NewPath("spec", "destAddress"), - "must specify spec.destAddress when spec.destProtocol is amqp10")) - return apierrors.NewInvalid(GroupVersion.WithKind("Shovel").GroupKind(), s.Name, errorList) + return field.Required(field.NewPath("spec", "destAddress"), + "must specify spec.destAddress when spec.destProtocol is amqp10") } return nil } diff --git a/api/v1beta1/shovel_webhook_test.go b/api/v1beta1/shovel_webhook_test.go index 47d769b9..0c5f90fd 100644 --- a/api/v1beta1/shovel_webhook_test.go +++ b/api/v1beta1/shovel_webhook_test.go @@ -1,81 +1,88 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) var _ = Describe("shovel webhook", func() { - var shovel = Shovel{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - }, - Spec: ShovelSpec{ - Name: "test-upstream", - Vhost: "/a-vhost", - UriSecret: &corev1.LocalObjectReference{ - Name: "a-secret", + var ( + shovel = Shovel{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", }, - AckMode: "no-ack", - AddForwardHeaders: true, - DeleteAfter: "never", - DestinationAddForwardHeaders: true, - DestinationAddTimestampHeader: true, - DestinationAddress: "myQueue", - DestinationApplicationProperties: &runtime.RawExtension{Raw: []byte(`{"key": "a-property"}`)}, - DestinationExchange: "an-exchange", - DestinationExchangeKey: "a-key", - DestinationProperties: &runtime.RawExtension{Raw: []byte(`{"key": "a-property"}`)}, - DestinationProtocol: "amqp091", - DestinationPublishProperties: &runtime.RawExtension{Raw: []byte(`{"delivery_mode": 1}`)}, - DestinationMessageAnnotations: &runtime.RawExtension{Raw: []byte(`{"a-key": "an-annotation"}`)}, - DestinationQueue: "a-queue", - PrefetchCount: 10, - ReconnectDelay: 10, - SourceAddress: "myQueue", - SourceDeleteAfter: "never", - SourceExchange: "an-exchange", - SourceExchangeKey: "a-key", - SourcePrefetchCount: 10, - SourceProtocol: "amqp091", - SourceQueue: "a-queue", - SourceConsumerArgs: &runtime.RawExtension{Raw: []byte(`{"x-priority": 1}`)}, - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "a-cluster", + Spec: ShovelSpec{ + Name: "test-upstream", + Vhost: "/a-vhost", + UriSecret: &corev1.LocalObjectReference{ + Name: "a-secret", + }, + AckMode: "no-ack", + AddForwardHeaders: true, + DeleteAfter: "never", + DestinationAddForwardHeaders: true, + DestinationAddTimestampHeader: true, + DestinationAddress: "myQueue", + DestinationApplicationProperties: &runtime.RawExtension{Raw: []byte(`{"key": "a-property"}`)}, + DestinationExchange: "an-exchange", + DestinationExchangeKey: "a-key", + DestinationProperties: &runtime.RawExtension{Raw: []byte(`{"key": "a-property"}`)}, + DestinationProtocol: "amqp091", + DestinationPublishProperties: &runtime.RawExtension{Raw: []byte(`{"delivery_mode": 1}`)}, + DestinationMessageAnnotations: &runtime.RawExtension{Raw: []byte(`{"a-key": "an-annotation"}`)}, + DestinationQueue: "a-queue", + PrefetchCount: 10, + ReconnectDelay: 10, + SourceAddress: "myQueue", + SourceDeleteAfter: "never", + SourceExchange: "an-exchange", + SourceExchangeKey: "a-key", + SourcePrefetchCount: 10, + SourceProtocol: "amqp091", + SourceQueue: "a-queue", + SourceConsumerArgs: &runtime.RawExtension{Raw: []byte(`{"x-priority": 1}`)}, + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "a-cluster", + }, }, - }, - } + } + rootCtx = context.Background() + ) Context("ValidateCreate", func() { It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := shovel.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := shovel.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) It("spec.srcAddress must be set if spec.srcProtocol is amqp10", func() { notValid := shovel.DeepCopy() notValid.Spec.SourceProtocol = "amqp10" notValid.Spec.SourceAddress = "" - Expect(apierrors.IsInvalid(ignoreNilWarning(notValid.ValidateCreate()))).To(BeTrue()) + _, err := notValid.ValidateCreate(rootCtx, notValid) + Expect(err).To(MatchError(ContainSubstring("must specify spec.srcAddress when spec.srcProtocol is amqp10"))) }) It("spec.destAddress must be set if spec.destProtocol is amqp10", func() { notValid := shovel.DeepCopy() notValid.Spec.DestinationProtocol = "amqp10" notValid.Spec.DestinationAddress = "" - Expect(apierrors.IsInvalid(ignoreNilWarning(notValid.ValidateCreate()))).To(BeTrue()) + _, err := notValid.ValidateCreate(rootCtx, notValid) + Expect(err).To(MatchError(ContainSubstring("must specify spec.destAddress when spec.destProtocol is amqp10"))) }) }) @@ -83,13 +90,15 @@ var _ = Describe("shovel webhook", func() { It("does not allow updates on name", func() { newShovel := shovel.DeepCopy() newShovel.Spec.Name = "another-shovel" - Expect(apierrors.IsForbidden(ignoreNilWarning(newShovel.ValidateUpdate(&shovel)))).To(BeTrue()) + _, err := newShovel.ValidateUpdate(rootCtx, &shovel, newShovel) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on vhost", func() { newShovel := shovel.DeepCopy() newShovel.Spec.Vhost = "another-vhost" - Expect(apierrors.IsForbidden(ignoreNilWarning(newShovel.ValidateUpdate(&shovel)))).To(BeTrue()) + _, err := newShovel.ValidateUpdate(rootCtx, &shovel, newShovel) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on RabbitmqClusterReference", func() { @@ -97,21 +106,24 @@ var _ = Describe("shovel webhook", func() { newShovel.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "another-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newShovel.ValidateUpdate(&shovel)))).To(BeTrue()) + _, err := newShovel.ValidateUpdate(rootCtx, &shovel, newShovel) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("spec.srcAddress must be set if spec.srcProtocol is amqp10", func() { newShovel := shovel.DeepCopy() newShovel.Spec.SourceProtocol = "amqp10" newShovel.Spec.SourceAddress = "" - Expect(apierrors.IsInvalid(ignoreNilWarning(newShovel.ValidateUpdate(&shovel)))).To(BeTrue()) + _, err := newShovel.ValidateCreate(rootCtx, newShovel) + Expect(err).To(MatchError(ContainSubstring("must specify spec.srcAddress when spec.srcProtocol is amqp10"))) }) It("spec.destAddress must be set if spec.destProtocol is amqp10", func() { newShovel := shovel.DeepCopy() newShovel.Spec.DestinationProtocol = "amqp10" newShovel.Spec.DestinationAddress = "" - Expect(apierrors.IsInvalid(ignoreNilWarning(newShovel.ValidateUpdate(&shovel)))).To(BeTrue()) + _, err := newShovel.ValidateCreate(rootCtx, newShovel) + Expect(err).To(MatchError(ContainSubstring("must specify spec.destAddress when spec.destProtocol is amqp10"))) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { @@ -132,9 +144,10 @@ var _ = Describe("shovel webhook", func() { }, }, } - new := connectionScr.DeepCopy() - new.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" - Expect(apierrors.IsForbidden(ignoreNilWarning(new.ValidateUpdate(&connectionScr)))).To(BeTrue()) + newShovel := connectionScr.DeepCopy() + newShovel.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" + _, err := newShovel.ValidateUpdate(rootCtx, &connectionScr, newShovel) + Expect(err).To(MatchError(ContainSubstring("updates on name, vhost and rabbitmqClusterReference are all forbidden"))) }) It("allows updates on shovel configurations", func() { @@ -163,7 +176,8 @@ var _ = Describe("shovel webhook", func() { newShovel.Spec.SourceProtocol = "another-protocol" newShovel.Spec.SourceQueue = "another-queue" newShovel.Spec.SourceConsumerArgs = &runtime.RawExtension{Raw: []byte(`{"x-priority": 10}`)} - Expect(ignoreNilWarning(newShovel.ValidateUpdate(&shovel))).To(Succeed()) + _, err := newShovel.ValidateUpdate(rootCtx, &shovel, newShovel) + Expect(err).ToNot(HaveOccurred()) }) }) }) diff --git a/api/v1beta1/topicpermission_webhook.go b/api/v1beta1/topicpermission_webhook.go index 8f8066ad..36b4cb4b 100644 --- a/api/v1beta1/topicpermission_webhook.go +++ b/api/v1beta1/topicpermission_webhook.go @@ -1,6 +1,7 @@ package v1beta1 import ( + "context" "fmt" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" @@ -11,82 +12,89 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook" ) -func (r *TopicPermission) SetupWebhookWithManager(mgr ctrl.Manager) error { +func (t *TopicPermission) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). - For(r). + For(t). Complete() } //+kubebuilder:webhook:path=/validate-rabbitmq-com-v1beta1-topicpermission,mutating=false,failurePolicy=fail,sideEffects=None,groups=rabbitmq.com,resources=topicpermissions,verbs=create;update,versions=v1beta1,name=vtopicpermission.kb.io,admissionReviewVersions={v1,v1beta1} -var _ webhook.Validator = &TopicPermission{} +var _ webhook.CustomValidator = &TopicPermission{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type -func (p *TopicPermission) ValidateCreate() (admission.Warnings, error) { - var errorList field.ErrorList - if p.Spec.User == "" && p.Spec.UserReference == nil { - errorList = append(errorList, field.Required(field.NewPath("spec", "user and userReference"), - "must specify either spec.user or spec.userReference")) - return nil, apierrors.NewInvalid(GroupVersion.WithKind("Permission").GroupKind(), p.Name, errorList) +func (t *TopicPermission) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + tp, ok := obj.(*TopicPermission) + if !ok { + return nil, fmt.Errorf("expected a RabbitMQ permission but got a %T", obj) } - if p.Spec.User != "" && p.Spec.UserReference != nil { - errorList = append(errorList, field.Required(field.NewPath("spec", "user and userReference"), - "cannot specify spec.user and spec.userReference at the same time")) - return nil, apierrors.NewInvalid(GroupVersion.WithKind("Permission").GroupKind(), p.Name, errorList) + if t.Spec.User == "" && t.Spec.UserReference == nil { + return nil, field.Required(field.NewPath("spec", "user and userReference"), + "must specify either spec.user or spec.userReference") } - return p.Spec.RabbitmqClusterReference.ValidateOnCreate(p.GroupResource(), p.Name) + + if t.Spec.User != "" && t.Spec.UserReference != nil { + return nil, field.Required(field.NewPath("spec", "user and userReference"), + "cannot specify spec.user and spec.userReference at the same time") + } + return nil, t.Spec.RabbitmqClusterReference.validate(tp.RabbitReference()) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (p *TopicPermission) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldPermission, ok := old.(*TopicPermission) +func (t *TopicPermission) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldPermission, ok := oldObj.(*TopicPermission) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a permission but got a %T", oldObj)) + } + + newPermission, ok := newObj.(*TopicPermission) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a permission but got a %T", old)) + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a permission but got a %T", newObj)) } var errorList field.ErrorList - if p.Spec.User == "" && p.Spec.UserReference == nil { + if newPermission.Spec.User == "" && newPermission.Spec.UserReference == nil { errorList = append(errorList, field.Required(field.NewPath("spec", "user and userReference"), "must specify either spec.user or spec.userReference")) - return nil, apierrors.NewInvalid(GroupVersion.WithKind("TopicPermission").GroupKind(), p.Name, errorList) + return nil, apierrors.NewInvalid(GroupVersion.WithKind("TopicPermission").GroupKind(), newPermission.Name, errorList) } - if p.Spec.User != "" && p.Spec.UserReference != nil { + if newPermission.Spec.User != "" && newPermission.Spec.UserReference != nil { errorList = append(errorList, field.Required(field.NewPath("spec", "user and userReference"), "cannot specify spec.user and spec.userReference at the same time")) - return nil, apierrors.NewInvalid(GroupVersion.WithKind("TopicPermission").GroupKind(), p.Name, errorList) + return nil, apierrors.NewInvalid(GroupVersion.WithKind("TopicPermission").GroupKind(), newPermission.Name, errorList) } - detailMsg := "updates on exchange, user, userReference, vhost and rabbitmqClusterReference are all forbidden" - if p.Spec.Permissions.Exchange != oldPermission.Spec.Permissions.Exchange { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + const detailMsg = "updates on exchange, user, userReference, vhost and rabbitmqClusterReference are all forbidden" + if newPermission.Spec.Permissions.Exchange != oldPermission.Spec.Permissions.Exchange { + return nil, apierrors.NewForbidden(newPermission.GroupResource(), newPermission.Name, field.Forbidden(field.NewPath("spec", "permissions", "exchange"), detailMsg)) } - if p.Spec.User != oldPermission.Spec.User { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + if newPermission.Spec.User != oldPermission.Spec.User { + return nil, apierrors.NewForbidden(newPermission.GroupResource(), newPermission.Name, field.Forbidden(field.NewPath("spec", "user"), detailMsg)) } - if userReferenceUpdated(p.Spec.UserReference, oldPermission.Spec.UserReference) { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + if userReferenceUpdated(newPermission.Spec.UserReference, oldPermission.Spec.UserReference) { + return nil, apierrors.NewForbidden(newPermission.GroupResource(), newPermission.Name, field.Forbidden(field.NewPath("spec", "userReference"), detailMsg)) } - if p.Spec.Vhost != oldPermission.Spec.Vhost { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + if newPermission.Spec.Vhost != oldPermission.Spec.Vhost { + return nil, apierrors.NewForbidden(newPermission.GroupResource(), newPermission.Name, field.Forbidden(field.NewPath("spec", "vhost"), detailMsg)) } - if !oldPermission.Spec.RabbitmqClusterReference.Matches(&p.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(p.GroupResource(), p.Name, + if !oldPermission.Spec.RabbitmqClusterReference.Matches(&newPermission.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newPermission.GroupResource(), newPermission.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), detailMsg)) } return nil, nil } // ValidateDelete implements webhook.Validator so a webhook will be registered for the type -func (r *TopicPermission) ValidateDelete() (admission.Warnings, error) { +func (t *TopicPermission) ValidateDelete(_ context.Context, _ runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } diff --git a/api/v1beta1/topicpermission_webhook_test.go b/api/v1beta1/topicpermission_webhook_test.go index ee70d62a..82693a6c 100644 --- a/api/v1beta1/topicpermission_webhook_test.go +++ b/api/v1beta1/topicpermission_webhook_test.go @@ -1,57 +1,65 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var _ = Describe("topic permission webhook", func() { - var permission = TopicPermission{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - }, - Spec: TopicPermissionSpec{ - User: "test-user", - Vhost: "/a-vhost", - Permissions: TopicPermissionConfig{ - Exchange: "a-exchange", - Read: ".*", - Write: ".*", + var ( + permission = TopicPermission{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", }, - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "a-cluster", + Spec: TopicPermissionSpec{ + User: "test-user", + Vhost: "/a-vhost", + Permissions: TopicPermissionConfig{ + Exchange: "a-exchange", + Read: ".*", + Write: ".*", + }, + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "a-cluster", + }, }, - }, - } + } + rootCtx = context.Background() + ) Context("ValidateCreate", func() { It("does not allow user and userReference to be specified at the same time", func() { invalidPermission := permission.DeepCopy() invalidPermission.Spec.UserReference = &corev1.LocalObjectReference{Name: "invalid"} invalidPermission.Spec.User = "test-user" - Expect(apierrors.IsInvalid(ignoreNilWarning(invalidPermission.ValidateCreate()))).To(BeTrue()) + _, err := invalidPermission.ValidateCreate(rootCtx, invalidPermission) + Expect(err).To(MatchError(ContainSubstring("cannot specify spec.user and spec.userReference at the same time"))) }) + It("does not allow both user and userReference to be unset", func() { invalidPermission := permission.DeepCopy() invalidPermission.Spec.UserReference = nil invalidPermission.Spec.User = "" - Expect(apierrors.IsInvalid(ignoreNilWarning(invalidPermission.ValidateCreate()))).To(BeTrue()) + _, err := invalidPermission.ValidateCreate(rootCtx, invalidPermission) + Expect(err).To(MatchError(ContainSubstring("must specify either spec.user or spec.userReference"))) }) It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := permission.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := permission.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) }) @@ -59,7 +67,8 @@ var _ = Describe("topic permission webhook", func() { It("does not allow updates on user", func() { newPermission := permission.DeepCopy() newPermission.Spec.User = "new-user" - Expect(apierrors.IsForbidden(ignoreNilWarning(newPermission.ValidateUpdate(&permission)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("updates on exchange, user, userReference, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on userReference", func() { @@ -68,13 +77,15 @@ var _ = Describe("topic permission webhook", func() { permissionWithUserRef.Spec.UserReference = &corev1.LocalObjectReference{Name: "a-user"} newPermission := permissionWithUserRef.DeepCopy() newPermission.Spec.UserReference = &corev1.LocalObjectReference{Name: "a-new-user"} - Expect(apierrors.IsForbidden(ignoreNilWarning(newPermission.ValidateUpdate(permissionWithUserRef)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, permissionWithUserRef, newPermission) + Expect(err).To(MatchError(ContainSubstring("updates on exchange, user, userReference, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on vhost", func() { newPermission := permission.DeepCopy() newPermission.Spec.Vhost = "new-vhost" - Expect(apierrors.IsForbidden(ignoreNilWarning(newPermission.ValidateUpdate(&permission)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("updates on exchange, user, userReference, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on RabbitmqClusterReference", func() { @@ -82,63 +93,70 @@ var _ = Describe("topic permission webhook", func() { newPermission.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "new-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newPermission.ValidateUpdate(&permission)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("updates on exchange, user, userReference, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { - connectionScr := Permission{ + connectionScr := TopicPermission{ ObjectMeta: metav1.ObjectMeta{ Name: "test", }, - Spec: PermissionSpec{ + Spec: TopicPermissionSpec{ User: "test-user", Vhost: "/a-vhost", - Permissions: VhostPermissions{ - Configure: ".*", - Read: ".*", - Write: ".*", + Permissions: TopicPermissionConfig{ + Exchange: "a-exchange", + Read: ".*", + Write: ".*", }, RabbitmqClusterReference: RabbitmqClusterReference{ - ConnectionSecret: &corev1.LocalObjectReference{ - Name: "a-secret", - }, + ConnectionSecret: &corev1.LocalObjectReference{Name: "some-secret"}, }, }, } - new := connectionScr.DeepCopy() - new.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" - Expect(apierrors.IsForbidden(ignoreNilWarning(new.ValidateUpdate(&connectionScr)))).To(BeTrue()) + + newTopicPermissions := connectionScr.DeepCopy() + Expect(newTopicPermissions).ToNot(BeNil()) + newTopicPermissions.Spec.RabbitmqClusterReference.ConnectionSecret.Name = "new-secret" + _, err := newTopicPermissions.ValidateUpdate(rootCtx, &connectionScr, newTopicPermissions) + Expect(err).To(MatchError(ContainSubstring("updates on exchange, user, userReference, vhost and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on spec.permissions.exchange", func() { newPermission := permission.DeepCopy() newPermission.Spec.Permissions.Exchange = "a-different-exchange" - Expect(apierrors.IsForbidden(ignoreNilWarning(newPermission.ValidateUpdate(&permission)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("updates on exchange, user, userReference, vhost and rabbitmqClusterReference are all forbidden"))) }) It("allows updates on permission.spec.permissions.read", func() { newPermission := permission.DeepCopy() newPermission.Spec.Permissions.Read = "?" - Expect(ignoreNilWarning(newPermission.ValidateUpdate(&permission))).To(Succeed()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).ToNot(HaveOccurred()) }) It("allows updates on permission.spec.permissions.write", func() { newPermission := permission.DeepCopy() newPermission.Spec.Permissions.Write = "?" - Expect(ignoreNilWarning(newPermission.ValidateUpdate(&permission))).To(Succeed()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).ToNot(HaveOccurred()) }) It("does not allow user and userReference to be specified at the same time", func() { newPermission := permission.DeepCopy() newPermission.Spec.UserReference = &corev1.LocalObjectReference{Name: "invalid"} - Expect(apierrors.IsInvalid(ignoreNilWarning(newPermission.ValidateUpdate(&permission)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("cannot specify spec.user and spec.userReference at the same time"))) }) It("does not allow both user and userReference to be unset", func() { newPermission := permission.DeepCopy() newPermission.Spec.User = "" newPermission.Spec.UserReference = nil - Expect(apierrors.IsInvalid(ignoreNilWarning(newPermission.ValidateUpdate(&permission)))).To(BeTrue()) + _, err := newPermission.ValidateUpdate(rootCtx, &permission, newPermission) + Expect(err).To(MatchError(ContainSubstring("must specify either spec.user or spec.userReference"))) }) }) }) diff --git a/api/v1beta1/user_webhook.go b/api/v1beta1/user_webhook.go index 04315d6e..8e004f2c 100644 --- a/api/v1beta1/user_webhook.go +++ b/api/v1beta1/user_webhook.go @@ -1,6 +1,7 @@ package v1beta1 import ( + "context" "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -18,29 +19,37 @@ func (u *User) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1beta1-user,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=users,versions=v1beta1,name=vuser.kb.io,sideEffects=none,admissionReviewVersions=v1 -var _ webhook.Validator = &User{} +var _ webhook.CustomValidator = &User{} -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type -// either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both -func (u *User) ValidateCreate() (admission.Warnings, error) { - return u.Spec.RabbitmqClusterReference.ValidateOnCreate(u.GroupResource(), u.Name) +// ValidateCreate - either rabbitmqClusterReference.name or +// rabbitmqClusterReference.connectionSecret must be provided but not both +func (u *User) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + user, ok := obj.(*User) + if !ok { + return nil, fmt.Errorf("expected a RabbitMQ user but got a %T", obj) + } + return nil, u.Spec.RabbitmqClusterReference.validate(user.RabbitReference()) } // ValidateUpdate returns error type 'forbidden' for updates on rabbitmqClusterReference -// user.spec.tags can be updated -func (u *User) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldUser, ok := old.(*User) +func (u *User) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldUser, ok := oldObj.(*User) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a user but got a %T", oldObj)) + } + + newUser, ok := newObj.(*User) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a user but got a %T", old)) + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a user but got a %T", newObj)) } - if !oldUser.Spec.RabbitmqClusterReference.Matches(&u.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(u.GroupResource(), u.Name, + if !oldUser.Spec.RabbitmqClusterReference.Matches(&newUser.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newUser.GroupResource(), newUser.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), "update on rabbitmqClusterReference is forbidden")) } return nil, nil } -func (u *User) ValidateDelete() (admission.Warnings, error) { +func (u *User) ValidateDelete(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } diff --git a/api/v1beta1/user_webhook_test.go b/api/v1beta1/user_webhook_test.go index f67c1b87..c7194ab7 100644 --- a/api/v1beta1/user_webhook_test.go +++ b/api/v1beta1/user_webhook_test.go @@ -1,38 +1,43 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var _ = Describe("user webhook", func() { - var user = User{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - }, - Spec: UserSpec{ - Tags: []UserTag{"policymaker"}, - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "a-cluster", + var ( + user = User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", }, - }, - } + Spec: UserSpec{ + Tags: []UserTag{"policymaker"}, + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "a-cluster", + }, + }, + } + rootCtx = context.Background() + ) Context("ValidateCreate", func() { It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := user.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := user.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) }) @@ -42,7 +47,8 @@ var _ = Describe("user webhook", func() { newUser.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "newUser-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newUser.ValidateUpdate(&user)))).To(BeTrue()) + _, err := newUser.ValidateUpdate(rootCtx, &user, newUser) + Expect(err).To(MatchError(ContainSubstring("update on rabbitmqClusterReference is forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { @@ -59,16 +65,18 @@ var _ = Describe("user webhook", func() { }, }, } - new := connectionScr.DeepCopy() - new.Spec.RabbitmqClusterReference.Name = "a-name" - new.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(new.ValidateUpdate(&connectionScr)))).To(BeTrue()) + newUser := connectionScr.DeepCopy() + newUser.Spec.RabbitmqClusterReference.Name = "a-name" + newUser.Spec.RabbitmqClusterReference.ConnectionSecret = nil + _, err := newUser.ValidateUpdate(rootCtx, &connectionScr, newUser) + Expect(err).To(MatchError(ContainSubstring("update on rabbitmqClusterReference is forbidden"))) }) It("allows update on tags", func() { newUser := user.DeepCopy() newUser.Spec.Tags = []UserTag{"monitoring"} - Expect(ignoreNilWarning(newUser.ValidateUpdate(&user))).To(Succeed()) + _, err := newUser.ValidateUpdate(rootCtx, &user, newUser) + Expect(err).ToNot(HaveOccurred()) }) }) }) diff --git a/api/v1beta1/vhost_webhook.go b/api/v1beta1/vhost_webhook.go index 67509a0c..4c591dcb 100644 --- a/api/v1beta1/vhost_webhook.go +++ b/api/v1beta1/vhost_webhook.go @@ -1,6 +1,7 @@ package v1beta1 import ( + "context" "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -10,44 +11,54 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) -func (r *Vhost) SetupWebhookWithManager(mgr ctrl.Manager) error { +func (v *Vhost) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). - For(r). + For(v). Complete() } // +kubebuilder:webhook:verbs=create;update,path=/validate-rabbitmq-com-v1beta1-vhost,mutating=false,failurePolicy=fail,groups=rabbitmq.com,resources=vhosts,versions=v1beta1,name=vvhost.kb.io,sideEffects=none,admissionReviewVersions=v1 -var _ webhook.Validator = &Vhost{} +var _ webhook.CustomValidator = &Vhost{} -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type -// either rabbitmqClusterReference.name or rabbitmqClusterReference.connectionSecret must be provided but not both -func (v *Vhost) ValidateCreate() (admission.Warnings, error) { - return v.Spec.RabbitmqClusterReference.ValidateOnCreate(v.GroupResource(), v.Name) +// ValidateCreate +// +// Either rabbitmqClusterReference.name or +// rabbitmqClusterReference.connectionSecret must be provided but not both +func (v *Vhost) ValidateCreate(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { + vhost, ok := obj.(*Vhost) + if !ok { + return nil, fmt.Errorf("expected a RabbitMQ vhost but got a %T", obj) + } + return nil, v.Spec.RabbitmqClusterReference.validate(vhost.RabbitReference()) } // ValidateUpdate returns error type 'forbidden' for updates on vhost name and rabbitmqClusterReference -// vhost.spec.tracing can be updated -func (v *Vhost) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldVhost, ok := old.(*Vhost) +func (v *Vhost) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { + oldVhost, ok := oldObj.(*Vhost) + if !ok { + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a vhost but got a %T", oldObj)) + } + + newVhost, ok := newObj.(*Vhost) if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a vhost but got a %T", old)) + return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a vhost but got a %T", newObj)) } - detailMsg := "updates on name and rabbitmqClusterReference are all forbidden" - if v.Spec.Name != oldVhost.Spec.Name { - return nil, apierrors.NewForbidden(v.GroupResource(), v.Name, + const detailMsg = "updates on name and rabbitmqClusterReference are all forbidden" + if newVhost.Spec.Name != oldVhost.Spec.Name { + return nil, apierrors.NewForbidden(newVhost.GroupResource(), newVhost.Name, field.Forbidden(field.NewPath("spec", "name"), detailMsg)) } - if !oldVhost.Spec.RabbitmqClusterReference.Matches(&v.Spec.RabbitmqClusterReference) { - return nil, apierrors.NewForbidden(v.GroupResource(), v.Name, + if !oldVhost.Spec.RabbitmqClusterReference.Matches(&newVhost.Spec.RabbitmqClusterReference) { + return nil, apierrors.NewForbidden(newVhost.GroupResource(), newVhost.Name, field.Forbidden(field.NewPath("spec", "rabbitmqClusterReference"), detailMsg)) } return nil, nil } -func (v *Vhost) ValidateDelete() (admission.Warnings, error) { +func (v *Vhost) ValidateDelete(_ context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { return nil, nil } diff --git a/api/v1beta1/vhost_webhook_test.go b/api/v1beta1/vhost_webhook_test.go index 2ff6db64..3390ab3e 100644 --- a/api/v1beta1/vhost_webhook_test.go +++ b/api/v1beta1/vhost_webhook_test.go @@ -1,41 +1,46 @@ package v1beta1 import ( + "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var _ = Describe("vhost webhook", func() { - var vhost = Vhost{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-vhost", - }, - Spec: VhostSpec{ - Name: "test", - Tracing: false, - DefaultQueueType: "classic", - RabbitmqClusterReference: RabbitmqClusterReference{ - Name: "a-cluster", + var ( + vhost = Vhost{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-vhost", }, - }, - } + Spec: VhostSpec{ + Name: "test", + Tracing: false, + DefaultQueueType: "classic", + RabbitmqClusterReference: RabbitmqClusterReference{ + Name: "a-cluster", + }, + }, + } + rootCtx = context.Background() + ) Context("ValidateCreate", func() { It("does not allow both spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret be configured", func() { notAllowed := vhost.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = &corev1.LocalObjectReference{Name: "some-secret"} - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: do not provide both name and connectionSecret"))) }) It("spec.rabbitmqClusterReference.name and spec.rabbitmqClusterReference.connectionSecret cannot both be empty", func() { notAllowed := vhost.DeepCopy() notAllowed.Spec.RabbitmqClusterReference.Name = "" notAllowed.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(notAllowed.ValidateCreate()))).To(BeTrue()) + _, err := notAllowed.ValidateCreate(rootCtx, notAllowed) + Expect(err).To(MatchError(ContainSubstring("invalid RabbitmqClusterReference: must provide either name or connectionSecret"))) }) }) @@ -43,7 +48,8 @@ var _ = Describe("vhost webhook", func() { It("does not allow updates on vhost name", func() { newVhost := vhost.DeepCopy() newVhost.Spec.Name = "new-name" - Expect(apierrors.IsForbidden(ignoreNilWarning(newVhost.ValidateUpdate(&vhost)))).To(BeTrue()) + _, err := newVhost.ValidateUpdate(rootCtx, &vhost, newVhost) + Expect(err).To(MatchError(ContainSubstring("updates on name and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on RabbitmqClusterReference", func() { @@ -51,7 +57,8 @@ var _ = Describe("vhost webhook", func() { newVhost.Spec.RabbitmqClusterReference = RabbitmqClusterReference{ Name: "new-cluster", } - Expect(apierrors.IsForbidden(ignoreNilWarning(newVhost.ValidateUpdate(&vhost)))).To(BeTrue()) + _, err := newVhost.ValidateUpdate(rootCtx, &vhost, newVhost) + Expect(err).To(MatchError(ContainSubstring("updates on name and rabbitmqClusterReference are all forbidden"))) }) It("does not allow updates on rabbitmqClusterReference.connectionSecret", func() { @@ -68,28 +75,32 @@ var _ = Describe("vhost webhook", func() { }, }, } - new := connectionScr.DeepCopy() - new.Spec.RabbitmqClusterReference.Name = "a-name" - new.Spec.RabbitmqClusterReference.ConnectionSecret = nil - Expect(apierrors.IsForbidden(ignoreNilWarning(new.ValidateUpdate(&connectionScr)))).To(BeTrue()) + newVhost := connectionScr.DeepCopy() + newVhost.Spec.RabbitmqClusterReference.Name = "a-name" + newVhost.Spec.RabbitmqClusterReference.ConnectionSecret = nil + _, err := newVhost.ValidateUpdate(rootCtx, &connectionScr, newVhost) + Expect(err).To(MatchError(ContainSubstring("updates on name and rabbitmqClusterReference are all forbidden"))) }) It("allows updates on vhost.spec.tracing", func() { newVhost := vhost.DeepCopy() newVhost.Spec.Tracing = true - Expect(ignoreNilWarning(newVhost.ValidateUpdate(&vhost))).To(Succeed()) + _, err := newVhost.ValidateUpdate(rootCtx, &vhost, newVhost) + Expect(err).ToNot(HaveOccurred()) }) It("allows updates on vhost.spec.tags", func() { newVhost := vhost.DeepCopy() newVhost.Spec.Tags = []string{"new-tag"} - Expect(ignoreNilWarning(newVhost.ValidateUpdate(&vhost))).To(Succeed()) + _, err := newVhost.ValidateUpdate(rootCtx, &vhost, newVhost) + Expect(err).ToNot(HaveOccurred()) }) It("allows updates on vhost.spec.defaultQueueType", func() { newVhost := vhost.DeepCopy() newVhost.Spec.DefaultQueueType = "quorum" - Expect(ignoreNilWarning(newVhost.ValidateUpdate(&vhost))).To(Succeed()) + _, err := newVhost.ValidateUpdate(rootCtx, &vhost, newVhost) + Expect(err).ToNot(HaveOccurred()) }) }) }) diff --git a/go.sum b/go.sum index 03632287..dff450f9 100644 --- a/go.sum +++ b/go.sum @@ -64,13 +64,17 @@ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+ github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= +github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/goccy/go-yaml v1.11.2 h1:joq77SxuyIs9zzxEjgyLBugMQ9NEgTWxXfz2wVqwAaQ= @@ -170,11 +174,13 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -288,14 +294,17 @@ github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv github.com/rabbitmq/cluster-operator/v2 v2.6.0 h1:pr42elurQgi4DVmLTI1cOh8VZRNkfFKZK9+FgQuM/8w= github.com/rabbitmq/cluster-operator/v2 v2.6.0/go.mod h1:Zryxg5YgbPUFcLSCcKpf10il8kIRAK5HloNo6khhdis= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8= +github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= github.com/sclevine/yj v0.0.0-20200815061347-554173e71934 h1:HQgRgQK9d7cDKkRTS9zlvd6agG3yg7E4Q1ChdHgPs6Y= github.com/sclevine/yj v0.0.0-20200815061347-554173e71934/go.mod h1:AeGluipFgaqcTzUkgIazjEUPD+xbrS9qmLUE1TO1xpo= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= @@ -319,6 +328,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/weppos/publicsuffix-go v0.13.1-0.20210123135404-5fd73613514e/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b h1:FsyNrX12e5BkplJq7wKOLk0+C6LZ+KGXvuEcKUYm5ss= github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= @@ -339,6 +349,7 @@ go.starlark.net v0.0.0-20230912135651-745481cf39ed h1:kNt8RXSIU6IRBO9MP3m+6q3Wpy go.starlark.net v0.0.0-20230912135651-745481cf39ed/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= @@ -426,6 +437,7 @@ golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/internal/managedresource/managedresource_builder.go b/internal/managedresource/managedresource_builder.go index 7f9cd380..94cd9e25 100644 --- a/internal/managedresource/managedresource_builder.go +++ b/internal/managedresource/managedresource_builder.go @@ -22,6 +22,6 @@ type ResourceBuilder interface { ResourceType() string } -func (builder Builder) GenerateChildResourceName(suffix string) string { +func (builder *Builder) GenerateChildResourceName(suffix string) string { return builder.ObjectOwner.GetName() + suffix } From 4f7cca71bfc8a15bf87a8f1a4cd75c4716406e57 Mon Sep 17 00:00:00 2001 From: Aitor Perez Cedres Date: Thu, 1 Feb 2024 19:32:48 +0000 Subject: [PATCH 3/4] Bump deps Signed-off-by: Aitor Perez Cedres --- go.mod | 57 ++++++++++---------- go.sum | 167 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 114 insertions(+), 110 deletions(-) diff --git a/go.mod b/go.mod index 8cf6da79..e4abd31a 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/michaelklishin/rabbit-hole/v2 v2.16.0 github.com/onsi/ginkgo/v2 v2.15.0 github.com/onsi/gomega v1.31.1 - github.com/rabbitmq/cluster-operator/v2 v2.6.0 + github.com/rabbitmq/cluster-operator/v2 v2.7.0 github.com/sclevine/yj v0.0.0-20200815061347-554173e71934 gopkg.in/ini.v1 v1.67.0 k8s.io/api v0.29.1 @@ -22,8 +22,8 @@ require ( k8s.io/client-go v0.29.1 k8s.io/code-generator v0.29.1 k8s.io/klog/v2 v2.120.1 - k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e - k8s.io/utils v0.0.0-20230726121419-3b25d923346b + k8s.io/kube-openapi v0.0.0-20240126223410-2919ad4fcfec + k8s.io/utils v0.0.0-20240102154912-e7106e64919e sigs.k8s.io/controller-runtime v0.17.0 sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20231121004636-2154ffbc22e2 sigs.k8s.io/controller-tools v0.14.0 @@ -35,52 +35,51 @@ require ( github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/sprig v2.22.0+incompatible // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cenkalti/backoff/v3 v3.0.0 // indirect + github.com/cenkalti/backoff/v3 v3.2.2 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch v5.7.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.8.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.2 // indirect + github.com/evanphx/json-patch v5.9.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/fatih/color v1.16.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-errors/errors v1.5.0 // indirect github.com/go-jose/go-jose/v3 v3.0.1 // indirect github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.20.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/jsonpointer v0.20.2 // indirect + github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/swag v0.22.9 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gobuffalo/flect v1.0.2 // indirect github.com/goccy/go-yaml v1.11.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/certificate-transparency-go v1.1.4 // indirect + github.com/google/certificate-transparency-go v1.1.7 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 // indirect + github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-hclog v1.0.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-retryablehttp v0.6.6 // indirect + github.com/hashicorp/go-retryablehttp v0.7.5 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect - github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect - github.com/hashicorp/go-sockaddr v1.0.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.6 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.3.3 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jmoiron/sqlx v1.3.3 // indirect + github.com/jmoiron/sqlx v1.3.5 // 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/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -89,43 +88,43 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pelletier/go-toml v1.9.4 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/common v0.46.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/spf13/afero v1.6.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b // indirect + github.com/weppos/publicsuffix-go v0.30.2-0.20230730094716-a20f9abcc222 // indirect github.com/xlab/treeprint v1.2.0 // indirect - github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc // indirect - github.com/zmap/zlint/v3 v3.1.0 // indirect + github.com/zmap/zcrypto v0.0.0-20231219022726-a1f61fb1661c // indirect + github.com/zmap/zlint/v3 v3.6.0 // indirect go.starlark.net v0.0.0-20230912135651-745481cf39ed // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect + golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.20.0 // indirect - golang.org/x/oauth2 v0.12.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/sys v0.16.0 // indirect golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/evanphx/json-patch.v5 v5.6.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.29.0 // indirect - k8s.io/component-base v0.29.0 // indirect + k8s.io/apiextensions-apiserver v0.29.1 // indirect + k8s.io/component-base v0.29.1 // indirect k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.16.0 // indirect diff --git a/go.sum b/go.sum index dff450f9..a17df0ae 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,5 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= @@ -6,12 +7,12 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= -github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M= +github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -21,21 +22,21 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cfssl v1.6.4 h1:NMOvfrEjFfC63K3SGXgAnFdsgkmiq4kATme5BfcqrO8= github.com/cloudflare/cfssl v1.6.4/go.mod h1:8b3CQMxfWPAeom3zBnGJ6sd+G1NkL5TXqmDXacb+1J0= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/elastic/crd-ref-docs v0.0.10 h1:FAc9oCxxY4+rMCLSLtTGrEaPyuxmp3LNlQ+dZfG9Ujc= github.com/elastic/crd-ref-docs v0.0.10/go.mod h1:zha4djxzWirfx+c4fl/Kmk9Rc7Fv7XBoOi9CL9kne+M= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.11.2 h1:1onLa9DcsMYO9P+CXaL0dStDqQ2EHHXLiz+BtnqkLAU= +github.com/emicklei/go-restful/v3 v3.11.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= -github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= -github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= +github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= @@ -55,21 +56,19 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= -github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= +github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= +github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= +github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= @@ -99,8 +98,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/certificate-transparency-go v1.1.4 h1:hCyXHDbtqlr/lMXU0D4WgbalXL0Zk4dSWWMbPV8VrqY= -github.com/google/certificate-transparency-go v1.1.4/go.mod h1:D6lvbfwckhNrbM9WVl1EVeMOyzC19mpIjMOI4nxBHtQ= +github.com/google/certificate-transparency-go v1.1.7 h1:IASD+NtgSTJLPdzkthwvAG1ZVbF2WtFg4IvoA68XGSw= +github.com/google/certificate-transparency-go v1.1.7/go.mod h1:FSSBo8fyMVgqptbfF6j5p/XNdgQftAhSmXcIxV9iphE= 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.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -109,18 +108,21 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v50 v50.2.0/go.mod h1:VBY8FB6yPIjrtKhozXv4FQupxKLS6H4m6xFZlT43q8Q= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.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-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ= -github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -128,26 +130,23 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v1.0.0 h1:bkKf0BeBXcSYa7f5Fyi9gMuQ8gNsxeiNpZjR6VxNZeo= github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM= -github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= +github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 h1:iBt4Ew4XEGLfh6/bPk4rSYmuZJGizr6/x/AEizP0CQc= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8/go.mod h1:aiJI+PIApBRQG7FZTEBx5GiiX+HbOHilUdNxUZi4eV0= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= -github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= -github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-sockaddr v1.0.6 h1:RSG8rKU28VTUTvEKghe5gIhIQpv8evvNpnDEyqO4u9I= +github.com/hashicorp/go-sockaddr v1.0.6/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/vault/api v1.11.0 h1:AChWByeHf4/P9sX3Y1B7vFsQhZO2BgQiCMQ2SA1P1UY= @@ -160,8 +159,8 @@ github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jmoiron/sqlx v1.3.3 h1:j82X0bf7oQ27XeqxicSZsTU5suPwKElg3oyxNn43iTk= -github.com/jmoiron/sqlx v1.3.3/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -184,30 +183,23 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/maxbrunsfeld/counterfeiter/v6 v6.8.1 h1:NicmruxkeqHjDv03SfSxqmaLuisddudfP3h5wdXFbhM= github.com/maxbrunsfeld/counterfeiter/v6 v6.8.1/go.mod h1:eyp4DdUJAKkr9tvxR3jWhw2mDK7CWABMG5r9uyaKC7I= github.com/michaelklishin/rabbit-hole/v2 v2.16.0 h1:RvTPW3DnmyR7R1XTbET0ILRneU1Ou3vzIVj4YHBIE/g= github.com/michaelklishin/rabbit-hole/v2 v2.16.0/go.mod h1:wnHAhXYVncuXKdF/3mdywRE4vzBgn4k07Z+HjdNGMpM= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -220,6 +212,7 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= +github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= 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/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -271,42 +264,41 @@ github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= -github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= +github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rabbitmq/amqp091-go v1.9.0 h1:qrQtyzB4H8BQgEuJwhmVQqVHB9O4+MNDJCCAcpc3Aoo= github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc= -github.com/rabbitmq/cluster-operator/v2 v2.6.0 h1:pr42elurQgi4DVmLTI1cOh8VZRNkfFKZK9+FgQuM/8w= -github.com/rabbitmq/cluster-operator/v2 v2.6.0/go.mod h1:Zryxg5YgbPUFcLSCcKpf10il8kIRAK5HloNo6khhdis= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rabbitmq/cluster-operator/v2 v2.7.0 h1:DqyMucZrzD31hkAnznEiAf1W+KWC0sRdu6bDTtLp7LY= +github.com/rabbitmq/cluster-operator/v2 v2.7.0/go.mod h1:i4J22uZ+nGAPDLtORnF/yfdIL2tQp+bUN+RfY6qj20U= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8= github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= github.com/sclevine/yj v0.0.0-20200815061347-554173e71934 h1:HQgRgQK9d7cDKkRTS9zlvd6agG3yg7E4Q1ChdHgPs6Y= github.com/sclevine/yj v0.0.0-20200815061347-554173e71934/go.mod h1:AeGluipFgaqcTzUkgIazjEUPD+xbrS9qmLUE1TO1xpo= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= @@ -329,9 +321,9 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/weppos/publicsuffix-go v0.13.1-0.20210123135404-5fd73613514e/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= -github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b h1:FsyNrX12e5BkplJq7wKOLk0+C6LZ+KGXvuEcKUYm5ss= -github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= +github.com/weppos/publicsuffix-go v0.13.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= +github.com/weppos/publicsuffix-go v0.30.2-0.20230730094716-a20f9abcc222 h1:h2JizvZl9aIj6za9S5AyrkU+OzIS4CetQthH/ejO+lg= +github.com/weppos/publicsuffix-go v0.30.2-0.20230730094716-a20f9abcc222/go.mod h1:s41lQh6dIsDWIC1OWh7ChWJXLH0zkJ9KHZVqA7vHyuQ= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -339,12 +331,16 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= +github.com/zmap/rc2 v0.0.0-20190804163417-abaa70531248/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= -github.com/zmap/zcrypto v0.0.0-20210123152837-9cf5beac6d91/go.mod h1:R/deQh6+tSWlgI9tb4jNmXxn8nSCabl5ZQsBX9//I/E= -github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc h1:zkGwegkOW709y0oiAraH/3D8njopUR/pARHv4tZZ6pw= -github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc/go.mod h1:FM4U1E3NzlNMRnSUTU3P1UdukWhYGifqEsjk9fn7BCk= -github.com/zmap/zlint/v3 v3.1.0 h1:WjVytZo79m/L1+/Mlphl09WBob6YTGljN5IGWZFpAv0= -github.com/zmap/zlint/v3 v3.1.0/go.mod h1:L7t8s3sEKkb0A2BxGy1IWrxt1ZATa1R4QfJZaQOD3zU= +github.com/zmap/zcertificate v0.0.1/go.mod h1:q0dlN54Jm4NVSSuzisusQY0hqDWvu92C+TWveAxiVWk= +github.com/zmap/zcrypto v0.0.0-20201128221613-3719af1573cf/go.mod h1:aPM7r+JOkfL+9qSB4KbYjtoEzJqUK50EXkkJabeNJDQ= +github.com/zmap/zcrypto v0.0.0-20201211161100-e54a5822fb7e/go.mod h1:aPM7r+JOkfL+9qSB4KbYjtoEzJqUK50EXkkJabeNJDQ= +github.com/zmap/zcrypto v0.0.0-20231219022726-a1f61fb1661c h1:U1b4THKcgOpJ+kILupuznNwPiURtwVW3e9alJvji9+s= +github.com/zmap/zcrypto v0.0.0-20231219022726-a1f61fb1661c/go.mod h1:GSDpFDD4TASObxvfZfvpZZ3OWHIUHMlhVWlkOe4ewVk= +github.com/zmap/zlint/v3 v3.0.0/go.mod h1:paGwFySdHIBEMJ61YjoqT4h7Ge+fdYG4sUQhnTb1lJ8= +github.com/zmap/zlint/v3 v3.6.0 h1:vTEaDRtYN0d/1Ax60T+ypvbLQUHwHxbvYRnUMVr35ug= +github.com/zmap/zlint/v3 v3.6.0/go.mod h1:NVgiIWssgzp0bNl8P4Gz94NHV2ep/4Jyj9V69uTmZyg= go.starlark.net v0.0.0-20230912135651-745481cf39ed h1:kNt8RXSIU6IRBO9MP3m+6q3WpyBHQQXqSktcyVKDPOQ= go.starlark.net v0.0.0-20230912135651-745481cf39ed/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= @@ -361,17 +357,20 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U 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/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= +golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -396,11 +395,11 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/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-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -423,8 +422,9 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= -golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -438,7 +438,6 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -458,6 +457,7 @@ golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -479,6 +479,7 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -496,6 +497,7 @@ golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -504,6 +506,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -515,8 +518,8 @@ golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -550,8 +553,9 @@ gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= @@ -570,8 +574,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -600,25 +605,25 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw= k8s.io/api v0.29.1/go.mod h1:7Kl10vBRUXhnQQI8YR/R327zXC8eJ7887/+Ybta+RoQ= -k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= -k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= +k8s.io/apiextensions-apiserver v0.29.1 h1:S9xOtyk9M3Sk1tIpQMu9wXHm5O2MX6Y1kIpPMimZBZw= +k8s.io/apiextensions-apiserver v0.29.1/go.mod h1:zZECpujY5yTW58co8V2EQR4BD6A9pktVgHhvc0uLfeU= k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc= k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= k8s.io/client-go v0.29.1 h1:19B/+2NGEwnFLzt0uB5kNJnfTsbV8w6TgQRz9l7ti7A= k8s.io/client-go v0.29.1/go.mod h1:TDG/psL9hdet0TI9mGyHJSgRkW3H9JZk2dNEUS7bRks= k8s.io/code-generator v0.29.1 h1:8ba8BdtSmAVHgAMpzThb/fuyQeTRtN7NtN7VjMcDLew= k8s.io/code-generator v0.29.1/go.mod h1:FwFi3C9jCrmbPjekhaCYcYG1n07CYiW1+PAPCockaos= -k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= -k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= +k8s.io/component-base v0.29.1 h1:MUimqJPCRnnHsskTTjKD+IC1EHBbRCVyi37IoFBrkYw= +k8s.io/component-base v0.29.1/go.mod h1:fP9GFjxYrLERq1GcWWZAE3bqbNcDKDytn2srWuHTtKc= k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks= k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e h1:snPmy96t93RredGRjKfMFt+gvxuVAncqSAyBveJtr4Q= -k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20240126223410-2919ad4fcfec h1:iGTel2aR8vCZdxJDgmbeY0zrlXy9Qcvyw4R2sB4HLrA= +k8s.io/kube-openapi v0.0.0-20240126223410-2919ad4fcfec/go.mod h1:Pa1PvrP7ACSkuX6I7KYomY6cmMA0Tx86waBhDUgoKPw= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/controller-runtime v0.17.0 h1:fjJQf8Ukya+VjogLO6/bNX9HE6Y2xpsO5+fyS26ur/s= sigs.k8s.io/controller-runtime v0.17.0/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20231121004636-2154ffbc22e2 h1:S1i08nqcuJsCyUBR0jvmKnMLHEbPb74yrVfUoSeuGew= From 9fe0aec7c68573b2005e0a7f6085f0803bea5f42 Mon Sep 17 00:00:00 2001 From: Aitor Perez Cedres Date: Tue, 6 Feb 2024 16:21:40 +0000 Subject: [PATCH 4/4] Register webhooks using the new API Signed-off-by: Aitor Perez Cedres --- Makefile | 2 +- api/v1beta1/binding_webhook.go | 1 + api/v1beta1/exchange_webhook.go | 1 + api/v1beta1/federation_webhook.go | 1 + api/v1beta1/operatorpolicy_webhook.go | 1 + api/v1beta1/permission_webhook.go | 1 + api/v1beta1/policy_webhook.go | 1 + api/v1beta1/queue_webhook.go | 1 + api/v1beta1/schemareplication_webhook.go | 1 + api/v1beta1/shovel_webhook.go | 2 +- api/v1beta1/topicpermission_webhook.go | 7 ++++--- api/v1beta1/user_webhook.go | 1 + api/v1beta1/vhost_webhook.go | 1 + system_tests/binding_system_test.go | 2 +- 14 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 815f5bad..f1e863ff 100644 --- a/Makefile +++ b/Makefile @@ -73,7 +73,7 @@ just-integration-tests: $(KUBEBUILDER_ASSETS) vet local-tests: unit-tests integration-tests ## Run all local tests (unit & integration) system-tests: ## run end-to-end tests against Kubernetes cluster defined in ~/.kube/config. Expects cluster operator and messaging topology operator to be installed in the cluster - NAMESPACE="rabbitmq-system" ginkgo --randomize-all -r system_tests/ + NAMESPACE="rabbitmq-system" ginkgo --randomize-all -r $(GINKGO_EXTRA) system_tests/ # Build manager binary manager: generate fmt vet vuln diff --git a/api/v1beta1/binding_webhook.go b/api/v1beta1/binding_webhook.go index 4673a1f4..09f13547 100644 --- a/api/v1beta1/binding_webhook.go +++ b/api/v1beta1/binding_webhook.go @@ -14,6 +14,7 @@ import ( func (b *Binding) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(b). For(b). Complete() } diff --git a/api/v1beta1/exchange_webhook.go b/api/v1beta1/exchange_webhook.go index ff7ee11b..94a82aab 100644 --- a/api/v1beta1/exchange_webhook.go +++ b/api/v1beta1/exchange_webhook.go @@ -13,6 +13,7 @@ import ( func (e *Exchange) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(e). For(e). Complete() } diff --git a/api/v1beta1/federation_webhook.go b/api/v1beta1/federation_webhook.go index e3dad89a..b9af8b87 100644 --- a/api/v1beta1/federation_webhook.go +++ b/api/v1beta1/federation_webhook.go @@ -13,6 +13,7 @@ import ( func (f *Federation) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(f). For(f). Complete() } diff --git a/api/v1beta1/operatorpolicy_webhook.go b/api/v1beta1/operatorpolicy_webhook.go index 944ccd70..f6d77a61 100644 --- a/api/v1beta1/operatorpolicy_webhook.go +++ b/api/v1beta1/operatorpolicy_webhook.go @@ -13,6 +13,7 @@ import ( func (p *OperatorPolicy) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(p). For(p). Complete() } diff --git a/api/v1beta1/permission_webhook.go b/api/v1beta1/permission_webhook.go index 1b9a3bac..2b63675e 100644 --- a/api/v1beta1/permission_webhook.go +++ b/api/v1beta1/permission_webhook.go @@ -14,6 +14,7 @@ import ( func (p *Permission) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(p). For(p). Complete() } diff --git a/api/v1beta1/policy_webhook.go b/api/v1beta1/policy_webhook.go index 3d4c2cd6..642e9bc1 100644 --- a/api/v1beta1/policy_webhook.go +++ b/api/v1beta1/policy_webhook.go @@ -13,6 +13,7 @@ import ( func (p *Policy) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(p). For(p). Complete() } diff --git a/api/v1beta1/queue_webhook.go b/api/v1beta1/queue_webhook.go index 93b22090..23ac25e5 100644 --- a/api/v1beta1/queue_webhook.go +++ b/api/v1beta1/queue_webhook.go @@ -13,6 +13,7 @@ import ( func (q *Queue) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(q). For(q). Complete() } diff --git a/api/v1beta1/schemareplication_webhook.go b/api/v1beta1/schemareplication_webhook.go index f38220de..ca30cb84 100644 --- a/api/v1beta1/schemareplication_webhook.go +++ b/api/v1beta1/schemareplication_webhook.go @@ -13,6 +13,7 @@ import ( func (s *SchemaReplication) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(s). For(s). Complete() } diff --git a/api/v1beta1/shovel_webhook.go b/api/v1beta1/shovel_webhook.go index a3f97bf4..6ae39e35 100644 --- a/api/v1beta1/shovel_webhook.go +++ b/api/v1beta1/shovel_webhook.go @@ -13,6 +13,7 @@ import ( func (s *Shovel) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(s). For(s). Complete() } @@ -37,7 +38,6 @@ func (s *Shovel) ValidateCreate(_ context.Context, obj runtime.Object) (warnings // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type func (s *Shovel) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { - //TODO implement me oldShovel, ok := oldObj.(*Shovel) if !ok { return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a shovel but got a %T", oldShovel)) diff --git a/api/v1beta1/topicpermission_webhook.go b/api/v1beta1/topicpermission_webhook.go index 36b4cb4b..dab427ee 100644 --- a/api/v1beta1/topicpermission_webhook.go +++ b/api/v1beta1/topicpermission_webhook.go @@ -14,6 +14,7 @@ import ( func (t *TopicPermission) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(t). For(t). Complete() } @@ -29,16 +30,16 @@ func (t *TopicPermission) ValidateCreate(_ context.Context, obj runtime.Object) return nil, fmt.Errorf("expected a RabbitMQ permission but got a %T", obj) } - if t.Spec.User == "" && t.Spec.UserReference == nil { + if tp.Spec.User == "" && tp.Spec.UserReference == nil { return nil, field.Required(field.NewPath("spec", "user and userReference"), "must specify either spec.user or spec.userReference") } - if t.Spec.User != "" && t.Spec.UserReference != nil { + if tp.Spec.User != "" && tp.Spec.UserReference != nil { return nil, field.Required(field.NewPath("spec", "user and userReference"), "cannot specify spec.user and spec.userReference at the same time") } - return nil, t.Spec.RabbitmqClusterReference.validate(tp.RabbitReference()) + return nil, tp.Spec.RabbitmqClusterReference.validate(tp.RabbitReference()) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type diff --git a/api/v1beta1/user_webhook.go b/api/v1beta1/user_webhook.go index 8e004f2c..1c2d90c4 100644 --- a/api/v1beta1/user_webhook.go +++ b/api/v1beta1/user_webhook.go @@ -13,6 +13,7 @@ import ( func (u *User) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(u). For(u). Complete() } diff --git a/api/v1beta1/vhost_webhook.go b/api/v1beta1/vhost_webhook.go index 4c591dcb..6ec48b2e 100644 --- a/api/v1beta1/vhost_webhook.go +++ b/api/v1beta1/vhost_webhook.go @@ -13,6 +13,7 @@ import ( func (v *Vhost) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). + WithValidator(v). For(v). Complete() } diff --git a/system_tests/binding_system_test.go b/system_tests/binding_system_test.go index f8671c28..bae11e04 100644 --- a/system_tests/binding_system_test.go +++ b/system_tests/binding_system_test.go @@ -131,7 +131,7 @@ var _ = Describe("Binding", func() { updateBinding := topology.Binding{} Expect(k8sClient.Get(ctx, types.NamespacedName{Name: binding.Name, Namespace: binding.Namespace}, &updateBinding)).To(Succeed()) updatedBinding.Spec.RoutingKey = "new-key" - Expect(k8sClient.Update(ctx, &updatedBinding).Error()).To(ContainSubstring("invalid: spec.routingKey: Invalid value: \"new-key\": routingKey cannot be updated")) + Expect(k8sClient.Update(ctx, &updatedBinding).Error()).To(ContainSubstring("spec.routingKey: Invalid value: \"new-key\": routingKey cannot be updated")) By("deleting binding from rabbitmq server") Expect(k8sClient.Delete(ctx, binding)).To(Succeed())