Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ add kustomize/v2-alpha plugin to support kustomize versions >= v4 (pinned version 4.5.3) #2583

Merged
merged 1 commit into from
May 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
"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 Down Expand Up @@ -57,6 +58,7 @@ func main() {
golangv3.Plugin{},
gov3Bundle,
&kustomizecommonv1.Plugin{},
&kustomizecommonv2.Plugin{},
&declarativev1.Plugin{},
),
cli.WithPlugins(externalPlugins...),
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 @@ -8,6 +8,7 @@ This section describes the plugins supported and shipped in with the Kubebuilder
| [go.kubebuilder.io/v2](go-v2-plugin.md) | `go/v2` | Golang plugin responsible for scaffold the legacy layout provided with Kubebuilder CLI >= `2.0.0` and < `3.0.0`. |
| [declarative.go.kubebuilder.io/v1](declarative-v1.md) | `declarative/v1` | Optional plugin used to scaffold APIs/controllers using the [kubebuilder-declarative-pattern][kubebuilder-declarative-pattern] project. |
| [kustomize.common.kubebuilder.io/v1](kustomize-v1.md) | `kustomize/v1` | Responsible for scaffold all manifests to configure the projects with [kustomize(v3)][kustomize]. (create and update the the `config/` directory). This plugin is used in the composition to create the plugin (`go/v3`). |
| [kustomize.common.kubebuilder.io/v1](kustomize-v2-alpha.md) | `kustomize/v2-alpha` | It has the same purpose of `kustomize/v1`. However, it works with [kustomize][kustomize] version `v4` and address the required changes for the future kustomize configurations. It will probably be used with the future `go/v4-alpha` plugin. |
| `base.go.kubebuilder.io/v3` | `base/v3` | Responsible for scaffold all files which specific requires Golang. This plugin is used in the composition to create the plugin (`go/v3`) |

<aside class="note">
Expand All @@ -20,4 +21,4 @@ This section describes the plugins supported and shipped in with the Kubebuilder

[create-plugins]: creating-plugins.md
[kubebuilder-declarative-pattern]: https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern
[kustomize]: https://kustomize.io/
[kustomize]: https://kustomize.io/
2 changes: 1 addition & 1 deletion docs/book/src/plugins/kustomize-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ If you are looking to scaffold the kustomize configuration manifests for your ow
## 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
to specify that your language plugin is a composition with your plugin responsible for scaffold
all that is laguage specific and kustomize for its configuration, see:

