Skip to content

Commit

Permalink
WIP: Changes Webhooks - Add Hub and Spoke
Browse files Browse the repository at this point in the history
  • Loading branch information
camilamacedo86 committed Oct 31, 2024
1 parent 8b7e17d commit 0941851
Show file tree
Hide file tree
Showing 36 changed files with 555 additions and 381 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ resources:
path: tutorial.kubebuilder.io/project/api/v1
version: v1
webhooks:
conversion: true
defaulting: true
validation: true
webhookVersion: v1
Expand All @@ -30,7 +31,6 @@ resources:
path: tutorial.kubebuilder.io/project/api/v2
version: v2
webhooks:
conversion: true
defaulting: true
validation: true
webhookVersion: v1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/*
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ type CronJobStatus struct {
*/

// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:conversion:hub
// +kubebuilder:subresource:status
// +versionName=v1
// +kubebuilder:storageversion
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/*
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
Expand All @@ -21,31 +23,27 @@ For imports, we'll need the controller-runtime
package, plus the API version for our hub type (v1), and finally some of the
standard packages.
*/

import (
"fmt"
"strings"

"log"

"sigs.k8s.io/controller-runtime/pkg/conversion"

v1 "tutorial.kubebuilder.io/project/api/v1"
batchv1 "tutorial.kubebuilder.io/project/api/v1"
)

// +kubebuilder:docs-gen:collapse=Imports

/*
Our "spoke" versions need to implement the
[`Convertible`](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Convertible)
interface. Namely, they'll need `ConvertTo()` and `ConvertFrom()`
methods to convert to/from the hub version.
*/

/*
ConvertTo is expected to modify its argument to contain the converted object.
Most of the conversion is straightforward copying, except for converting our changed field.
*/
// ConvertTo converts this CronJob to the Hub version (v1).

