Skip to content

Commit 6ea883f

Browse files
committed
Add url marker for webhook manifests
1 parent 89530d9 commit 6ea883f

File tree

5 files changed

+259
-0
lines changed

5 files changed

+259
-0
lines changed

pkg/webhook/parser.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@ type Config struct {
125125
// an object, and mutating webhooks can specify a reinvocationPolicy to control
126126
// whether they are reinvoked as well.
127127
ReinvocationPolicy string `marker:"reinvocationPolicy,optional"`
128+
129+
// URL allows mutating webhooks configuration to specify an external URL when generating
130+
// the manifests, instead of using the internal service communication. Should be in format of
131+
// https://address:port/ and will have the path specified on Path field appended to it.
132+
// When this option is specified, the serviceConfig.Service is removed from webhook the manifest.
133+
// The URL configuration should be between quotes
134+
URL string `marker:"url,optional"`
128135
}
129136

130137
// verbToAPIVariant converts a marker's verb to the proper value for the API.
@@ -253,6 +260,16 @@ func (c Config) matchPolicy() (*admissionregv1.MatchPolicyType, error) {
253260
// clientConfig returns the client config for a webhook.
254261
func (c Config) clientConfig() admissionregv1.WebhookClientConfig {
255262
path := c.Path
263+
264+
if c.URL != "" {
265+
var url string
266+
path = strings.TrimPrefix(c.Path, "/")
267+
url = fmt.Sprintf("%s/%s", c.URL, path)
268+
return admissionregv1.WebhookClientConfig{
269+
URL: &url,
270+
}
271+
}
272+
256273
return admissionregv1.WebhookClientConfig{
257274
Service: &admissionregv1.ServiceReference{
258275
Name: "webhook-service",

pkg/webhook/parser_integration_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,51 @@ var _ = Describe("Webhook Generation From Parsing to CustomResourceDefinition",
253253
assertSame(actualManifest, expectedManifest)
254254
}
255255
})
256+
257+
It("should properly generate the webhook definition with url instead of service", func() {
258+
By("switching into testdata to appease go modules")
259+
cwd, err := os.Getwd()
260+
Expect(err).NotTo(HaveOccurred())
261+
Expect(os.Chdir("./testdata/valid-url")).To(Succeed()) // go modules are directory-sensitive
262+
defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }()
263+
264+
By("loading the roots")
265+
pkgs, err := loader.LoadRoots(".")
266+
Expect(err).NotTo(HaveOccurred())
267+
Expect(pkgs).To(HaveLen(1))
268+
269+
By("setting up the parser")
270+
reg := &markers.Registry{}
271+
Expect(reg.Register(webhook.ConfigDefinition)).To(Succeed())
272+
273+
By("requesting that the manifest be generated")
274+
outputDir, err := ioutil.TempDir("", "webhook-integration-test")
275+
Expect(err).NotTo(HaveOccurred())
276+
defer os.RemoveAll(outputDir)
277+
genCtx := &genall.GenerationContext{
278+
Collector: &markers.Collector{Registry: reg},
279+
Roots: pkgs,
280+
OutputRule: genall.OutputToDirectory(outputDir),
281+
}
282+
Expect(webhook.Generator{}.Generate(genCtx)).To(Succeed())
283+
for _, r := range genCtx.Roots {
284+
Expect(r.Errors).To(HaveLen(0))
285+
}
286+
287+
By("loading the generated v1 YAML")
288+
actualFile, err := ioutil.ReadFile(path.Join(outputDir, "manifests.yaml"))
289+
Expect(err).NotTo(HaveOccurred())
290+
actualMutating, actualValidating := unmarshalBothV1(actualFile)
291+
292+
By("loading the desired v1 YAML")
293+
expectedFile, err := ioutil.ReadFile("manifests.yaml")
294+
Expect(err).NotTo(HaveOccurred())
295+
expectedMutating, expectedValidating := unmarshalBothV1(expectedFile)
296+
297+
By("comparing the two")
298+
assertSame(actualMutating, expectedMutating)
299+
assertSame(actualValidating, expectedValidating)
300+
})
256301
})
257302

