Skip to content

Commit 645d44d

Browse files
authored
Merge pull request #429 from sethp-nr/feat/side-effects-for-webhooks
✨ add sideEffects parameter for webhooks
2 parents 3c5446d + 73faa54 commit 645d44d

File tree

11 files changed

+824
-2
lines changed

11 files changed

+824
-2
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/google/go-cmp v0.3.0
99
github.com/mattn/go-colorable v0.1.2 // indirect
1010
github.com/onsi/ginkgo v1.11.0
11-
github.com/onsi/gomega v1.7.0
11+
github.com/onsi/gomega v1.8.1
1212
github.com/spf13/cobra v0.0.5
1313
github.com/spf13/pflag v1.0.5
1414
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72

go.sum

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4
2929
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
3030
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
3131
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
32+
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
3233
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
3334
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
3435
github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
@@ -78,6 +79,7 @@ github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7a
7879
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
7980
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
8081
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
82+
github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg=
8183
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
8284
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
8385
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
@@ -246,24 +248,31 @@ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
246248
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
247249
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
248250
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
251+
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
252+
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
249253
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
250254
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
251255
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
252256
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
253257
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
258+
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
254259
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
255260
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
256261
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
257262
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
258263
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
264+
github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM=
259265
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
260266
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
261267
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
262268
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
263269
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
270+
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
264271
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
272+
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
265273
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
266274
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
275+
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
267276
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
268277
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
269278
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@@ -306,8 +315,11 @@ go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
306315
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
307316
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
308317
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
318+
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
309319
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
320+
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
310321
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
322+
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
311323
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
312324
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
313325
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -317,6 +329,7 @@ golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACk
317329
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU=
318330
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
319331
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
332+
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
320333
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
321334
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
322335
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -379,6 +392,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
379392
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
380393
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg=
381394
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
395+
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
382396
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
383397
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
384398
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -444,6 +458,7 @@ k8s.io/apiextensions-apiserver v0.18.0/go.mod h1:18Cwn1Xws4xnWQNC00FLq1E350b9lUF
444458
k8s.io/apimachinery v0.18.0 h1:fuPfYpk3cs1Okp/515pAf0dNhL66+8zk8RLbSX+EgAE=
445459
k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
446460
k8s.io/apiserver v0.18.0/go.mod h1:3S2O6FeBBd6XTo0njUrLxiqk8GNy6wWOftjhJcXYnjw=
461+
k8s.io/client-go v0.18.0 h1:yqKw4cTUQraZK3fcVCMeSa+lqKwcjZ5wtcOIPnxQno4=
447462
k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8=
448463
k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
449464
k8s.io/component-base v0.18.0/go.mod h1:u3BCg0z1uskkzrnAKFzulmYaEpZF7XC9Pf/uFyb1v2c=
@@ -453,6 +468,7 @@ k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUc
453468
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
454469
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
455470
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
471+
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDNZ16KJtb49HfR3ZHB9qYXM=
456472
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
457473
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU=
458474
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=

pkg/webhook/parser.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ limitations under the License.
1919
//
2020
// The markers take the form:
2121
//
22-
// +kubebuilder:webhook:failurePolicy=<string>,matchPolicy=<string>,groups=<[]string>,resources=<[]string>,verbs=<[]string>,versions=<[]string>,name=<string>,path=<string>,mutating=<bool>
22+
// +kubebuilder:webhook:failurePolicy=<string>,matchPolicy=<string>,groups=<[]string>,resources=<[]string>,verbs=<[]string>,versions=<[]string>,name=<string>,path=<string>,mutating=<bool>,sideEffects=<string>
2323
package webhook
2424

2525
import (
@@ -61,6 +61,13 @@ type Config struct {
6161
// Allowed values are "Exact" (match only if it exactly matches the specified rule)
6262
// or "Equivalent" (match a request if it modifies a resource listed in rules, even via another API group or version).
6363
MatchPolicy string `marker:",optional"`
64+
// SideEffects specify whether calling the webhook will have side effects.
65+
// This has an impact on dry runs and `kubectl diff`: if the sideEffect is "Unknown" (the default) or "Some", then
66+
// the API server will not call the webhook on a dry-run request and fails instead.
67+
// If the value is "None", then the webhook has no side effects and the API server will call it on dry-run.
68+
// If the value is "NoneOnDryRun", then the webhook is responsible for inspecting the "dryRun" property of the
69+
// AdmissionReview sent in the request, and avoiding side effects if that value is "true."
70+
SideEffects string `marker:",optional"`
6471

6572
// Groups specifies the API groups that this webhook receives requests for.
6673
Groups []string
@@ -122,6 +129,7 @@ func (c Config) ToMutatingWebhook() (admissionreg.MutatingWebhook, error) {
122129
FailurePolicy: c.failurePolicy(),
123130
MatchPolicy: matchPolicy,
124131
ClientConfig: c.clientConfig(),
132+
SideEffects: c.sideEffects(),
125133
}, nil
126134
}
127135

@@ -142,6 +150,7 @@ func (c Config) ToValidatingWebhook() (admissionreg.ValidatingWebhook, error) {
142150
FailurePolicy: c.failurePolicy(),
143151
MatchPolicy: matchPolicy,
144152
ClientConfig: c.clientConfig(),
153+
SideEffects: c.sideEffects(),
145154
}, nil
146155
}
147156

