mirror of https://github.com/kubernetes/kops.git
Update controller-runtime to v0.9.0-beta.0
This commit is contained in:
parent
071ea676d6
commit
39fe0175aa
2
go.mod
2
go.mod
|
|
@ -96,6 +96,6 @@ require (
|
|||
k8s.io/mount-utils v0.21.0
|
||||
k8s.io/utils v0.0.0-20210305010621-2afb4311ab10
|
||||
rsc.io/letsencrypt v0.0.3 // indirect
|
||||
sigs.k8s.io/controller-runtime v0.9.0-alpha.1
|
||||
sigs.k8s.io/controller-runtime v0.9.0-beta.0
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -1805,8 +1805,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
|||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/controller-runtime v0.6.2/go.mod h1:vhcq/rlnENJ09SIRp3EveTaZ0yqH526hjf9iJdbUJ/E=
|
||||
sigs.k8s.io/controller-runtime v0.9.0-alpha.1 h1:yIYTxDHQfcrYWO1hjZvHhjkGY1fYFo1k07FzlTono4E=
|
||||
sigs.k8s.io/controller-runtime v0.9.0-alpha.1/go.mod h1:BARxVvgj+8Ihw9modUvYh7/OJmjxuBtLK8P36jdf7rY=
|
||||
sigs.k8s.io/controller-runtime v0.9.0-beta.0 h1:GMy39zuf8ywrQyNuc24wR1mdiJCSGJnxaaqakZldaug=
|
||||
sigs.k8s.io/controller-runtime v0.9.0-beta.0/go.mod h1:ufPDuvefw2Y1KnBgHQrLdOjueYlj+XJV2AszbT+WTxs=
|
||||
sigs.k8s.io/controller-tools v0.2.9-0.20200414181213-645d44dca7c0/go.mod h1:YKE/iHvcKITCljdnlqHYe+kAt7ZldvtAwUzQff0k1T0=
|
||||
sigs.k8s.io/kustomize/api v0.8.5 h1:bfCXGXDAbFbb/Jv5AhMj2BB8a5VAJuuQ5/KU69WtDjQ=
|
||||
sigs.k8s.io/kustomize/api v0.8.5/go.mod h1:M377apnKT5ZHJS++6H4rQoCHmWtt6qTpp3mbe7p6OLY=
|
||||
|
|
|
|||
|
|
@ -2209,7 +2209,7 @@ sigs.k8s.io/boskos v0.0.0-20200710214748-f5935686c7fc/go.mod h1:ZO5RV+VxJS9mb6Dv
|
|||
sigs.k8s.io/controller-runtime v0.5.0/go.mod h1:REiJzC7Y00U+2YkMbT8wxgrsX5USpXKGhb2sCtAXiT8=
|
||||
sigs.k8s.io/controller-runtime v0.5.4/go.mod h1:JZUwSMVbxDupo0lTJSSFP5pimEyxGynROImSsqIOx1A=
|
||||
sigs.k8s.io/controller-runtime v0.6.2/go.mod h1:vhcq/rlnENJ09SIRp3EveTaZ0yqH526hjf9iJdbUJ/E=
|
||||
sigs.k8s.io/controller-runtime v0.9.0-alpha.1/go.mod h1:BARxVvgj+8Ihw9modUvYh7/OJmjxuBtLK8P36jdf7rY=
|
||||
sigs.k8s.io/controller-runtime v0.9.0-beta.0/go.mod h1:ufPDuvefw2Y1KnBgHQrLdOjueYlj+XJV2AszbT+WTxs=
|
||||
sigs.k8s.io/controller-tools v0.2.9-0.20200414181213-645d44dca7c0/go.mod h1:YKE/iHvcKITCljdnlqHYe+kAt7ZldvtAwUzQff0k1T0=
|
||||
sigs.k8s.io/kubetest2 v0.0.0-20210309183806-9230b4e73d8d h1:dhWiqYfVQS+jhaoGsdbw7rZJjtuN4gzgcoHPgXptttI=
|
||||
sigs.k8s.io/kubetest2 v0.0.0-20210309183806-9230b4e73d8d/go.mod h1:miwZW11FA2Bvclxo4WqIVY+gHTR5B927inXdfxJYoAA=
|
||||
|
|
|
|||
|
|
@ -998,7 +998,7 @@ k8s.io/api/scheduling/v1beta1
|
|||
k8s.io/api/storage/v1
|
||||
k8s.io/api/storage/v1alpha1
|
||||
k8s.io/api/storage/v1beta1
|
||||
# k8s.io/apiextensions-apiserver v0.21.0-beta.1 => k8s.io/apiextensions-apiserver v0.21.0
|
||||
# k8s.io/apiextensions-apiserver v0.21.0 => k8s.io/apiextensions-apiserver v0.21.0
|
||||
k8s.io/apiextensions-apiserver/pkg/apis/apiextensions
|
||||
k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1
|
||||
k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1
|
||||
|
|
@ -1422,7 +1422,7 @@ k8s.io/utils/pointer
|
|||
k8s.io/utils/trace
|
||||
# rsc.io/letsencrypt v0.0.3
|
||||
## explicit
|
||||
# sigs.k8s.io/controller-runtime v0.9.0-alpha.1
|
||||
# sigs.k8s.io/controller-runtime v0.9.0-beta.0
|
||||
## explicit
|
||||
sigs.k8s.io/controller-runtime
|
||||
sigs.k8s.io/controller-runtime/pkg/builder
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
SHELL:=/usr/bin/env bash
|
||||
.DEFAULT_GOAL:=help
|
||||
|
||||
export WHAT ?= ./...
|
||||
|
||||
# Use GOPROXY environment variable if set
|
||||
GOPROXY := $(shell go env GOPROXY)
|
||||
ifeq ($(GOPROXY),)
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ see how it can be used.
|
|||
|
||||
Documentation:
|
||||
|
||||
- [Package overview](https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg)
|
||||
- [Basic controller using builder](https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/builder#example-Builder)
|
||||
- [Creating a manager](https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/manager#example-New)
|
||||
- [Creating a controller](https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/controller#example-New)
|
||||
- [Package overview](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg)
|
||||
- [Basic controller using builder](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/builder#example-Builder)
|
||||
- [Creating a manager](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/manager#example-New)
|
||||
- [Creating a controller](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller#example-New)
|
||||
- [Examples](https://github.com/kubernetes-sigs/controller-runtime/blob/master/examples)
|
||||
- [Designs](https://github.com/kubernetes-sigs/controller-runtime/blob/master/designs)
|
||||
|
||||
|
|
@ -63,4 +63,3 @@ Before starting any work, please either comment on an existing issue, or file a
|
|||
## Code of conduct
|
||||
|
||||
Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md).
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ require (
|
|||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
|
||||
gomodules.xyz/jsonpatch/v2 v2.1.0
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
k8s.io/api v0.21.0-beta.1
|
||||
k8s.io/apiextensions-apiserver v0.21.0-beta.1
|
||||
k8s.io/apimachinery v0.21.0-beta.1
|
||||
k8s.io/client-go v0.21.0-beta.1
|
||||
k8s.io/component-base v0.21.0-beta.1
|
||||
k8s.io/api v0.21.0
|
||||
k8s.io/apiextensions-apiserver v0.21.0
|
||||
k8s.io/apimachinery v0.21.0
|
||||
k8s.io/client-go v0.21.0
|
||||
k8s.io/component-base v0.21.0
|
||||
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11/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=
|
||||
|
|
@ -305,7 +306,7 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
|
|||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
|
@ -415,6 +416,7 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
|
|||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
|
|
@ -608,6 +610,7 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -781,8 +784,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
@ -791,24 +794,24 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.21.0-beta.1 h1:nIQCL8N0a0AncD6Xs/QPiDbw466AGsPs1K9CG0ZMcTY=
|
||||
k8s.io/api v0.21.0-beta.1/go.mod h1:8A+GKfJYDnFlmsIqnwi7z2l5+GwI3fbIdAkPu3xiZKA=
|
||||
k8s.io/apiextensions-apiserver v0.21.0-beta.1 h1:qUvWURtH6TZCabcYEGKVydU4f17qso00ZtSPodbQdEo=
|
||||
k8s.io/apiextensions-apiserver v0.21.0-beta.1/go.mod h1:vluMqsJ5+hPgM9UtBhkFSGrfD86KUac9yeKVqpGBZz0=
|
||||
k8s.io/apimachinery v0.21.0-beta.1 h1:PFLBa8viYJOvtkOEiyrzzcZSzBHEuu4wwIxzED0utCw=
|
||||
k8s.io/apimachinery v0.21.0-beta.1/go.mod h1:ZaN7d/yx5I8h2mk8Nu08sdLigsmkt4flkTxCTc9LElI=
|
||||
k8s.io/apiserver v0.21.0-beta.1/go.mod h1:nl/H4DPS1abtRhCj8bhosbyU9XOgnMt0QFK3fAFEhSE=
|
||||
k8s.io/client-go v0.21.0-beta.1 h1:gIO2RPWzchI9DnHn1hz0pObztWh7RDVcIUCSKzbxb/g=
|
||||
k8s.io/client-go v0.21.0-beta.1/go.mod h1:SsWZEBajlozcXLnUS7OD47n9MtuzduVt02GMQO2/DIA=
|
||||
k8s.io/code-generator v0.21.0-beta.1/go.mod h1:IpCUojpiKp25KNB3/UbEeElznqpQUMvhAOUoC7AbISY=
|
||||
k8s.io/component-base v0.21.0-beta.1 h1:1p2rRyBgoXuCD0rZrG07jXCfkvSnHo0aGCoNCbyhQhY=
|
||||
k8s.io/component-base v0.21.0-beta.1/go.mod h1:WPMZyV0sNk3ruzA8cWt1EO2KWAnLDK2docEC14JWbTM=
|
||||
k8s.io/api v0.21.0 h1:gu5iGF4V6tfVCQ/R+8Hc0h7H1JuEhzyEi9S4R5LM8+Y=
|
||||
k8s.io/api v0.21.0/go.mod h1:+YbrhBBGgsxbF6o6Kj4KJPJnBmAKuXDeS3E18bgHNVU=
|
||||
k8s.io/apiextensions-apiserver v0.21.0 h1:Nd4uBuweg6ImzbxkC1W7xUNZcCV/8Vt10iTdTIVF3hw=
|
||||
k8s.io/apiextensions-apiserver v0.21.0/go.mod h1:gsQGNtGkc/YoDG9loKI0V+oLZM4ljRPjc/sql5tmvzc=
|
||||
k8s.io/apimachinery v0.21.0 h1:3Fx+41if+IRavNcKOz09FwEXDBG6ORh6iMsTSelhkMA=
|
||||
k8s.io/apimachinery v0.21.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
|
||||
k8s.io/apiserver v0.21.0/go.mod h1:w2YSn4/WIwYuxG5zJmcqtRdtqgW/J2JRgFAqps3bBpg=
|
||||
k8s.io/client-go v0.21.0 h1:n0zzzJsAQmJngpC0IhgFcApZyoGXPrDIAD601HD09ag=
|
||||
k8s.io/client-go v0.21.0/go.mod h1:nNBytTF9qPFDEhoqgEPaarobC8QPae13bElIVHzIglA=
|
||||
k8s.io/code-generator v0.21.0/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q=
|
||||
k8s.io/component-base v0.21.0 h1:tLLGp4BBjQaCpS/KiuWh7m2xqvAdsxLm4ATxHSe5Zpg=
|
||||
k8s.io/component-base v0.21.0/go.mod h1:qvtjz6X0USWXbgmbfXR+Agik4RZ3jv2Bgr5QnZzdPYw=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.5.0 h1:8mOnjf1RmUPW6KRqQCfYSZq/K20Unmp3IhuZUhxl8KI=
|
||||
k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts=
|
||||
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0=
|
||||
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
|
|
@ -819,8 +822,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
|||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.3 h1:4oyYo8NREp49LBBhKxEqCulFjg26rawYKrnCmg+Sr6c=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
|
|
|
|||
|
|
@ -164,13 +164,13 @@ func (blder *Builder) Named(name string) *Builder {
|
|||
return blder
|
||||
}
|
||||
|
||||
// Complete builds the Application ControllerManagedBy.
|
||||
// Complete builds the Application Controller.
|
||||
func (blder *Builder) Complete(r reconcile.Reconciler) error {
|
||||
_, err := blder.Build(r)
|
||||
return err
|
||||
}
|
||||
|
||||
// Build builds the Application ControllerManagedBy and returns the Controller it created.
|
||||
// Build builds the Application Controller and returns the Controller it created.
|
||||
func (blder *Builder) Build(r reconcile.Reconciler) (controller.Controller, error) {
|
||||
if r == nil {
|
||||
return nil, fmt.Errorf("must provide a non-nil Reconciler")
|
||||
|
|
|
|||
|
|
@ -86,6 +86,9 @@ type Informer interface {
|
|||
HasSynced() bool
|
||||
}
|
||||
|
||||
// SelectorsByObject associate a client.Object's GVK to a field/label selector
|
||||
type SelectorsByObject map[client.Object]internal.Selector
|
||||
|
||||
// Options are the optional arguments for creating a new InformersMap object
|
||||
type Options struct {
|
||||
// Scheme is the scheme to use for mapping objects to GroupVersionKinds
|
||||
|
|
@ -103,6 +106,13 @@ type Options struct {
|
|||
// Namespace restricts the cache's ListWatch to the desired namespace
|
||||
// Default watches all namespaces
|
||||
Namespace string
|
||||
|
||||
// SelectorsByObject restricts the cache's ListWatch to the desired
|
||||
// fields per GVK at the specified object, the map's value must implement
|
||||
// Selector [1] using for example a Set [2]
|
||||
// [1] https://pkg.go.dev/k8s.io/apimachinery/pkg/fields#Selector
|
||||
// [2] https://pkg.go.dev/k8s.io/apimachinery/pkg/fields#Set
|
||||
SelectorsByObject SelectorsByObject
|
||||
}
|
||||
|
||||
var defaultResyncTime = 10 * time.Hour
|
||||
|
|
@ -113,10 +123,38 @@ func New(config *rest.Config, opts Options) (Cache, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
im := internal.NewInformersMap(config, opts.Scheme, opts.Mapper, *opts.Resync, opts.Namespace)
|
||||
selectorsByGVK, err := convertToSelectorsByGVK(opts.SelectorsByObject, opts.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
im := internal.NewInformersMap(config, opts.Scheme, opts.Mapper, *opts.Resync, opts.Namespace, selectorsByGVK)
|
||||
return &informerCache{InformersMap: im}, nil
|
||||
}
|
||||
|
||||
// BuilderWithOptions returns a Cache constructor that will build the a cache
|
||||
// honoring the options argument, this is useful to specify options like
|
||||
// SelectorsByObject
|
||||
// WARNING: if SelectorsByObject is specified. filtered out resources are not
|
||||
// returned.
|
||||
func BuilderWithOptions(options Options) NewCacheFunc {
|
||||
return func(config *rest.Config, opts Options) (Cache, error) {
|
||||
if opts.Scheme == nil {
|
||||
opts.Scheme = options.Scheme
|
||||
}
|
||||
if opts.Mapper == nil {
|
||||
opts.Mapper = options.Mapper
|
||||
}
|
||||
if opts.Resync == nil {
|
||||
opts.Resync = options.Resync
|
||||
}
|
||||
if opts.Namespace == "" {
|
||||
opts.Namespace = options.Namespace
|
||||
}
|
||||
opts.SelectorsByObject = options.SelectorsByObject
|
||||
return New(config, opts)
|
||||
}
|
||||
}
|
||||
|
||||
func defaultOpts(config *rest.Config, opts Options) (Options, error) {
|
||||
// Use the default Kubernetes Scheme if unset
|
||||
if opts.Scheme == nil {
|
||||
|
|
@ -139,3 +177,15 @@ func defaultOpts(config *rest.Config, opts Options) (Options, error) {
|
|||
}
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func convertToSelectorsByGVK(selectorsByObject SelectorsByObject, scheme *runtime.Scheme) (internal.SelectorsByGVK, error) {
|
||||
selectorsByGVK := internal.SelectorsByGVK{}
|
||||
for object, selector := range selectorsByObject {
|
||||
gvk, err := apiutil.GVKForObject(object, scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selectorsByGVK[gvk] = selector
|
||||
}
|
||||
return selectorsByGVK, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ go_library(
|
|||
"cache_reader.go",
|
||||
"deleg_map.go",
|
||||
"informers_map.go",
|
||||
"metadata_infomer_wrapper.go",
|
||||
"selector.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal",
|
||||
importpath = "sigs.k8s.io/controller-runtime/pkg/cache/internal",
|
||||
|
|
|
|||
|
|
@ -49,12 +49,14 @@ func NewInformersMap(config *rest.Config,
|
|||
scheme *runtime.Scheme,
|
||||
mapper meta.RESTMapper,
|
||||
resync time.Duration,
|
||||
namespace string) *InformersMap {
|
||||
namespace string,
|
||||
selectors SelectorsByGVK,
|
||||
) *InformersMap {
|
||||
|
||||
return &InformersMap{
|
||||
structured: newStructuredInformersMap(config, scheme, mapper, resync, namespace),
|
||||
unstructured: newUnstructuredInformersMap(config, scheme, mapper, resync, namespace),
|
||||
metadata: newMetadataInformersMap(config, scheme, mapper, resync, namespace),
|
||||
structured: newStructuredInformersMap(config, scheme, mapper, resync, namespace, selectors),
|
||||
unstructured: newUnstructuredInformersMap(config, scheme, mapper, resync, namespace, selectors),
|
||||
metadata: newMetadataInformersMap(config, scheme, mapper, resync, namespace, selectors),
|
||||
|
||||
Scheme: scheme,
|
||||
}
|
||||
|
|
@ -105,16 +107,19 @@ func (m *InformersMap) Get(ctx context.Context, gvk schema.GroupVersionKind, obj
|
|||
}
|
||||
|
||||
// newStructuredInformersMap creates a new InformersMap for structured objects.
|
||||
func newStructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration, namespace string) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, createStructuredListWatch)
|
||||
func newStructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration,
|
||||
namespace string, selectors SelectorsByGVK) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, createStructuredListWatch)
|
||||
}
|
||||
|
||||
// newUnstructuredInformersMap creates a new InformersMap for unstructured objects.
|
||||
func newUnstructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration, namespace string) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, createUnstructuredListWatch)
|
||||
func newUnstructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration,
|
||||
namespace string, selectors SelectorsByGVK) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, createUnstructuredListWatch)
|
||||
}
|
||||
|
||||
// newMetadataInformersMap creates a new InformersMap for metadata-only objects.
|
||||
func newMetadataInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration, namespace string) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, createMetadataListWatch)
|
||||
func newMetadataInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration,
|
||||
namespace string, selectors SelectorsByGVK) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, createMetadataListWatch)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import (
|
|||
"k8s.io/client-go/metadata"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
)
|
||||
|
||||
|
|
@ -48,6 +47,7 @@ func newSpecificInformersMap(config *rest.Config,
|
|||
mapper meta.RESTMapper,
|
||||
resync time.Duration,
|
||||
namespace string,
|
||||
selectors SelectorsByGVK,
|
||||
createListWatcher createListWatcherFunc) *specificInformersMap {
|
||||
ip := &specificInformersMap{
|
||||
config: config,
|
||||
|
|
@ -60,6 +60,7 @@ func newSpecificInformersMap(config *rest.Config,
|
|||
startWait: make(chan struct{}),
|
||||
createListWatcher: createListWatcher,
|
||||
namespace: namespace,
|
||||
selectors: selectors,
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
|
@ -120,6 +121,10 @@ type specificInformersMap struct {
|
|||
// namespace is the namespace that all ListWatches are restricted to
|
||||
// default or empty string means all namespaces
|
||||
namespace string
|
||||
|
||||
// selectors are the label or field selectors that will be added to the
|
||||
// ListWatch ListOptions.
|
||||
selectors SelectorsByGVK
|
||||
}
|
||||
|
||||
// Start calls Run on each of the informers and sets started to true. Blocks on the context.
|
||||
|
|
@ -216,6 +221,13 @@ func (ip *specificInformersMap) addInformerToMap(gvk schema.GroupVersionKind, ob
|
|||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
switch obj.(type) {
|
||||
case *metav1.PartialObjectMetadata, *metav1.PartialObjectMetadataList:
|
||||
ni = metadataSharedIndexInformerPreserveGVK(gvk, ni)
|
||||
default:
|
||||
}
|
||||
|
||||
i := &MapEntry{
|
||||
Informer: ni,
|
||||
Reader: CacheReader{indexer: ni.GetIndexer(), groupVersionKind: gvk, scopeName: rm.Scope.Name()},
|
||||
|
|
@ -256,6 +268,7 @@ func createStructuredListWatch(gvk schema.GroupVersionKind, ip *specificInformer
|
|||
// Create a new ListWatch for the obj
|
||||
return &cache.ListWatch{
|
||||
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
res := listObj.DeepCopyObject()
|
||||
isNamespaceScoped := ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot
|
||||
err := client.Get().NamespaceIfScoped(ip.namespace, isNamespaceScoped).Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec).Do(ctx).Into(res)
|
||||
|
|
@ -263,6 +276,7 @@ func createStructuredListWatch(gvk schema.GroupVersionKind, ip *specificInformer
|
|||
},
|
||||
// Setup the watch function
|
||||
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
// Watch needs to be set to true separately
|
||||
opts.Watch = true
|
||||
isNamespaceScoped := ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot
|
||||
|
|
@ -278,7 +292,12 @@ func createUnstructuredListWatch(gvk schema.GroupVersionKind, ip *specificInform
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dynamicClient, err := dynamic.NewForConfig(ip.config)
|
||||
|
||||
// If the rest configuration has a negotiated serializer passed in,
|
||||
// we should remove it and use the one that the dynamic client sets for us.
|
||||
cfg := rest.CopyConfig(ip.config)
|
||||
cfg.NegotiatedSerializer = nil
|
||||
dynamicClient, err := dynamic.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -289,6 +308,7 @@ func createUnstructuredListWatch(gvk schema.GroupVersionKind, ip *specificInform
|
|||
// Create a new ListWatch for the obj
|
||||
return &cache.ListWatch{
|
||||
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
return dynamicClient.Resource(mapping.Resource).Namespace(ip.namespace).List(ctx, opts)
|
||||
}
|
||||
|
|
@ -296,6 +316,7 @@ func createUnstructuredListWatch(gvk schema.GroupVersionKind, ip *specificInform
|
|||
},
|
||||
// Setup the watch function
|
||||
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
// Watch needs to be set to true separately
|
||||
opts.Watch = true
|
||||
if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
|
|
@ -314,8 +335,13 @@ func createMetadataListWatch(gvk schema.GroupVersionKind, ip *specificInformersM
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Always clear the negotiated serializer and use the one
|
||||
// set from the metadata client.
|
||||
cfg := rest.CopyConfig(ip.config)
|
||||
cfg.NegotiatedSerializer = nil
|
||||
|
||||
// grab the metadata client
|
||||
client, err := metadata.NewForConfig(ip.config)
|
||||
client, err := metadata.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -327,6 +353,7 @@ func createMetadataListWatch(gvk schema.GroupVersionKind, ip *specificInformersM
|
|||
// create the relevant listwatch
|
||||
return &cache.ListWatch{
|
||||
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
return client.Resource(mapping.Resource).Namespace(ip.namespace).List(ctx, opts)
|
||||
}
|
||||
|
|
@ -334,6 +361,7 @@ func createMetadataListWatch(gvk schema.GroupVersionKind, ip *specificInformersM
|
|||
},
|
||||
// Setup the watch function
|
||||
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
// Watch needs to be set to true separately
|
||||
opts.Watch = true
|
||||
if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
|
|
|
|||
71
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/metadata_infomer_wrapper.go
generated
vendored
Normal file
71
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/metadata_infomer_wrapper.go
generated
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
func metadataSharedIndexInformerPreserveGVK(gvk schema.GroupVersionKind, si cache.SharedIndexInformer) cache.SharedIndexInformer {
|
||||
return &sharedInformerWrapper{
|
||||
gvk: gvk,
|
||||
SharedIndexInformer: si,
|
||||
}
|
||||
}
|
||||
|
||||
type sharedInformerWrapper struct {
|
||||
gvk schema.GroupVersionKind
|
||||
cache.SharedIndexInformer
|
||||
}
|
||||
|
||||
func (s *sharedInformerWrapper) AddEventHandler(handler cache.ResourceEventHandler) {
|
||||
s.SharedIndexInformer.AddEventHandler(&handlerPreserveGVK{s.gvk, handler})
|
||||
}
|
||||
|
||||
func (s *sharedInformerWrapper) AddEventHandlerWithResyncPeriod(handler cache.ResourceEventHandler, resyncPeriod time.Duration) {
|
||||
s.SharedIndexInformer.AddEventHandlerWithResyncPeriod(&handlerPreserveGVK{s.gvk, handler}, resyncPeriod)
|
||||
}
|
||||
|
||||
type handlerPreserveGVK struct {
|
||||
gvk schema.GroupVersionKind
|
||||
cache.ResourceEventHandler
|
||||
}
|
||||
|
||||
func (h *handlerPreserveGVK) resetGroupVersionKind(obj interface{}) {
|
||||
if v, ok := obj.(schema.ObjectKind); ok {
|
||||
v.SetGroupVersionKind(h.gvk)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handlerPreserveGVK) OnAdd(obj interface{}) {
|
||||
h.resetGroupVersionKind(obj)
|
||||
h.ResourceEventHandler.OnAdd(obj)
|
||||
}
|
||||
|
||||
func (h *handlerPreserveGVK) OnUpdate(oldObj, newObj interface{}) {
|
||||
h.resetGroupVersionKind(oldObj)
|
||||
h.resetGroupVersionKind(newObj)
|
||||
h.ResourceEventHandler.OnUpdate(oldObj, newObj)
|
||||
}
|
||||
|
||||
func (h *handlerPreserveGVK) OnDelete(obj interface{}) {
|
||||
h.resetGroupVersionKind(obj)
|
||||
h.ResourceEventHandler.OnDelete(obj)
|
||||
}
|
||||
27
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go
generated
vendored
Normal file
27
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// SelectorsByGVK associate a GroupVersionKind to a field/label selector
|
||||
type SelectorsByGVK map[schema.GroupVersionKind]Selector
|
||||
|
||||
// Selector specify the label/field selector to fill in ListOptions
|
||||
type Selector struct {
|
||||
Label labels.Selector
|
||||
Field fields.Selector
|
||||
}
|
||||
|
||||
// ApplyToList fill in ListOptions LabelSelector and FieldSelector if needed
|
||||
func (s Selector) ApplyToList(listOpts *metav1.ListOptions) {
|
||||
if s.Label != nil {
|
||||
listOpts.LabelSelector = s.Label.String()
|
||||
}
|
||||
if s.Field != nil {
|
||||
listOpts.FieldSelector = s.Field.String()
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ go_library(
|
|||
"split.go",
|
||||
"typed_client.go",
|
||||
"unstructured_client.go",
|
||||
"watch.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/sigs.k8s.io/controller-runtime/pkg/client",
|
||||
importpath = "sigs.k8s.io/controller-runtime/pkg/client",
|
||||
|
|
@ -37,9 +38,12 @@ go_library(
|
|||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||
"//vendor/k8s.io/client-go/metadata:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil:go_default_library",
|
||||
"//vendor/sigs.k8s.io/controller-runtime/pkg/log:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -118,15 +118,24 @@ func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersi
|
|||
// with the given GroupVersionKind. The REST client will be configured to use the negotiated serializer from
|
||||
// baseConfig, if set, otherwise a default serializer will be set.
|
||||
func RESTClientForGVK(gvk schema.GroupVersionKind, isUnstructured bool, baseConfig *rest.Config, codecs serializer.CodecFactory) (rest.Interface, error) {
|
||||
cfg := createRestConfig(gvk, isUnstructured, baseConfig)
|
||||
if cfg.NegotiatedSerializer == nil {
|
||||
cfg.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: codecs}
|
||||
}
|
||||
return rest.RESTClientFor(cfg)
|
||||
return rest.RESTClientFor(createRestConfig(gvk, isUnstructured, baseConfig, codecs))
|
||||
}
|
||||
|
||||
// serializerWithDecodedGVK is a CodecFactory that overrides the DecoderToVersion of a WithoutConversionCodecFactory
|
||||
// in order to avoid clearing the GVK from the decoded object.
|
||||
//
|
||||
// See https://github.com/kubernetes/kubernetes/issues/80609.
|
||||
type serializerWithDecodedGVK struct {
|
||||
serializer.WithoutConversionCodecFactory
|
||||
}
|
||||
|
||||
// DecoderToVersion returns an decoder that does not do conversion.
|
||||
func (f serializerWithDecodedGVK) DecoderToVersion(serializer runtime.Decoder, _ runtime.GroupVersioner) runtime.Decoder {
|
||||
return serializer
|
||||
}
|
||||
|
||||
//createRestConfig copies the base config and updates needed fields for a new rest config
|
||||
func createRestConfig(gvk schema.GroupVersionKind, isUnstructured bool, baseConfig *rest.Config) *rest.Config {
|
||||
func createRestConfig(gvk schema.GroupVersionKind, isUnstructured bool, baseConfig *rest.Config, codecs serializer.CodecFactory) *rest.Config {
|
||||
gv := gvk.GroupVersion()
|
||||
|
||||
cfg := rest.CopyConfig(baseConfig)
|
||||
|
|
@ -147,5 +156,16 @@ func createRestConfig(gvk schema.GroupVersionKind, isUnstructured bool, baseConf
|
|||
}
|
||||
protobufSchemeLock.RUnlock()
|
||||
}
|
||||
|
||||
if cfg.NegotiatedSerializer == nil {
|
||||
if isUnstructured {
|
||||
// If the object is unstructured, we need to preserve the GVK information.
|
||||
// Use our own custom serializer.
|
||||
cfg.NegotiatedSerializer = serializerWithDecodedGVK{serializer.WithoutConversionCodecFactory{CodecFactory: codecs}}
|
||||
} else {
|
||||
cfg.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: codecs}
|
||||
}
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package client
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -31,8 +32,23 @@ import (
|
|||
"k8s.io/client-go/rest"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
// WarningHandlerOptions are options for configuring a
|
||||
// warning handler for the client which is responsible
|
||||
// for surfacing API Server warnings.
|
||||
type WarningHandlerOptions struct {
|
||||
// SuppressWarnings decides if the warnings from the
|
||||
// API server are suppressed or surfaced in the client.
|
||||
SuppressWarnings bool
|
||||
// AllowDuplicateLogs does not deduplicate the to-be
|
||||
// logged surfaced warnings messages. See
|
||||
// log.WarningHandlerOptions for considerations
|
||||
// regarding deuplication
|
||||
AllowDuplicateLogs bool
|
||||
}
|
||||
|
||||
// Options are creation options for a Client
|
||||
type Options struct {
|
||||
// Scheme, if provided, will be used to map go structs to GroupVersionKinds
|
||||
|
|
@ -40,6 +56,10 @@ type Options struct {
|
|||
|
||||
// Mapper, if provided, will be used to map GroupVersionKinds to Resources
|
||||
Mapper meta.RESTMapper
|
||||
|
||||
// Opts is used to configure the warning handler responsible for
|
||||
// surfacing and handling warnings messages sent by the API server.
|
||||
Opts WarningHandlerOptions
|
||||
}
|
||||
|
||||
// New returns a new Client using the provided config and Options.
|
||||
|
|
@ -53,10 +73,31 @@ type Options struct {
|
|||
// case of unstructured types, the group, version, and kind will be extracted
|
||||
// from the corresponding fields on the object.
|
||||
func New(config *rest.Config, options Options) (Client, error) {
|
||||
return newClient(config, options)
|
||||
}
|
||||
|
||||
func newClient(config *rest.Config, options Options) (*client, error) {
|
||||
if config == nil {
|
||||
return nil, fmt.Errorf("must provide non-nil rest.Config to client.New")
|
||||
}
|
||||
|
||||
if !options.Opts.SuppressWarnings {
|
||||
// surface warnings
|
||||
logger := log.Log.WithName("KubeAPIWarningLogger")
|
||||
// Set a WarningHandler, the default WarningHandler
|
||||
// is log.KubeAPIWarningLogger with deduplication enabled.
|
||||
// See log.KubeAPIWarningLoggerOptions for considerations
|
||||
// regarding deduplication.
|
||||
rest.SetDefaultWarningHandler(
|
||||
log.NewKubeAPIWarningLogger(
|
||||
logger,
|
||||
log.KubeAPIWarningLoggerOptions{
|
||||
Deduplicate: !options.Opts.AllowDuplicateLogs,
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// Init a scheme if none provided
|
||||
if options.Scheme == nil {
|
||||
options.Scheme = scheme.Scheme
|
||||
|
|
@ -119,7 +160,6 @@ type client struct {
|
|||
}
|
||||
|
||||
// resetGroupVersionKind is a helper function to restore and preserve GroupVersionKind on an object.
|
||||
// TODO(vincepri): Remove this function and its calls once controller-runtime dependencies are upgraded to 1.16?
|
||||
func (c *client) resetGroupVersionKind(obj runtime.Object, gvk schema.GroupVersionKind) {
|
||||
if gvk != schema.EmptyObjectKind.GroupVersionKind() {
|
||||
if v, ok := obj.(schema.ObjectKind); ok {
|
||||
|
|
@ -206,6 +246,8 @@ func (c *client) Get(ctx context.Context, key ObjectKey, obj Object) error {
|
|||
case *unstructured.Unstructured:
|
||||
return c.unstructuredClient.Get(ctx, key, obj)
|
||||
case *metav1.PartialObjectMetadata:
|
||||
// Metadata only object should always preserve the GVK coming in from the caller.
|
||||
defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
|
||||
return c.metadataClient.Get(ctx, key, obj)
|
||||
default:
|
||||
return c.typedClient.Get(ctx, key, obj)
|
||||
|
|
@ -214,11 +256,33 @@ func (c *client) Get(ctx context.Context, key ObjectKey, obj Object) error {
|
|||
|
||||
// List implements client.Client
|
||||
func (c *client) List(ctx context.Context, obj ObjectList, opts ...ListOption) error {
|
||||
switch obj.(type) {
|
||||
switch x := obj.(type) {
|
||||
case *unstructured.UnstructuredList:
|
||||
return c.unstructuredClient.List(ctx, obj, opts...)
|
||||
case *metav1.PartialObjectMetadataList:
|
||||
return c.metadataClient.List(ctx, obj, opts...)
|
||||
// Metadata only object should always preserve the GVK.
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
defer c.resetGroupVersionKind(obj, gvk)
|
||||
|
||||
// Call the list client.
|
||||
if err := c.metadataClient.List(ctx, obj, opts...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Restore the GVK for each item in the list.
|
||||
itemGVK := schema.GroupVersionKind{
|
||||
Group: gvk.Group,
|
||||
Version: gvk.Version,
|
||||
// TODO: this is producing unsafe guesses that don't actually work,
|
||||
// but it matches ~99% of the cases out there.
|
||||
Kind: strings.TrimSuffix(gvk.Kind, "List"),
|
||||
}
|
||||
for i := range x.Items {
|
||||
item := &x.Items[i]
|
||||
item.SetGroupVersionKind(itemGVK)
|
||||
}
|
||||
|
||||
return nil
|
||||
default:
|
||||
return c.typedClient.List(ctx, obj, opts...)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,6 @@ type resourceMeta struct {
|
|||
// isNamespaced returns true if the type is namespaced
|
||||
func (r *resourceMeta) isNamespaced() bool {
|
||||
return r.mapping.Scope.Name() != meta.RESTScopeNameRoot
|
||||
|
||||
}
|
||||
|
||||
// resource returns the resource name of the type
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
)
|
||||
|
||||
// ObjectKey identifies a Kubernetes Object.
|
||||
|
|
@ -108,6 +109,14 @@ type Client interface {
|
|||
RESTMapper() meta.RESTMapper
|
||||
}
|
||||
|
||||
// WithWatch supports Watch on top of the CRUD operations supported by
|
||||
// the normal Client. Its intended use-case are CLI apps that need to wait for
|
||||
// events.
|
||||
type WithWatch interface {
|
||||
Client
|
||||
Watch(ctx context.Context, obj ObjectList, opts ...ListOption) (watch.Interface, error)
|
||||
}
|
||||
|
||||
// IndexerFunc knows how to take an object and turn it into a series
|
||||
// of non-namespaced keys. Namespaced objects are automatically given
|
||||
// namespaced and non-spaced variants, so keys do not need to include namespace.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// NewWithWatch returns a new WithWatch.
|
||||
func NewWithWatch(config *rest.Config, options Options) (WithWatch, error) {
|
||||
client, err := newClient(config, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dynamicClient, err := dynamic.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &watchingClient{client: client, dynamic: dynamicClient}, nil
|
||||
}
|
||||
|
||||
type watchingClient struct {
|
||||
*client
|
||||
dynamic dynamic.Interface
|
||||
}
|
||||
|
||||
func (w *watchingClient) Watch(ctx context.Context, list ObjectList, opts ...ListOption) (watch.Interface, error) {
|
||||
switch l := list.(type) {
|
||||
case *unstructured.UnstructuredList:
|
||||
return w.unstructuredWatch(ctx, l, opts...)
|
||||
case *metav1.PartialObjectMetadataList:
|
||||
return w.metadataWatch(ctx, l, opts...)
|
||||
default:
|
||||
return w.typedWatch(ctx, l, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *watchingClient) listOpts(opts ...ListOption) ListOptions {
|
||||
listOpts := ListOptions{}
|
||||
listOpts.ApplyOptions(opts)
|
||||
if listOpts.Raw == nil {
|
||||
listOpts.Raw = &metav1.ListOptions{}
|
||||
}
|
||||
listOpts.Raw.Watch = true
|
||||
|
||||
return listOpts
|
||||
}
|
||||
|
||||
func (w *watchingClient) metadataWatch(ctx context.Context, obj *metav1.PartialObjectMetadataList, opts ...ListOption) (watch.Interface, error) {
|
||||
gvk := obj.GroupVersionKind()
|
||||
if strings.HasSuffix(gvk.Kind, "List") {
|
||||
gvk.Kind = gvk.Kind[:len(gvk.Kind)-4]
|
||||
}
|
||||
|
||||
listOpts := w.listOpts(opts...)
|
||||
|
||||
resInt, err := w.client.metadataClient.getResourceInterface(gvk, listOpts.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resInt.Watch(ctx, *listOpts.AsListOptions())
|
||||
}
|
||||
|
||||
func (w *watchingClient) unstructuredWatch(ctx context.Context, obj *unstructured.UnstructuredList, opts ...ListOption) (watch.Interface, error) {
|
||||
gvk := obj.GroupVersionKind()
|
||||
if strings.HasSuffix(gvk.Kind, "List") {
|
||||
gvk.Kind = gvk.Kind[:len(gvk.Kind)-4]
|
||||
}
|
||||
|
||||
r, err := w.client.unstructuredClient.cache.getResource(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
listOpts := w.listOpts(opts...)
|
||||
|
||||
if listOpts.Namespace != "" && r.isNamespaced() {
|
||||
return w.dynamic.Resource(r.mapping.Resource).Namespace(listOpts.Namespace).Watch(ctx, *listOpts.AsListOptions())
|
||||
}
|
||||
return w.dynamic.Resource(r.mapping.Resource).Watch(ctx, *listOpts.AsListOptions())
|
||||
}
|
||||
|
||||
func (w *watchingClient) typedWatch(ctx context.Context, obj ObjectList, opts ...ListOption) (watch.Interface, error) {
|
||||
r, err := w.client.typedClient.cache.getResource(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
listOpts := w.listOpts(opts...)
|
||||
|
||||
return r.Get().
|
||||
NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()).
|
||||
Resource(r.resource()).
|
||||
VersionedParams(listOpts.AsListOptions(), w.client.typedClient.paramCodec).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ go_library(
|
|||
"deleg.go",
|
||||
"log.go",
|
||||
"null.go",
|
||||
"warning_handler.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/sigs.k8s.io/controller-runtime/pkg/log",
|
||||
importpath = "sigs.k8s.io/controller-runtime/pkg/log",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
)
|
||||
|
||||
// KubeAPIWarningLoggerOptions controls the behavior
|
||||
// of a rest.WarningHandler constructed using NewKubeAPIWarningLogger()
|
||||
type KubeAPIWarningLoggerOptions struct {
|
||||
// Deduplicate indicates a given warning message should only be written once.
|
||||
// Setting this to true in a long-running process handling many warnings can
|
||||
// result in increased memory use.
|
||||
Deduplicate bool
|
||||
}
|
||||
|
||||
// KubeAPIWarningLogger is a wrapper around
|
||||
// a provided logr.Logger that implements the
|
||||
// rest.WarningHandler interface.
|
||||
type KubeAPIWarningLogger struct {
|
||||
// logger is used to log responses with the warning header
|
||||
logger logr.Logger
|
||||
// opts contain options controlling warning output
|
||||
opts KubeAPIWarningLoggerOptions
|
||||
// writtenLock gurads written
|
||||
writtenLock sync.Mutex
|
||||
// used to keep track of already logged messages
|
||||
// and help in de-duplication.
|
||||
written map[string]struct{}
|
||||
}
|
||||
|
||||
// HandleWarningHeader handles logging for responses from API server that are
|
||||
// warnings with code being 299 and uses a logr.Logger for it's logging purposes.
|
||||
func (l *KubeAPIWarningLogger) HandleWarningHeader(code int, agent string, message string) {
|
||||
if code != 299 || len(message) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if l.opts.Deduplicate {
|
||||
l.writtenLock.Lock()
|
||||
defer l.writtenLock.Unlock()
|
||||
|
||||
if _, alreadyLogged := l.written[message]; alreadyLogged {
|
||||
return
|
||||
}
|
||||
l.written[message] = struct{}{}
|
||||
}
|
||||
l.logger.Info(message)
|
||||
}
|
||||
|
||||
// NewKubeAPIWarningLogger returns an implementation of rest.WarningHandler that logs warnings
|
||||
// with code = 299 to the provided logr.Logger.
|
||||
func NewKubeAPIWarningLogger(l logr.Logger, opts KubeAPIWarningLoggerOptions) *KubeAPIWarningLogger {
|
||||
h := &KubeAPIWarningLogger{logger: l, opts: opts}
|
||||
if opts.Deduplicate {
|
||||
h.written = map[string]struct{}{}
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
|
@ -11,9 +11,9 @@ go_library(
|
|||
importpath = "sigs.k8s.io/controller-runtime/pkg/webhook",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus/promhttp:go_default_library",
|
||||
"//vendor/gomodules.xyz/jsonpatch/v2:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||
"//vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher:go_default_library",
|
||||
"//vendor/sigs.k8s.io/controller-runtime/pkg/internal/log:go_default_library",
|
||||
"//vendor/sigs.k8s.io/controller-runtime/pkg/runtime/inject:go_default_library",
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ go_library(
|
|||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||
"//vendor/sigs.k8s.io/controller-runtime/pkg/internal/log:go_default_library",
|
||||
"//vendor/sigs.k8s.io/controller-runtime/pkg/runtime/inject:go_default_library",
|
||||
"//vendor/sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -27,8 +27,11 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -110,6 +113,9 @@ func (f HandlerFunc) Handle(ctx context.Context, req Request) Response {
|
|||
}
|
||||
|
||||
// Webhook represents each individual webhook.
|
||||
//
|
||||
// It must be registered with a webhook.Server or
|
||||
// populated by StandaloneWebhook to be ran on an arbitrary HTTP server.
|
||||
type Webhook struct {
|
||||
// Handler actually processes an admission request returning whether it was allowed or denied,
|
||||
// and potentially patches to apply to the handler.
|
||||
|
|
@ -203,3 +209,43 @@ func (w *Webhook) InjectFunc(f inject.Func) error {
|
|||
|
||||
return setFields(w.Handler)
|
||||
}
|
||||
|
||||
// StandaloneOptions let you configure a StandaloneWebhook.
|
||||
type StandaloneOptions struct {
|
||||
// Scheme is the scheme used to resolve runtime.Objects to GroupVersionKinds / Resources
|
||||
// Defaults to the kubernetes/client-go scheme.Scheme, but it's almost always better
|
||||
// idea to pass your own scheme in. See the documentation in pkg/scheme for more information.
|
||||
Scheme *runtime.Scheme
|
||||
// Logger to be used by the webhook.
|
||||
// If none is set, it defaults to log.Log global logger.
|
||||
Logger logr.Logger
|
||||
// MetricsPath is used for labelling prometheus metrics
|
||||
// by the path is served on.
|
||||
// If none is set, prometheus metrics will not be generated.
|
||||
MetricsPath string
|
||||
}
|
||||
|
||||
// StandaloneWebhook prepares a webhook for use without a webhook.Server,
|
||||
// passing in the information normally populated by webhook.Server
|
||||
// and instrumenting the webhook with metrics.
|
||||
//
|
||||
// Use this to attach your webhook to an arbitrary HTTP server or mux.
|
||||
func StandaloneWebhook(hook *Webhook, opts StandaloneOptions) (http.Handler, error) {
|
||||
if opts.Scheme == nil {
|
||||
opts.Scheme = scheme.Scheme
|
||||
}
|
||||
|
||||
if err := hook.InjectScheme(opts.Scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.Logger == nil {
|
||||
opts.Logger = logf.RuntimeLog.WithName("webhook")
|
||||
}
|
||||
hook.log = opts.Logger
|
||||
|
||||
if opts.MetricsPath == "" {
|
||||
return hook, nil
|
||||
}
|
||||
return metrics.InstrumentedHook(opts.MetricsPath, hook), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ go_library(
|
|||
visibility = ["//vendor/sigs.k8s.io/controller-runtime/pkg/webhook:__subpackages__"],
|
||||
deps = [
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus/promhttp:go_default_library",
|
||||
"//vendor/sigs.k8s.io/controller-runtime/pkg/metrics:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@ limitations under the License.
|
|||
package metrics
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/metrics"
|
||||
)
|
||||
|
|
@ -59,3 +62,24 @@ var (
|
|||
func init() {
|
||||
metrics.Registry.MustRegister(RequestLatency, RequestTotal, RequestInFlight)
|
||||
}
|
||||
|
||||
// InstrumentedHook adds some instrumentation on top of the given webhook.
|
||||
func InstrumentedHook(path string, hookRaw http.Handler) http.Handler {
|
||||
lbl := prometheus.Labels{"webhook": path}
|
||||
|
||||
lat := RequestLatency.MustCurryWith(lbl)
|
||||
cnt := RequestTotal.MustCurryWith(lbl)
|
||||
gge := RequestInFlight.With(lbl)
|
||||
|
||||
// Initialize the most likely HTTP status codes.
|
||||
cnt.WithLabelValues("200")
|
||||
cnt.WithLabelValues("500")
|
||||
|
||||
return promhttp.InstrumentHandlerDuration(
|
||||
lat,
|
||||
promhttp.InstrumentHandlerCounter(
|
||||
cnt,
|
||||
promhttp.InstrumentHandlerInFlight(gge, hookRaw),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ import (
|
|||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
kscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics"
|
||||
|
|
@ -124,7 +124,7 @@ func (s *Server) Register(path string, hook http.Handler) {
|
|||
}
|
||||
// TODO(directxman12): call setfields if we've already started the server
|
||||
s.webhooks[path] = hook
|
||||
s.WebhookMux.Handle(path, instrumentedHook(path, hook))
|
||||
s.WebhookMux.Handle(path, metrics.InstrumentedHook(path, hook))
|
||||
|
||||
regLog := log.WithValues("path", path)
|
||||
regLog.Info("registering webhook")
|
||||
|
|
@ -149,25 +149,24 @@ func (s *Server) Register(path string, hook http.Handler) {
|
|||
}
|
||||
}
|
||||
|
||||
// instrumentedHook adds some instrumentation on top of the given webhook.
|
||||
func instrumentedHook(path string, hookRaw http.Handler) http.Handler {
|
||||
lbl := prometheus.Labels{"webhook": path}
|
||||
// StartStandalone runs a webhook server without
|
||||
// a controller manager.
|
||||
func (s *Server) StartStandalone(ctx context.Context, scheme *runtime.Scheme) error {
|
||||
// Use the Kubernetes client-go scheme if none is specified
|
||||
if scheme == nil {
|
||||
scheme = kscheme.Scheme
|
||||
}
|
||||
|
||||
lat := metrics.RequestLatency.MustCurryWith(lbl)
|
||||
cnt := metrics.RequestTotal.MustCurryWith(lbl)
|
||||
gge := metrics.RequestInFlight.With(lbl)
|
||||
if err := s.InjectFunc(func(i interface{}) error {
|
||||
if _, err := inject.SchemeInto(scheme, i); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize the most likely HTTP status codes.
|
||||
cnt.WithLabelValues("200")
|
||||
cnt.WithLabelValues("500")
|
||||
|
||||
return promhttp.InstrumentHandlerDuration(
|
||||
lat,
|
||||
promhttp.InstrumentHandlerCounter(
|
||||
cnt,
|
||||
promhttp.InstrumentHandlerInFlight(gge, hookRaw),
|
||||
),
|
||||
)
|
||||
return s.Start(ctx)
|
||||
}
|
||||
|
||||
// Start runs the server.
|
||||
|
|
|
|||
Loading…
Reference in New Issue