diff --git a/docs/book/src/multiversion-tutorial/testdata/project/.gitignore b/docs/book/src/multiversion-tutorial/testdata/project/.gitignore index 7a7feec504..ada68ff086 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/.gitignore +++ b/docs/book/src/multiversion-tutorial/testdata/project/.gitignore @@ -1,4 +1,3 @@ - # Binaries for programs and plugins *.exe *.exe~ diff --git a/docs/book/src/multiversion-tutorial/testdata/project/Makefile b/docs/book/src/multiversion-tutorial/testdata/project/Makefile index 33cd76e837..c78348a151 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/Makefile +++ b/docs/book/src/multiversion-tutorial/testdata/project/Makefile @@ -1,4 +1,3 @@ - # Image URL to use all building/pushing image targets IMG ?= controller:latest # 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 .PHONY: build-installer build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment. mkdir -p dist - echo "---" > dist/install.yaml # Clean previous content - @if [ -d "config/crd" ]; then \ - $(KUSTOMIZE) build config/crd > dist/install.yaml; \ - echo "---" >> dist/install.yaml; \ - fi cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default >> dist/install.yaml + $(KUSTOMIZE) build config/default > dist/install.yaml ##@ Deployment @@ -167,7 +161,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION) KUSTOMIZE_VERSION ?= v5.3.0 CONTROLLER_TOOLS_VERSION ?= v0.14.0 ENVTEST_VERSION ?= release-0.17 -GOLANGCI_LINT_VERSION ?= v1.54.2 +GOLANGCI_LINT_VERSION ?= v1.57.2 .PHONY: kustomize kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. diff --git a/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_types.go b/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_types.go index c4bcdb930c..615fa46a76 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_types.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_types.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Kubernetes authors. +Copyright 2024 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. diff --git a/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_webhook.go b/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_webhook.go index 4fa2609c7f..cb4e8ead6a 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_webhook.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_webhook.go @@ -17,12 +17,126 @@ limitations under the License. package v2 import ( + "github.com/robfig/cron" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + validationutils "k8s.io/apimachinery/pkg/util/validation" + "k8s.io/apimachinery/pkg/util/validation/field" ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + "strings" ) -// SetupWebhookWithManager will setup the manager to manage the webhooks +// log is for logging in this package. +var cronjoblog = logf.Log.WithName("cronjob-resource") + +// SetupWebhookWithManager sets up the webhooks with the manager func (r *CronJob) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). For(r). Complete() } + +// +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 +var _ webhook.Defaulter = &CronJob{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *CronJob) Default() { + cronjoblog.Info("default", "name", r.Name) + if r.Spec.ConcurrencyPolicy == "" { + r.Spec.ConcurrencyPolicy = AllowConcurrent + } + if r.Spec.Suspend == nil { + r.Spec.Suspend = new(bool) + } + if r.Spec.SuccessfulJobsHistoryLimit == nil { + r.Spec.SuccessfulJobsHistoryLimit = new(int32) + *r.Spec.SuccessfulJobsHistoryLimit = 3 + } + if r.Spec.FailedJobsHistoryLimit == nil { + r.Spec.FailedJobsHistoryLimit = new(int32) + *r.Spec.FailedJobsHistoryLimit = 1 + } +} + +// +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 +var _ webhook.Validator = &CronJob{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *CronJob) ValidateCreate() (admission.Warnings, error) { + cronjoblog.Info("validate create", "name", r.Name) + return nil, r.validateCronJob() +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *CronJob) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { + cronjoblog.Info("validate update", "name", r.Name) + return nil, r.validateCronJob() +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *CronJob) ValidateDelete() (admission.Warnings, error) { + cronjoblog.Info("validate delete", "name", r.Name) + return nil, nil +} + +func (r *CronJob) validateCronJob() error { + var allErrs field.ErrorList + if err := r.validateCronJobName(); err != nil { + allErrs = append(allErrs, err) + } + if err := r.validateCronJobSpec(); err != nil { + allErrs = append(allErrs, err) + } + if len(allErrs) == 0 { + return nil + } + + return apierrors.NewInvalid( + schema.GroupKind{Group: "batch.tutorial.kubebuilder.io", Kind: "CronJob"}, + r.Name, allErrs) +} + +func (r *CronJob) validateCronJobName() *field.Error { + if len(r.ObjectMeta.Name) > validationutils.DNS1035LabelMaxLength-11 { + return field.Invalid(field.NewPath("metadata").Child("name"), r.Name, "must be no more than 52 characters") + } + return nil +} + +func (r *CronJob) validateCronJobSpec() *field.Error { + // Build cron expression from the parts + parts := []string{"*", "*", "*", "*", "*"} // default parts for minute, hour, day of month, month, day of week + if r.Spec.Schedule.Minute != nil { + parts[0] = string(*r.Spec.Schedule.Minute) // Directly cast CronField (which is an alias of string) to string + } + if r.Spec.Schedule.Hour != nil { + parts[1] = string(*r.Spec.Schedule.Hour) + } + if r.Spec.Schedule.DayOfMonth != nil { + parts[2] = string(*r.Spec.Schedule.DayOfMonth) + } + if r.Spec.Schedule.Month != nil { + parts[3] = string(*r.Spec.Schedule.Month) + } + if r.Spec.Schedule.DayOfWeek != nil { + parts[4] = string(*r.Spec.Schedule.DayOfWeek) + } + + // Join parts to form the full cron expression + cronExpression := strings.Join(parts, " ") + + return validateScheduleFormat( + cronExpression, + field.NewPath("spec").Child("schedule")) +} + +func validateScheduleFormat(schedule string, fldPath *field.Path) *field.Error { + if _, err := cron.ParseStandard(schedule); err != nil { + return field.Invalid(fldPath, schedule, "invalid cron schedule format: "+err.Error()) + } + return nil +} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_webhook_test.go b/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_webhook_test.go new file mode 100644 index 0000000000..84c0a1af4d --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_webhook_test.go @@ -0,0 +1,33 @@ +/* +Copyright 2024 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 v2 + +import ( + . "github.com/onsi/ginkgo/v2" +) + +var _ = Describe("CronJob Webhook", func() { + + Context("When creating CronJob under Conversion Webhook", func() { + It("Should get the converted version of CronJob", func() { + + // TODO(user): Add your logic here + + }) + }) + +}) diff --git a/docs/book/src/multiversion-tutorial/testdata/project/cmd/main.go b/docs/book/src/multiversion-tutorial/testdata/project/cmd/main.go index d6b8b8238d..4c995a5b58 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/cmd/main.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/cmd/main.go @@ -90,7 +90,7 @@ func main() { // if the enable-http2 flag is false (the default), http/2 should be disabled // due to its vulnerabilities. More specifically, disabling http/2 will - // prevent from being vulnerable to the HTTP/2 Stream Cancelation and + // prevent from being vulnerable to the HTTP/2 Stream Cancellation and // Rapid Reset CVEs. For more information see: // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3 // - https://github.com/advisories/GHSA-4374-p667-p6c8 diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/certmanager/certificate.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/certmanager/certificate.yaml index 36b9d42e69..b51082a01e 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/certmanager/certificate.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/certmanager/certificate.yaml @@ -5,11 +5,7 @@ apiVersion: cert-manager.io/v1 kind: Issuer metadata: labels: - app.kubernetes.io/name: certificate - app.kubernetes.io/instance: serving-cert - app.kubernetes.io/component: certificate - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: selfsigned-issuer namespace: system diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/crd/kustomization.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/crd/kustomization.yaml index 4e18fb4847..da9ca342d9 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/crd/kustomization.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/crd/kustomization.yaml @@ -10,11 +10,13 @@ patches: # patches here are for enabling the conversion webhook for each CRD - path: patches/webhook_in_cronjobs.yaml - path: patches/webhook_in_cronjobs.yaml +- path: patches/webhook_in_cronjobs.yaml +- path: patches/webhook_in_cronjobs.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD -- path: patches/cainjection_in_cronjobs.yaml +#- path: patches/cainjection_in_cronjobs.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # [WEBHOOK] To enable webhook, uncomment the following section diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/default/manager_auth_proxy_patch.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/default/manager_auth_proxy_patch.yaml index 70c3437f4b..4c3c27602f 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/default/manager_auth_proxy_patch.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/default/manager_auth_proxy_patch.yaml @@ -15,7 +15,7 @@ spec: capabilities: drop: - "ALL" - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.16.0 args: - "--secure-listen-address=0.0.0.0:8443" - "--upstream=http://127.0.0.1:8080/" diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/default/webhookcainjection_patch.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/default/webhookcainjection_patch.yaml index 202f1d83d5..fd03b33e74 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/default/webhookcainjection_patch.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/default/webhookcainjection_patch.yaml @@ -4,11 +4,7 @@ apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: labels: - app.kubernetes.io/name: mutatingwebhookconfiguration - app.kubernetes.io/instance: mutating-webhook-configuration - app.kubernetes.io/component: webhook - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: mutating-webhook-configuration annotations: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/manager/manager.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/manager/manager.yaml index 30ecf899e6..839f4b6756 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/manager/manager.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/manager/manager.yaml @@ -3,11 +3,7 @@ kind: Namespace metadata: labels: control-plane: controller-manager - app.kubernetes.io/name: namespace - app.kubernetes.io/instance: system - app.kubernetes.io/component: manager - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: system --- @@ -18,11 +14,7 @@ metadata: namespace: system labels: control-plane: controller-manager - app.kubernetes.io/name: deployment - app.kubernetes.io/instance: controller-manager - app.kubernetes.io/component: manager - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize spec: selector: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor.yaml index d67c6106f8..893610e201 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor.yaml @@ -4,11 +4,7 @@ kind: ServiceMonitor metadata: labels: control-plane: controller-manager - app.kubernetes.io/name: servicemonitor - app.kubernetes.io/instance: controller-manager-metrics-monitor - app.kubernetes.io/component: metrics - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: controller-manager-metrics-monitor namespace: system diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_client_clusterrole.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_client_clusterrole.yaml index 500386b28f..ac8e7be7bc 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_client_clusterrole.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_client_clusterrole.yaml @@ -2,11 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: metrics-reader - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: metrics-reader rules: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_role.yaml index 85e39513cc..17e0a11d32 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_role.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_role.yaml @@ -2,11 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: proxy-role - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: proxy-role rules: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_role_binding.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_role_binding.yaml index 8b5ff114fa..e1f50c3178 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_role_binding.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_role_binding.yaml @@ -2,11 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/instance: proxy-rolebinding - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: proxy-rolebinding roleRef: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_service.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_service.yaml index f40b3d2c0b..aff147e644 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_service.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/auth_proxy_service.yaml @@ -3,11 +3,7 @@ kind: Service metadata: labels: control-plane: controller-manager - app.kubernetes.io/name: service - app.kubernetes.io/instance: controller-manager-metrics-service - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: controller-manager-metrics-service namespace: system diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml index f9bea3908e..c36d86e55d 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml @@ -3,11 +3,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: cronjob-editor-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: cronjob-editor-role rules: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml index d43e666ff5..0bfb980971 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml @@ -3,11 +3,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: cronjob-viewer-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: cronjob-viewer-role rules: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/kustomization.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/kustomization.yaml index 731832a6ac..8db606e9e7 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/kustomization.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/kustomization.yaml @@ -16,3 +16,9 @@ resources: - auth_proxy_role.yaml - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml +# For each CRD, "Editor" and "Viewer" roles are scaffolded by +# default, aiding admins in cluster management. Those roles are +# not used by the Project itself. You can comment the following lines +# if you do not want those helpers be installed with your Project. +- cronjob_editor_role.yaml +- cronjob_viewer_role.yaml diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/leader_election_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/leader_election_role.yaml index 1488e1ce2f..e3fc403c0d 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/leader_election_role.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/leader_election_role.yaml @@ -3,11 +3,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: labels: - app.kubernetes.io/name: role - app.kubernetes.io/instance: leader-election-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: leader-election-role rules: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/leader_election_role_binding.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/leader_election_role_binding.yaml index e54e64cda0..133026ff21 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/leader_election_role_binding.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/leader_election_role_binding.yaml @@ -2,11 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: - app.kubernetes.io/name: rolebinding - app.kubernetes.io/instance: leader-election-rolebinding - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: leader-election-rolebinding roleRef: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/role_binding.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/role_binding.yaml index b8189618ab..1e81c2443c 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/role_binding.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/role_binding.yaml @@ -2,11 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/instance: manager-rolebinding - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: project - app.kubernetes.io/part-of: project + app.kubernetes.io/name: project app.kubernetes.io/managed-by: kustomize name: manager-rolebinding roleRef: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/go.mod b/docs/book/src/multiversion-tutorial/testdata/project/go.mod index 85a69d07a4..153f2c5455 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/go.mod +++ b/docs/book/src/multiversion-tutorial/testdata/project/go.mod @@ -9,7 +9,7 @@ require ( k8s.io/api v0.29.0 k8s.io/apimachinery v0.29.0 k8s.io/client-go v0.29.0 - sigs.k8s.io/controller-runtime v0.17.0 + sigs.k8s.io/controller-runtime v0.17.2 ) require ( diff --git a/docs/book/src/multiversion-tutorial/testdata/project/go.sum b/docs/book/src/multiversion-tutorial/testdata/project/go.sum index 2619439606..59b050f982 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/go.sum +++ b/docs/book/src/multiversion-tutorial/testdata/project/go.sum @@ -197,8 +197,8 @@ k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/A k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.17.0 h1:fjJQf8Ukya+VjogLO6/bNX9HE6Y2xpsO5+fyS26ur/s= -sigs.k8s.io/controller-runtime v0.17.0/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= +sigs.k8s.io/controller-runtime v0.17.2 h1:FwHwD1CTUemg0pW2otk7/U5/i5m2ymzvOXdbeGOUvw0= +sigs.k8s.io/controller-runtime v0.17.2/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/docs/book/src/multiversion-tutorial/testdata/project/internal/controller/cronjob_controller.go b/docs/book/src/multiversion-tutorial/testdata/project/internal/controller/cronjob_controller.go index fc2f917668..9ab73d5580 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/internal/controller/cronjob_controller.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/internal/controller/cronjob_controller.go @@ -87,6 +87,15 @@ var ( scheduledTimeAnnotation = "batch.tutorial.kubebuilder.io/scheduled-at" ) +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the CronJob object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.17.2/pkg/reconcile func (r *CronJobReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { log := log.FromContext(ctx) diff --git a/docs/book/src/multiversion-tutorial/testdata/project/internal/controller/cronjob_controller_test.go b/docs/book/src/multiversion-tutorial/testdata/project/internal/controller/cronjob_controller_test.go new file mode 100644 index 0000000000..20312ce782 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/internal/controller/cronjob_controller_test.go @@ -0,0 +1,104 @@ +/* +Copyright 2024 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 controller + +import ( + "context" + kbatch "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + batchv1 "tutorial.kubebuilder.io/project/api/v1" +) + +var _ = Describe("CronJob Controller", func() { + Context("When reconciling a resource", func() { + const resourceName = "test-resource" + + ctx := context.Background() + + typeNamespacedName := types.NamespacedName{ + Name: resourceName, + Namespace: "default", // TODO(user):Modify as needed + } + cronjob := &batchv1.CronJob{} + + BeforeEach(func() { + By("creating the custom resource for the Kind CronJob") + err := k8sClient.Get(ctx, typeNamespacedName, cronjob) + if err != nil && errors.IsNotFound(err) { + resource := &batchv1.CronJob{ + ObjectMeta: metav1.ObjectMeta{ + Name: resourceName, + Namespace: "default", + }, + Spec: batchv1.CronJobSpec{ + Schedule: "*/1 * * * *", // Example: runs every minute + JobTemplate: kbatch.JobTemplateSpec{ + Spec: kbatch.JobSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "example-container", + Image: "example-image", + Command: []string{"echo", "Hello World"}, + }, + }, + RestartPolicy: corev1.RestartPolicyOnFailure, + }, + }, + }, + }, + }, + } + Expect(k8sClient.Create(ctx, resource)).To(Succeed()) + } + }) + + AfterEach(func() { + // TODO(user): Cleanup logic after each test, like removing the resource instance. + resource := &batchv1.CronJob{} + err := k8sClient.Get(ctx, typeNamespacedName, resource) + Expect(err).NotTo(HaveOccurred()) + + By("Cleanup the specific resource instance CronJob") + Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) + }) + // TODO: Fix me. We need to implement the tests and ensure + // that the controller implementation of multi-version tutorial is accurate + //It("should successfully reconcile the resource", func() { + // By("Reconciling the created resource") + // controllerReconciler := &CronJobReconciler{ + // Client: k8sClient, + // Scheme: k8sClient.Scheme(), + // } + // + // _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ + // NamespacedName: typeNamespacedName, + // }) + // Expect(err).NotTo(HaveOccurred()) + // // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. + // // Example: If you expect a certain status condition after reconciliation, verify it here. + //}) + }) +}) diff --git a/docs/book/src/multiversion-tutorial/testdata/project/test/utils/utils.go b/docs/book/src/multiversion-tutorial/testdata/project/test/utils/utils.go index 0c91bc93d2..31454d2fc4 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/test/utils/utils.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/test/utils/utils.go @@ -26,11 +26,11 @@ import ( ) const ( - prometheusOperatorVersion = "v0.68.0" + prometheusOperatorVersion = "v0.72.0" prometheusOperatorURL = "https://github.com/prometheus-operator/prometheus-operator/" + "releases/download/%s/bundle.yaml" - certmanagerVersion = "v1.5.3" + certmanagerVersion = "v1.14.4" certmanagerURLTmpl = "https://github.com/jetstack/cert-manager/releases/download/%s/cert-manager.yaml" )