Skip to content

Commit

Permalink
✨ add kustomize/v2-alpha plugin to support kustomize versions >= v4
Browse files Browse the repository at this point in the history
  • Loading branch information
Camila Macedo committed Mar 31, 2022
1 parent 51bdad6 commit b5c6838
Show file tree
Hide file tree
Showing 80 changed files with 3,128 additions and 33 deletions.
4 changes: 4 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3"
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
kustomizecommonv1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v1"
kustomizecommonv2 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang"
declarativev1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/declarative/v1"
golangv2 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2"
Expand All @@ -46,6 +47,9 @@ func main() {
golangv3.Plugin{},
gov3Bundle,
&kustomizecommonv1.Plugin{},
// The kustomize v2 alpha plugin requires kustomize v4
// and can be used with the base plugin: kubebuilder init --plugins=kustomize/v2-alpha,base.go.kubebuilder.io/v3
&kustomizecommonv2.Plugin{},
&declarativev1.Plugin{},
),
cli.WithDefaultPlugins(cfgv2.Version, golangv2.Plugin{}),
Expand Down
3 changes: 2 additions & 1 deletion docs/book/src/plugins/available-plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

This section details how to use the currently available plugins in Kubebuilder.

- [Declarative V1](declarative-v1.md)
- [Declarative V1](declarative-v1.md)
- [Kustomize V2-alpha (Requires kustomize >= v4)](kustomize-v2-alpha.md)
111 changes: 111 additions & 0 deletions docs/book/src/plugins/kustomize-v2-alpha.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Kustomize v2-alpha Plugin

The kustomize plugin allows you to scaffold all kustomize manifests used to work with the language base plugin `base.go.kubebuilder.io/v3`.

<aside class="note">
<h1>Examples</h1>

You can check the kustomize content by looking at the `config/` directory provide on the sample `project-v3-with-kustomize-v2` under the [testdata][testdata]
directory of the Kubebuilder project.

</aside>

## When to use it

- If you are looking to scaffold the kustomize configuration manifests for your own language plugin
- If you are looking for support on Apple silicon (`arm64`)
- If you are looking for to begin to try out the new syntax and features provide by kustomize v4
- If you are NOT looking to build projects which will be used on Kubernetes cluster versions < `1.22` (_The new features provides by kustomize v4 are not officially supported and might not work with kubectl < `1.22`_)
- If you are NOT looking to rely on special URLs in resource fields

<aside class="note">
<h1>Supportability</h1>

You can use `kustomize/v1` plugin which is the default configuration adopted by the `go/v3` plugin if you are not prepared to began to experiment kustomize `v4`.
Also, be aware that the `base.go.kubebuilder.io/v3` is prepared to work with this plugin.

</aside>


## How to use it

If you are looking to define that your language plugin should use kustomize use the [Bundle Plugin][bundle]
to specify that your language plugin is a composition with your plugin responsable for scaffold
all that is language specific and kustomize for its configuration, see:

```go
import (
...
kustomizecommonv2 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2"
golangv3 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3"
...
)

// Bundle plugin which built the golang projects scaffold by Kubebuilder go/v3
// The follow code is creating a new plugin with its name and version via composition
// You can define that one plugin is composite by 1 or Many others plugins
gov3Bundle, _ := plugin.NewBundle(golang.DefaultNameQualifier, plugin.Version{Number: 3},
kustomizecommonv2.Plugin{}, // scaffold the config/ directory and all kustomize files
golangv3.Plugin{}, // Scaffold the Golang files and all that specific for the language e.g. go.mod, apis, controllers
)
```

Also, you can use kustomize alone via the tool:

```sh
kubebuilder init --plugins=kustomize/v2-alpha
$ ls -la
total 24
drwxr-xr-x 6 camilamacedo86 staff 192 31 Mar 09:56 .
drwxr-xr-x 11 camilamacedo86 staff 352 29 Mar 21:23 ..
-rw------- 1 camilamacedo86 staff 129 26 Mar 12:01 .dockerignore
-rw------- 1 camilamacedo86 staff 367 26 Mar 12:01 .gitignore
-rw------- 1 camilamacedo86 staff 94 31 Mar 09:56 PROJECT
drwx------ 6 camilamacedo86 staff 192 31 Mar 09:56 config
```