@@ -218,6 +227,24 @@ func (c Config) clientConfig() admissionreg.WebhookClientConfig {
218227
}
219228
}
220229

230+
// sideEffects returns the sideEffects config for a webhook.
231+
func (c Config) sideEffects() *admissionreg.SideEffectClass {
232+
var sideEffects admissionreg.SideEffectClass
233+
switch strings.ToLower(c.SideEffects) {
234+
case strings.ToLower(string(admissionreg.SideEffectClassNone)):
235+
sideEffects = admissionreg.SideEffectClassNone
236+
case strings.ToLower(string(admissionreg.SideEffectClassNoneOnDryRun)):
237+
sideEffects = admissionreg.SideEffectClassNoneOnDryRun
238+
case strings.ToLower(string(admissionreg.SideEffectClassSome)):
239+
sideEffects = admissionreg.SideEffectClassSome
240+
case "":
241+
return nil
242+
default:
243+
return nil
244+
}
245+
return &sideEffects
246+
}
247+
221248
// +controllertools:marker:generateHelp
222249

223250
// Generator generates (partial) {Mutating,Validating}WebhookConfiguration objects.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
Copyright 2019 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package webhook_test
18+
19+
import (
20+
"bytes"
21+
"io/ioutil"
22+
"os"
23+
"path"
24+
25+
"github.com/google/go-cmp/cmp"
26+
. "github.com/onsi/ginkgo"
27+
. "github.com/onsi/gomega"
28+
admissionreg "k8s.io/api/admissionregistration/v1beta1"
29+
"sigs.k8s.io/yaml"
30+
31+
"sigs.k8s.io/controller-tools/pkg/genall"
32+
"sigs.k8s.io/controller-tools/pkg/loader"
33+
"sigs.k8s.io/controller-tools/pkg/markers"
34+
"sigs.k8s.io/controller-tools/pkg/webhook"
35+
)
36+
37+
var _ = Describe("Webhook Generation From Parsing to CustomResourceDefinition", func() {
38+
It("should properly generate the webhook definition", func() {
39+
// TODO(directxman12): test generation across multiple versions (right
40+
// now, we're trusting k/k's conversion code, though, which is probably
41+
// fine for the time being)
42+
By("switching into testdata to appease go modules")
43+
cwd, err := os.Getwd()
44+
Expect(err).NotTo(HaveOccurred())
45+
Expect(os.Chdir("./testdata")).To(Succeed()) // go modules are directory-sensitive
46+
defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }()
47+
48+
By("loading the roots")
49+
pkgs, err := loader.LoadRoots(".")
50+
Expect(err).NotTo(HaveOccurred())
51+
Expect(pkgs).To(HaveLen(1))
52+
53+
By("setting up the parser")
54+
reg := &markers.Registry{}
55+
Expect(reg.Register(webhook.ConfigDefinition)).To(Succeed())
56+
57+
By("requesting that the manifest be generated")
58+
outputDir, err := ioutil.TempDir("", "webhook-integration-test")
59+
Expect(err).NotTo(HaveOccurred())
60+
defer os.RemoveAll(outputDir)
61+
Expect(webhook.Generator{}.Generate(&genall.GenerationContext{
62+
Collector: &markers.Collector{Registry: reg},
63+
Roots: pkgs,
64+
OutputRule: genall.OutputToDirectory(outputDir),
65+
}))
66+
67+
By("loading the generated YAML")
68+
actualFile, err := ioutil.ReadFile(path.Join(outputDir, "manifests.yaml"))
69+
Expect(err).NotTo(HaveOccurred())
70+
actualMutating, actualValidating := unmarshalBoth(actualFile)
71+
72+
By("loading the desired YAML")
73+
expectedFile, err := ioutil.ReadFile("manifests.yaml")
74+
Expect(err).NotTo(HaveOccurred())
75+
expectedMutating, expectedValidating := unmarshalBoth(expectedFile)
76+
77+
By("comparing the two")
78+
assertSame := func(actual, expected interface{}) {
79+
ExpectWithOffset(1, actual).To(Equal(expected), "type not as expected, check pkg/webhook/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(actual, expected))
80+
}
81+
assertSame(actualMutating, expectedMutating)
82+
assertSame(actualValidating, expectedValidating)
83+
})
84+
})
85+
86+
func unmarshalBoth(in []byte) (mutating admissionreg.MutatingWebhookConfiguration, validating admissionreg.ValidatingWebhookConfiguration) {
87+
documents := bytes.Split(in, []byte("\n---\n"))[1:]
88+
ExpectWithOffset(1, documents).To(HaveLen(2), "expected two documents in file, found %d", len(documents))
89+
90+
ExpectWithOffset(1, yaml.UnmarshalStrict(documents[0], &mutating)).To(Succeed(), "expected the first document in the file to be a mutating webhook configuration")
91+
ExpectWithOffset(1, yaml.UnmarshalStrict(documents[1], &validating)).To(Succeed(), "expected the second document in the file to be a validating webhook configuration")
92+
return
93+
}

