Skip to content

Commit cab5b15

Browse files
authored
Merge pull request #3875 from camilamacedo86/update-doc-conv
📖 Update Multi-Version Tutorial
2 parents 8ef60ff + 2591ad0 commit cab5b15

27 files changed

+294
-89
lines changed

docs/book/src/multiversion-tutorial/testdata/project/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
# Binaries for programs and plugins
32
*.exe
43
*.exe~

docs/book/src/multiversion-tutorial/testdata/project/Makefile

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
# Image URL to use all building/pushing image targets
32
IMG ?= controller:latest
43
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
@@ -118,13 +117,8 @@ docker-buildx: ## Build and push docker image for the manager for cross-platform
118117
.PHONY: build-installer
119118
build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment.
120119
mkdir -p dist
121-
echo "---" > dist/install.yaml # Clean previous content
122-
@if [ -d "config/crd" ]; then \
123-
$(KUSTOMIZE) build config/crd > dist/install.yaml; \
124-
echo "---" >> dist/install.yaml; \
125-
fi
126120
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
127-
$(KUSTOMIZE) build config/default >> dist/install.yaml
121+
$(KUSTOMIZE) build config/default > dist/install.yaml
128122

129123
##@ Deployment
130124

@@ -167,7 +161,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION)
167161
KUSTOMIZE_VERSION ?= v5.3.0
168162
CONTROLLER_TOOLS_VERSION ?= v0.14.0
169163
ENVTEST_VERSION ?= release-0.17
170-
GOLANGCI_LINT_VERSION ?= v1.54.2
164+
GOLANGCI_LINT_VERSION ?= v1.57.2
171165

172166
.PHONY: kustomize
173167
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.

docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2023 The Kubernetes authors.
2+
Copyright 2024 The Kubernetes authors.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.

docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_webhook.go

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,126 @@ limitations under the License.
1717
package v2
1818

1919
import (
20+
"github.com/robfig/cron"
21+
apierrors "k8s.io/apimachinery/pkg/api/errors"
22+
"k8s.io/apimachinery/pkg/runtime"
23+
"k8s.io/apimachinery/pkg/runtime/schema"
24+
validationutils "k8s.io/apimachinery/pkg/util/validation"
25+
"k8s.io/apimachinery/pkg/util/validation/field"
2026
ctrl "sigs.k8s.io/controller-runtime"
27+
logf "sigs.k8s.io/controller-runtime/pkg/log"
28+
"sigs.k8s.io/controller-runtime/pkg/webhook"
29+
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
30+
"strings"
2131
)
2232