Or combined with the base language plugins:

```sh
# Provides the same scaffold of go/v3 plugin which is composition but with kustomize/v2-alpha
kubebuilder init --plugins=kustomize/v2-alpha,base.go.kubebuilder.io/v3 --domain example.org --repo example.org/guestbook-operator
```

## Subcommands

The kustomize plugin implements the following subcommands:

* init (`$ kubebuilder init [OPTIONS]`)
* create api (`$ kubebuilder create api [OPTIONS]`)
* create webhook (`$ kubebuilder create api [OPTIONS]`)

<aside class="note">
<h1>Create API and Webhook</h1>

Its implementation for the subcommand create api will scaffolds the kustomize manifests
which are specific for each API, see [here][kustomize-create-api]. Also, the same applies
to its implementation for create webhook.

</aside>

## Affected files

The following scaffolds will be created or updated by this plugin:

* `config/*`

## Further resources

* Check the kustomize [plugin implementation](https://github.com/kubernetes-sigs/kubebuilder/tree/master/pkg/plugins/common/kustomize)
* Check the [kustomize documentation][kustomize-docs]
* Check the [kustomize repository][kustomize-github]
* To know more about the changes between kustomize v3 and v3 see its [release notes][release-notes]
* Also, you can compare the `config/` directory between the samples `project-v3` and `project-v3-with-kustomize-v2` to check the difference in the syntax of the manifests provided by default

[sdk]:https://github.com/operator-framework/operator-sdk
[testdata]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/testdata/
[bundle]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/plugin/bundle.go
[kustomize-create-api]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/plugins/common/kustomize/v2/scaffolds/api.go#L72-L84
[kustomize-docs]: https://kustomize.io/
[kustomize-github]: https://github.com/kubernetes-sigs/kustomize
[release-notes]: https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv4.0.0
3 changes: 3 additions & 0 deletions pkg/plugins/common/kustomize/v1/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import (
"sigs.k8s.io/kubebuilder/v3/pkg/plugins"
)

// KustomizeVersion is the kubernetes-sigs/kustomize version to be used in the project
const KustomizeVersion = "v3.8.7"

const pluginName = "kustomize.common." + plugins.DefaultNameQualifier

var (
Expand Down
2 changes: 2 additions & 0 deletions pkg/plugins/common/kustomize/v2/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *
subcmdMeta.Description = `Initialize a common project including the following files:
- a "PROJECT" file that stores project configuration
- several YAML files for project deployment under the "config" directory
NOTE: This plugin requires kustomize version v4 and kubectl >= 1.22.
`
subcmdMeta.Examples = fmt.Sprintf(` # Initialize a common project with your domain and name in copyright
%[1]s init --plugins common/v3 --domain example.org
Expand Down
3 changes: 3 additions & 0 deletions pkg/plugins/common/kustomize/v2/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import (
"sigs.k8s.io/kubebuilder/v3/pkg/plugins"
)

// KustomizeVersion is the kubernetes-sigs/kustomize version to be used in the project
const KustomizeVersion = "v4.4.1"

const pluginName = "kustomize.common." + plugins.DefaultNameQualifier

var (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,33 +89,95 @@ patchesStrategicMerge:
# 'CERTMANAGER' needs to be enabled to use ca injection
#- webhookcainjection_patch.yaml
# the following config is for teaching kustomize how to do var substitution
vars:
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix.
#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
# objref:
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # this name should match the one in certificate.yaml
# fieldref:
# fieldpath: metadata.namespace
#- name: CERTIFICATE_NAME
# objref:
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # this name should match the one in certificate.yaml
#- name: SERVICE_NAMESPACE # namespace of the service
# objref:
# kind: Service
# version: v1
# name: webhook-service
# fieldref:
# fieldpath: metadata.namespace
#- name: SERVICE_NAME
# objref:
# kind: Service
# version: v1
# name: webhook-service
# Uncomment the following replacements to add the cert-manager CA injection annotations
#replacements:
# - source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # this name should match the one in certificate.yaml
# fieldPath: .metadata.namespace # namespace of the certificate CR
# targets:
# - select:
# kind: ValidatingWebhookConfiguration
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 0
# - select:
# kind: MutatingWebhookConfiguration
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 0
# - select:
# kind: CustomResourceDefinition
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 0
# - source:
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # this name should match the one in certificate.yaml
# fieldPath: .metadata.name
# targets:
# - select:
# kind: ValidatingWebhookConfiguration
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 1
# - select:
# kind: MutatingWebhookConfiguration
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 1
# - select:
# kind: CustomResourceDefinition
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 1
# - source: # Add cert-manager annotation to the webhook Service
# kind: Service
# version: v1
# name: webhook-service
# fieldPath: .metadata.name # namespace of the service
# targets:
# - select:
# kind: Certificate
# group: cert-manager.io
# version: v1
# fieldPaths:
# - .spec.dnsNames.0
# - .spec.dnsNames.1
# options:
# delimiter: '.'
# index: 0
# - source:
# kind: Service
# version: v1
# name: webhook-service
# fieldPath: .metadata.namespace # namespace of the service
# targets:
# - select:
# kind: Certificate
# group: cert-manager.io
# version: v1
# fieldPaths:
# - .spec.dnsNames.0
# - .spec.dnsNames.1
# options:
# delimiter: '.'
# index: 1
`
23 changes: 20 additions & 3 deletions pkg/plugins/golang/v3/scaffolds/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ package scaffolds
import (
"fmt"

"sigs.k8s.io/kubebuilder/v3/pkg/plugin"

"github.com/spf13/afero"

"sigs.k8s.io/kubebuilder/v3/pkg/config"
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins"
kustomizecommonv1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v1"
kustomizecommonv2 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/hack"
)
Expand All @@ -33,14 +37,14 @@ const (
ControllerRuntimeVersion = "v0.11.0"
// ControllerToolsVersion is the kubernetes-sigs/controller-tools version to be used in the project
ControllerToolsVersion = "v0.8.0"
// KustomizeVersion is the kubernetes-sigs/kustomize version to be used in the project
KustomizeVersion = "v3.8.7"

imageName = "controller:latest"
)

var _ plugins.Scaffolder = &initScaffolder{}

var kustomizeVersion string

type initScaffolder struct {
config config.Config
boilerplatePath string
Expand Down Expand Up @@ -97,6 +101,19 @@ func (s *initScaffolder) Scaffold() error {
machinery.WithBoilerplate(string(boilerplate)),
)

// If the KustomizeV2 was used to do the scaffold then
// we need to ensure that we use its supported Kustomize Version
// in order to support it
kustomizeVersion = kustomizecommonv1.KustomizeVersion
kustomizev2 := kustomizecommonv2.Plugin{}
pluginKeyForKustomizeV2 := plugin.KeyFor(kustomizev2)
if err := s.config.EncodePluginConfig(pluginKeyForKustomizeV2, struct{}{}); err == nil {
kustomizeVersion = kustomizecommonv2.KustomizeVersion
fmt.Println(kustomizeVersion)
} else {
fmt.Println(err)
}
fmt.Println(kustomizeVersion)
return scaffold.Execute(
&templates.Main{},
&templates.GoMod{
Expand All @@ -107,7 +124,7 @@ func (s *initScaffolder) Scaffold() error {
Image: imageName,
BoilerplatePath: s.boilerplatePath,
ControllerToolsVersion: ControllerToolsVersion,
KustomizeVersion: KustomizeVersion,
KustomizeVersion: kustomizeVersion,
ControllerRuntimeVersion: ControllerRuntimeVersion,
},
&templates.Dockerfile{},
Expand Down
Loading

0 comments on commit b5c6838

Please sign in to comment.