pkg/webhook/testdata/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Webhook Integration Test testdata
2+
3+
This contains a tiny module used for testdata for the webhook integration
4+
test. The directory should always be called testdata, so Go treats it
5+
specially.
6+
7+
The `cronjob_types.go` file contains the input types, and is loosely based
8+
on the CronJob tutorial from the [KubeBuilder
9+
Book](https://book.kubebuilder.io/cronjob-tutorial/cronjob-tutorial.html), but with added
10+
methods to test webhook generation behavior.
11+
12+
If you add a new marker, re-generate the golden output file,
13+
`manifests.yaml`, with
14+
15+
```bash
16+
go generate
17+
```
18+
19+
Make sure you review the diff to ensure that it only contains the desired
20+
changes!
21+
22+
If you didn't add a new marker and this output changes, make sure you have
23+
a good explanation for why generated output needs to change!

pkg/webhook/testdata/cronjob_types.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
*/
15+
16+
//go:generate ../../../.run-controller-gen.sh webhook paths=. output:dir=.
17+
18+
// +groupName=testdata.kubebuilder.io
19+
// +versionName=v1
20+
package cronjob
21+
22+
import (
23+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
)
25+
26+
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
27+
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
28+
29+
// CronJobSpec defines the desired state of CronJob
30+
type CronJobSpec struct {
31+
// The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
32+
Schedule string `json:"schedule"`
33+
}
34+
35+
// CronJobStatus defines the observed state of CronJob
36+
type CronJobStatus struct {
37+
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
38+
// Important: Run "make" to regenerate code after modifying this file
39+
40+
// Information when was the last time the job was successfully scheduled.
41+
// +optional
42+
LastScheduleTime *metav1.Time `json:"lastScheduleTime,omitempty"`
43+
}
44+
45+
// +kubebuilder:object:root=true
46+
// +kubebuilder:subresource:status
47+
// +kubebuilder:resource:singular=mycronjob
48+
49+
// CronJob is the Schema for the cronjobs API
50+
type CronJob struct {
51+
/*
52+
*/
53+
metav1.TypeMeta `json:",inline"`
54+
metav1.ObjectMeta `json:"metadata,omitempty"`
55+
56+
Spec CronJobSpec `json:"spec,omitempty"`
57+
Status CronJobStatus `json:"status,omitempty"`
58+
}
59+
60+
// +kubebuilder:object:root=true
61+
62+
// CronJobList contains a list of CronJob
63+
type CronJobList struct {
64+
metav1.TypeMeta `json:",inline"`
65+
metav1.ListMeta `json:"metadata,omitempty"`
66+
Items []CronJob `json:"items"`
67+
}
68+
69+
func init() {
70+
SchemeBuilder.Register(&CronJob{}, &CronJobList{})
71+
}

pkg/webhook/testdata/go.mod

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module testdata.kubebuilder.io/cronjob
2+
3+
go 1.13
4+
5+
require (
6+
k8s.io/api v0.18.1
7+
k8s.io/apimachinery v0.18.1
8+
sigs.k8s.io/controller-runtime v0.5.2
9+
)

0 commit comments

Comments
 (0)