23-
// SetupWebhookWithManager will setup the manager to manage the webhooks
33+
// log is for logging in this package.
34+
var cronjoblog = logf.Log.WithName("cronjob-resource")
35+
36+
// SetupWebhookWithManager sets up the webhooks with the manager
2437
func (r *CronJob) SetupWebhookWithManager(mgr ctrl.Manager) error {
2538
return ctrl.NewWebhookManagedBy(mgr).
2639
For(r).
2740
Complete()
2841
}
42+
43+
// +kubebuilder:webhook:path=/mutate-batch-tutorial-kubebuilder-io-v1-cronjob,mutating=true,failurePolicy=fail,groups=batch.tutorial.kubebuilder.io,resources=cronjobs,verbs=create;update,versions=v1,name=mcronjob.kb.io,sideEffects=None,admissionReviewVersions=v1
44+
var _ webhook.Defaulter = &CronJob{}
45+
46+
// Default implements webhook.Defaulter so a webhook will be registered for the type
47+
func (r *CronJob) Default() {
48+
cronjoblog.Info("default", "name", r.Name)
49+
if r.Spec.ConcurrencyPolicy == "" {
50+
r.Spec.ConcurrencyPolicy = AllowConcurrent
51+
}
52+
if r.Spec.Suspend == nil {
53+
r.Spec.Suspend = new(bool)
54+
}
55+
if r.Spec.SuccessfulJobsHistoryLimit == nil {
56+
r.Spec.SuccessfulJobsHistoryLimit = new(int32)
57+
*r.Spec.SuccessfulJobsHistoryLimit = 3
58+
}
59+
if r.Spec.FailedJobsHistoryLimit == nil {
60+
r.Spec.FailedJobsHistoryLimit = new(int32)
61+
*r.Spec.FailedJobsHistoryLimit = 1
62+
}
63+
}
64+
65+
// +kubebuilder:webhook:verbs=create;update;delete,path=/validate-batch-tutorial-kubebuilder-io-v1-cronjob,mutating=false,failurePolicy=fail,groups=batch.tutorial.kubebuilder.io,resources=cronjobs,versions=v1,name=vcronjob.kb.io,sideEffects=None,admissionReviewVersions=v1
66+
var _ webhook.Validator = &CronJob{}
67+
68+
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
69+
func (r *CronJob) ValidateCreate() (admission.Warnings, error) {
70+
cronjoblog.Info("validate create", "name", r.Name)
71+
return nil, r.validateCronJob()
72+
}
73+
74+
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
75+
func (r *CronJob) ValidateUpdate(old runtime.Object) (admission.Warnings, error) {
76+
cronjoblog.Info("validate update", "name", r.Name)
77+
return nil, r.validateCronJob()
78+
}
79+
80+
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
81+
func (r *CronJob) ValidateDelete() (admission.Warnings, error) {
82+
cronjoblog.Info("validate delete", "name", r.Name)
83+
return nil, nil
84+
}
85+
86+
func (r *CronJob) validateCronJob() error {
87+
var allErrs field.ErrorList
88+
if err := r.validateCronJobName(); err != nil {
89+
allErrs = append(allErrs, err)
90+
}
91+
if err := r.validateCronJobSpec(); err != nil {
92+
allErrs = append(allErrs, err)
93+
}
94+
if len(allErrs) == 0 {
95+
return nil
96+
}
97+
98+
return apierrors.NewInvalid(
99+
schema.GroupKind{Group: "batch.tutorial.kubebuilder.io", Kind: "CronJob"},
100+
r.Name, allErrs)
101+
}
102+
103+
func (r *CronJob) validateCronJobName() *field.Error {
104+
if len(r.ObjectMeta.Name) > validationutils.DNS1035LabelMaxLength-11 {
105+
return field.Invalid(field.NewPath("metadata").Child("name"), r.Name, "must be no more than 52 characters")
106+
}
107+
return nil
108+
}
109+
110+
func (r *CronJob) validateCronJobSpec() *field.Error {
111+
// Build cron expression from the parts
112+
parts := []string{"*", "*", "*", "*", "*"} // default parts for minute, hour, day of month, month, day of week
113+
if r.Spec.Schedule.Minute != nil {
114+
parts[0] = string(*r.Spec.Schedule.Minute) // Directly cast CronField (which is an alias of string) to string
115+
}
116+
if r.Spec.Schedule.Hour != nil {
117+
parts[1] = string(*r.Spec.Schedule.Hour)
118+
}
119+
if r.Spec.Schedule.DayOfMonth != nil {
120+
parts[2] = string(*r.Spec.Schedule.DayOfMonth)
121+
}
122+
if r.Spec.Schedule.Month != nil {
123+
parts[3] = string(*r.Spec.Schedule.Month)
124+
}
125+
if r.Spec.Schedule.DayOfWeek != nil {
126+
parts[4] = string(*r.Spec.Schedule.DayOfWeek)
127+
}
128+
129+
// Join parts to form the full cron expression
130+
cronExpression := strings.Join(parts, " ")
131+
132+
return validateScheduleFormat(
133+
cronExpression,
134+
field.NewPath("spec").Child("schedule"))
135+
}
136+
137+
func validateScheduleFormat(schedule string, fldPath *field.Path) *field.Error {
138+
if _, err := cron.ParseStandard(schedule); err != nil {
139+
return field.Invalid(fldPath, schedule, "invalid cron schedule format: "+err.Error())
140+
}
141+
return nil
142+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
Copyright 2024 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 v2
18+
19+
import (
20+
. "github.com/onsi/ginkgo/v2"
21+
)
22+
23+
var _ = Describe("CronJob Webhook", func() {
24+
25+
Context("When creating CronJob under Conversion Webhook", func() {
26+
It("Should get the converted version of CronJob", func() {
27+
28+
// TODO(user): Add your logic here
29+
30+
})
31+
})
32+
33+
})

docs/book/src/multiversion-tutorial/testdata/project/cmd/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func main() {
9090

9191
// if the enable-http2 flag is false (the default), http/2 should be disabled
9292
// due to its vulnerabilities. More specifically, disabling http/2 will
93-
// prevent from being vulnerable to the HTTP/2 Stream Cancelation and
93+
// prevent from being vulnerable to the HTTP/2 Stream Cancellation and
9494
// Rapid Reset CVEs. For more information see:
9595
// - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
9696
// - https://github.com/advisories/GHSA-4374-p667-p6c8

docs/book/src/multiversion-tutorial/testdata/project/config/certmanager/certificate.yaml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@ apiVersion: cert-manager.io/v1
55
kind: Issuer
66
metadata:
77
labels:
8-
app.kubernetes.io/name: certificate
9-
app.kubernetes.io/instance: serving-cert
10-
app.kubernetes.io/component: certificate
11-
app.kubernetes.io/created-by: project
12-
app.kubernetes.io/part-of: project
8+
app.kubernetes.io/name: project
139
app.kubernetes.io/managed-by: kustomize
1410
name: selfsigned-issuer
1511
namespace: system

docs/book/src/multiversion-tutorial/testdata/project/config/crd/kustomization.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ patches:
1010
# patches here are for enabling the conversion webhook for each CRD
1111
- path: patches/webhook_in_cronjobs.yaml
1212
- path: patches/webhook_in_cronjobs.yaml
13+
- path: patches/webhook_in_cronjobs.yaml
14+
- path: patches/webhook_in_cronjobs.yaml
1315
#+kubebuilder:scaffold:crdkustomizewebhookpatch
1416

1517
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
1618
# patches here are for enabling the CA injection for each CRD
17-
- path: patches/cainjection_in_cronjobs.yaml
19+
#- path: patches/cainjection_in_cronjobs.yaml
1820
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
1921

2022
# [WEBHOOK] To enable webhook, uncomment the following section

docs/book/src/multiversion-tutorial/testdata/project/config/default/manager_auth_proxy_patch.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ spec:
1515
capabilities:
1616
drop:
1717
- "ALL"
18-
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0
18+
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.16.0
1919
args:
2020
- "--secure-listen-address=0.0.0.0:8443"
2121
- "--upstream=http://127.0.0.1:8080/"

docs/book/src/multiversion-tutorial/testdata/project/config/default/webhookcainjection_patch.yaml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ apiVersion: admissionregistration.k8s.io/v1
44
kind: MutatingWebhookConfiguration
55
metadata:
66
labels:
7-
app.kubernetes.io/name: mutatingwebhookconfiguration
8-
app.kubernetes.io/instance: mutating-webhook-configuration
9-
app.kubernetes.io/component: webhook
10-
app.kubernetes.io/created-by: project
11-
app.kubernetes.io/part-of: project
7+
app.kubernetes.io/name: project
128
app.kubernetes.io/managed-by: kustomize
139
name: mutating-webhook-configuration
1410
annotations:

0 commit comments

Comments
 (0)