// ConvertTo converts this CronJob (v2) to the Hub version (v1).
func (src *CronJob) ConvertTo(dstRaw conversion.Hub) error {
dst := dstRaw.(*v1.CronJob)
dst := dstRaw.(*batchv1.CronJob)
log.Printf("Converting from %T to %T", src, dst)

sched := src.Spec.Schedule
scheduleParts := []string{"*", "*", "*", "*", "*"}
Expand Down Expand Up @@ -74,7 +72,7 @@ func (src *CronJob) ConvertTo(dstRaw conversion.Hub) error {

// Spec
dst.Spec.StartingDeadlineSeconds = src.Spec.StartingDeadlineSeconds
dst.Spec.ConcurrencyPolicy = v1.ConcurrencyPolicy(src.Spec.ConcurrencyPolicy)
dst.Spec.ConcurrencyPolicy = batchv1.ConcurrencyPolicy(src.Spec.ConcurrencyPolicy)
dst.Spec.Suspend = src.Spec.Suspend
dst.Spec.JobTemplate = src.Spec.JobTemplate
dst.Spec.SuccessfulJobsHistoryLimit = src.Spec.SuccessfulJobsHistoryLimit
Expand All @@ -85,6 +83,7 @@ func (src *CronJob) ConvertTo(dstRaw conversion.Hub) error {
dst.Status.LastScheduleTime = src.Status.LastScheduleTime

// +kubebuilder:docs-gen:collapse=rote conversion

return nil
}

Expand All @@ -93,9 +92,10 @@ ConvertFrom is expected to modify its receiver to contain the converted object.
Most of the conversion is straightforward copying, except for converting our changed field.
*/

// ConvertFrom converts from the Hub version (v1) to this version.
// ConvertFrom converts the Hub version (v1) to this CronJob (v2).
func (dst *CronJob) ConvertFrom(srcRaw conversion.Hub) error {
src := srcRaw.(*v1.CronJob)
src := srcRaw.(*batchv1.CronJob)
log.Printf("Converting from %T to %T", src, dst)

schedParts := strings.Split(src.Spec.Schedule, " ")
if len(schedParts) != 5 {
Expand Down Expand Up @@ -133,5 +133,6 @@ func (dst *CronJob) ConvertFrom(srcRaw conversion.Hub) error {
dst.Status.LastScheduleTime = src.Status.LastScheduleTime

// +kubebuilder:docs-gen:collapse=rote conversion

return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ 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
# +kubebuilder:scaffold:crdkustomizewebhookpatch

# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@ Next, we'll setup a logger for the webhooks.
var cronjoblog = logf.Log.WithName("cronjob-resource")

/*
This setup doubles as setup for our conversion webhooks: as long as our
types implement the
[Hub](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Hub) and
[Convertible](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Convertible)
interfaces, a conversion webhook will be registered.
Then, we set up the webhook with the manager.
*/

// SetupCronJobWebhookWithManager registers the webhook for CronJob in the manager.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,4 @@ var _ = Describe("CronJob Webhook", func() {
// })
})

Context("When creating CronJob under Conversion Webhook", func() {
// TODO (user): Add logic to convert the object to the desired version and verify the conversion
// Example:
// It("Should convert the object correctly", func() {
// convertedObj := &batchv2.CronJob{}
// Expect(obj.ConvertTo(convertedObj)).To(Succeed())
// Expect(convertedObj).ToNot(BeNil())
// })
})

})
99 changes: 69 additions & 30 deletions hack/docs/internal/multiversion-tutorial/generate_multiversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package multiversion

import (
"os"
"os/exec"
"path/filepath"

Expand Down Expand Up @@ -57,14 +56,23 @@ func (sp *Sample) GenerateSampleProject() {
)
hackutils.CheckError("Creating the v2 API without controller", err)

log.Infof("Creating conversion webhook for v1")
err = sp.ctx.CreateWebhook(
"--group", "batch",
"--version", "v1",
"--kind", "CronJob",
"--conversion",
"--spoke", "v2",
)
hackutils.CheckError("Creating conversion webhook for v1", err)

log.Infof("Creating defaulting and validation webhook for v2")
err = sp.ctx.CreateWebhook(
"--group", "batch",
"--version", "v2",
"--kind", "CronJob",
"--defaulting",
"--programmatic-validation",
"--conversion",
)
hackutils.CheckError("Creating defaulting and validation webhook for v2", err)
}
Expand All @@ -75,25 +83,12 @@ func (sp *Sample) UpdateTutorial() {
// Update files according to the multiversion
sp.updateApiV1()
sp.updateApiV2()
sp.updateWebhookV1()
sp.updateWebhookV2()
sp.createHubFiles()
sp.updateHubFiles()
sp.updateSampleV2()
sp.updateMain()
}

func (sp *Sample) updateWebhookV1() {
err := pluginutil.ReplaceInFile(
filepath.Join(sp.ctx.Dir, "internal/webhook/v1/cronjob_webhook.go"),
"Then, we set up the webhook with the manager.",
`This setup doubles as setup for our conversion webhooks: as long as our
types implement the
[Hub](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Hub) and
[Convertible](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Convertible)
interfaces, a conversion webhook will be registered.`,
)
hackutils.CheckError("replace webhook setup text", err)
}
func (sp *Sample) updateSampleV2() {
path := filepath.Join(sp.ctx.Dir, "config/samples/batch_v2_cronjob.yaml")
oldText := `# TODO(user): Add fields here`
Expand All @@ -106,28 +101,72 @@ func (sp *Sample) updateSampleV2() {
hackutils.CheckError("replacing TODO with sampleV2Code in batch_v2_cronjob.yaml", err)
}

func (sp *Sample) createHubFiles() {
func (sp *Sample) updateHubFiles() {
path := filepath.Join(sp.ctx.Dir, "api/v1/cronjob_conversion.go")

_, err := os.Create(path)
hackutils.CheckError("creating conversion file v1", err)
err := pluginutil.InsertCodeIfNotExist(path,
"limitations under the License.\n*/",
"\n// +kubebuilder:docs-gen:collapse=Apache License")
hackutils.CheckError("appending into hub v1 collapse docs", err)

err = pluginutil.AppendCodeAtTheEnd(path, "")
hackutils.CheckError("creating empty conversion file v1", err)

err = pluginutil.AppendCodeAtTheEnd(path, hubV1Code)
hackutils.CheckError("appending hubV1Code to cronjob_conversion.go", err)
err = pluginutil.ReplaceInFile(path,
"// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!",
hubV1CodeComment)
hackutils.CheckError("adding comment to hub v1", err)

path = filepath.Join(sp.ctx.Dir, "api/v2/cronjob_conversion.go")

_, err = os.Create(path)
hackutils.CheckError("creating conversion file v2", err)
err = pluginutil.InsertCodeIfNotExist(path,
"limitations under the License.\n*/",
"\n// +kubebuilder:docs-gen:collapse=Apache License")
hackutils.CheckError("appending into hub v2 collapse docs", err)

err = pluginutil.InsertCode(path,
"import (",
`
"fmt"
"strings"
`)
hackutils.CheckError("adding imports to hub v2", err)

err = pluginutil.ReplaceInFile(path,
"package v2",
hubV2CodeComment)
hackutils.CheckError("adding comment to hub v2", err)

err = pluginutil.ReplaceInFile(path,
"// TODO: Implement conversion logic from v2 to v1",
hubV2CovertTo)
hackutils.CheckError("replace covertTo at hub v2", err)

err = pluginutil.ReplaceInFile(path,
"// TODO: Implement conversion logic from v1 to v2",
hubV2ConvertFromCode)
hackutils.CheckError("replace covert from at hub v2", err)

err = pluginutil.ReplaceInFile(path,
"// ConvertFrom converts the Hub version (v1) to this CronJob (v2).",
`/*
ConvertFrom is expected to modify its receiver to contain the converted object.
Most of the conversion is straightforward copying, except for converting our changed field.
*/
// ConvertFrom converts the Hub version (v1) to this CronJob (v2).`)
hackutils.CheckError("replace covert from info at hub v2", err)

err = pluginutil.ReplaceInFile(path,
"// ConvertTo converts this CronJob (v2) to the Hub version (v1).",
`/*
ConvertTo is expected to modify its argument to contain the converted object.
Most of the conversion is straightforward copying, except for converting our changed field.
*/
err = pluginutil.AppendCodeAtTheEnd(path, "")
hackutils.CheckError("creating empty conversion file v2", err)
// ConvertTo converts this CronJob (v2) to the Hub version (v1).`)
hackutils.CheckError("replace covert info at hub v2", err)

err = pluginutil.AppendCodeAtTheEnd(path, hubV2Code)
hackutils.CheckError("appending hubV2Code to cronjob_conversion.go", err)
//err = pluginutil.AppendCodeAtTheEnd(path, hubV2Code)

Check failure on line 168 in hack/docs/internal/multiversion-tutorial/generate_multiversion.go

View workflow job for this annotation

GitHub Actions / golangci-lint

comment-spacings: no space between comment delimiter and comment text (revive)
//hackutils.CheckError("appending hubV2Code to cronjob_conversion.go", err)

Check failure on line 169 in hack/docs/internal/multiversion-tutorial/generate_multiversion.go

View workflow job for this annotation

GitHub Actions / golangci-lint

comment-spacings: no space between comment delimiter and comment text (revive)

}

Expand Down
Loading

0 comments on commit 0941851

Please sign in to comment.