258303
func unmarshalBothV1(in []byte) (mutating admissionregv1.MutatingWebhookConfiguration, validating admissionregv1.ValidatingWebhookConfiguration) {
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+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
apiVersion: admissionregistration.k8s.io/v1
3+
kind: MutatingWebhookConfiguration
4+
metadata:
5+
name: mutating-webhook-configuration
6+
webhooks:
7+
- admissionReviewVersions:
8+
- v1
9+
- v1beta1
10+
clientConfig:
11+
service:
12+
name: webhook-service
13+
namespace: system
14+
path: /mutate-testdata-kubebuilder-io-v1-cronjob
15+
failurePolicy: Fail
16+
matchPolicy: Equivalent
17+
name: default.cronjob.testdata.kubebuilder.io
18+
rules:
19+
- apiGroups:
20+
- testdata.kubebuiler.io
21+
apiVersions:
22+
- v1
23+
operations:
24+
- CREATE
25+
- UPDATE
26+
resources:
27+
- cronjobs
28+
sideEffects: None
29+
timeoutSeconds: 10
30+
reinvocationPolicy: IfNeeded
31+
---
32+
apiVersion: admissionregistration.k8s.io/v1
33+
kind: ValidatingWebhookConfiguration
34+
metadata:
35+
name: validating-webhook-configuration
36+
webhooks:
37+
- admissionReviewVersions:
38+
- v1
39+
- v1beta1
40+
clientConfig:
41+
url: https://somewebhook:9443/validate-testdata-kubebuilder-io-v1-cronjob
42+
failurePolicy: Fail
43+
matchPolicy: Equivalent
44+
name: validation.cronjob.testdata.kubebuilder.io
45+
rules:
46+
- apiGroups:
47+
- testdata.kubebuiler.io
48+
apiVersions:
49+
- v1
50+
operations:
51+
- CREATE
52+
- UPDATE
53+
resources:
54+
- cronjobs
55+
sideEffects: None
56+
timeoutSeconds: 10
57+
- admissionReviewVersions:
58+
- v1
59+
- v1beta1
60+
clientConfig:
61+
url: https://anothersomewebhook:9443/validate-testdata-kubebuilder-io-v1-cronjob
62+
failurePolicy: Fail
63+
matchPolicy: Equivalent
64+
name: validation.cronjob.testdata.kubebuilder.io
65+
rules:
66+
- apiGroups:
67+
- testdata.kubebuiler.io
68+
apiVersions:
69+
- v1
70+
operations:
71+
- CREATE
72+
- UPDATE
73+
resources:
74+
- cronjobs
75+
sideEffects: NoneOnDryRun
76+
timeoutSeconds: 10
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
package cronjob
17+
18+
import (
19+
"k8s.io/apimachinery/pkg/runtime"
20+
ctrl "sigs.k8s.io/controller-runtime"
21+
"sigs.k8s.io/controller-runtime/pkg/webhook"
22+
)
23+
24+
func (c *CronJob) SetupWebhookWithManager(mgr ctrl.Manager) error {
25+
return ctrl.NewWebhookManagedBy(mgr).
26+
For(c).
27+
Complete()
28+
}
29+
30+
// +kubebuilder:webhook:webhookVersions=v1,verbs=create;update,path=/validate-testdata-kubebuilder-io-v1-cronjob,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuiler.io,resources=cronjobs,versions=v1,name=validation.cronjob.testdata.kubebuilder.io,sideEffects=None,timeoutSeconds=10,admissionReviewVersions=v1;v1beta1,url="https://somewebhook:9443"
31+
// +kubebuilder:webhook:url="https://anothersomewebhook:9443",verbs=create;update,path=/validate-testdata-kubebuilder-io-v1-cronjob,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuiler.io,resources=cronjobs,versions=v1,name=validation.cronjob.testdata.kubebuilder.io,sideEffects=NoneOnDryRun,timeoutSeconds=10,admissionReviewVersions=v1;v1beta1
32+
// +kubebuilder:webhook:webhookVersions=v1,verbs=create;update,path=/mutate-testdata-kubebuilder-io-v1-cronjob,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuiler.io,resources=cronjobs,versions=v1,name=default.cronjob.testdata.kubebuilder.io,sideEffects=None,timeoutSeconds=10,admissionReviewVersions=v1;v1beta1,reinvocationPolicy=IfNeeded
33+
34+
var _ webhook.Defaulter = &CronJob{}
35+
var _ webhook.Validator = &CronJob{}
36+
37+
func (c *CronJob) Default() {
38+
}
39+
40+
func (c *CronJob) ValidateCreate() error {
41+
return nil
42+
}
43+
44+
func (c *CronJob) ValidateUpdate(_ runtime.Object) error {
45+
return nil
46+
}
47+
48+
func (c *CronJob) ValidateDelete() error {
49+
return nil
50+
}

0 commit comments

Comments
 (0)