```go
Expand Down
118 changes: 118 additions & 0 deletions docs/book/src/plugins/kustomize-v2-alpha.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Kustomize v2-alpha

Copy link
Member Author

@camilamacedo86 camilamacedo86 Mar 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See here the documentation to better understand it.
Note that after we have this plugin, tools such as SDK (which provides many language plugins) will also be able to allow its users to try out kustomize v4 and support the new mac arch, doing things like:

operator-sdk init --plugins=kustomize/v2-alpha,base.operatorframework.helm.sdk/v1

Then, we can provide all support and advantages to the users without introducing breaking changes.
So that, when the plugins become mature and we no longer need to support k8s versions < 1.22 then we might want to have new languages plugins that adopt them by default.

c/c @jmrodri

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

Note that projects such as [Operator-sdk][sdk] consume the Kubebuilder project as a lib and provide options to work with other languages
like Ansible and Helm. The kustomize plugin allows them to easily keep a maintained configuration and ensure that all languages have
the same configuration. It is also helpful if you are looking to provide nice plugins which will perform changes on top of
what is scaffolded by default. With this approach we do not need to keep manually updating this configuration in all possible language plugins
which uses the same and we are also
able to create "helper" plugins which can work with many projects and languages.

<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 responsible 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, with Kubebuilder, you can use kustomize/v2-alpha alone via:

```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 scaffold the kustomize manifests
which are specific for each API, see [here][kustomize-create-api]. 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
9 changes: 9 additions & 0 deletions docs/book/src/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ cd ~/projects/guestbook
kubebuilder init --domain my.domain --repo my.domain/guestbook
```

<aside class="note">
<h1>Supportability (Apple Silicon `arm64`)</h1>

If you are using Apple Silicon (`arm64`) you probably want try initialize the project with
`kubebuilder init --plugins=kustomize/v2-alpha,base.go.kubebuilder.io/v3` instead. [More Info][more-info]

</aside>

<aside class="note">
<h1>Developing in $GOPATH</h1>

Expand Down Expand Up @@ -238,3 +246,4 @@ Now, see the [architecture concept diagram][architecture-concept-diagram] for a
[go-modules-blogpost]: https://blog.golang.org/using-go-modules
[envtest]: https://book.kubebuilder.io/reference/testing/envtest.html
[architecture-concept-diagram]: architecture.md
[more-info]: plugins/kustomize-v2-alpha.md
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"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The kustomize version supported by the Kustomize plugin must leave in the Kustomize plugin. Otherwise, we are hurting concepts like single responsibility and cohesion.

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

var (
Expand Down
38 changes: 38 additions & 0 deletions pkg/plugins/common/kustomize/v2/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
Copyright 2022 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 (
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds"
)

var _ plugin.CreateAPISubcommand = &createAPISubcommand{}

type createAPISubcommand struct {
createSubcommand
}

func (p *createAPISubcommand) Scaffold(fs machinery.Filesystem) error {
if err := p.configure(); err != nil {
return err
}
scaffolder := scaffolds.NewAPIScaffolder(p.config, *p.resource, p.force)
scaffolder.InjectFS(fs)
return scaffolder.Scaffold()
}
58 changes: 58 additions & 0 deletions pkg/plugins/common/kustomize/v2/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
Copyright 2022 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 (
"strconv"

"github.com/spf13/pflag"

"sigs.k8s.io/kubebuilder/v3/pkg/config"
"sigs.k8s.io/kubebuilder/v3/pkg/model/resource"
)

type createSubcommand struct {
config config.Config
resource *resource.Resource

flagSet *pflag.FlagSet

// force indicates whether to scaffold files even if they exist.
force bool
}

func (p *createSubcommand) BindFlags(fs *pflag.FlagSet) { p.flagSet = fs }

func (p *createSubcommand) InjectConfig(c config.Config) error {
p.config = c
return nil
}

func (p *createSubcommand) InjectResource(res *resource.Resource) error {
p.resource = res
return nil
}

func (p *createSubcommand) configure() (err error) {
if forceFlag := p.flagSet.Lookup("force"); forceFlag != nil {
if p.force, err = strconv.ParseBool(forceFlag.Value.String()); err != nil {
return err
}

}
return nil
}
103 changes: 103 additions & 0 deletions pkg/plugins/common/kustomize/v2/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
Copyright 2022 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 (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/spf13/pflag"

"sigs.k8s.io/kubebuilder/v3/pkg/config"
"sigs.k8s.io/kubebuilder/v3/pkg/internal/validation"
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds"
)

var _ plugin.InitSubcommand = &initSubcommand{}

type initSubcommand struct {
config config.Config

// config options
domain string
name string
componentConfig bool
}

func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) {
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

# Initialize a common project defining a specific project version
%[1]s init --plugins common/v3 --project-version 3
`, cliMeta.CommandName)
}

func (p *initSubcommand) BindFlags(fs *pflag.FlagSet) {
fs.StringVar(&p.domain, "domain", "my.domain", "domain for groups")
fs.StringVar(&p.name, "project-name", "", "name of this project")
fs.BoolVar(&p.componentConfig, "component-config", false,
"create a versioned ComponentConfig file, may be 'true' or 'false'")
}

func (p *initSubcommand) InjectConfig(c config.Config) error {
p.config = c

if err := p.config.SetDomain(p.domain); err != nil {
return err
}

// Assign a default project name
if p.name == "" {
dir, err := os.Getwd()
if err != nil {
return fmt.Errorf("error getting current directory: %v", err)
}
p.name = strings.ToLower(filepath.Base(dir))
}
// Check if the project name is a valid k8s namespace (DNS 1123 label).
if err := validation.IsDNS1123Label(p.name); err != nil {
return fmt.Errorf("project name (%s) is invalid: %v", p.name, err)
}
if err := p.config.SetProjectName(p.name); err != nil {
return err
}

if p.componentConfig {
if err := p.config.SetComponentConfig(); err != nil {
return err
}
}

return nil
}

func (p *initSubcommand) Scaffold(fs machinery.Filesystem) error {
scaffolder := scaffolds.NewInitScaffolder(p.config)
scaffolder.InjectFS(fs)
return scaffolder.Scaffold()
}
Loading