Skip to content

Commit 6a23847

Browse files
authored
Merge pull request #2115 from camilamacedo86/doc-plugin
📖 plugins doc
2 parents 3748512 + 7855372 commit 6a23847

File tree

10 files changed

+415
-258
lines changed

10 files changed

+415
-258
lines changed

VERSIONING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,4 @@ to plugin `go.kubebuilder.io`, and can only be merged into plugin version `v3-al
103103
This plugin's package should exist already.
104104

105105
[kb-releases]:https://github.com/kubernetes-sigs/kubebuilder/releases
106-
[cli-plugins-versioning]:docs/book/src/reference/cli-plugins.md
106+
[cli-plugins-versioning]:docs/book/src/plugins/cli-plugins.md

docs/book/src/SUMMARY.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,17 @@
9494

9595
- [Metrics](./reference/metrics.md)
9696
- [Makefile Helpers](./reference/makefile-helpers.md)
97-
- [CLI Plugins](./reference/cli-plugins.md)
97+
- [Project config](./reference/project-config.md)
9898

9999
---
100100

101+
- [Plugins][plugins]
102+
103+
- [Extending the CLI](./plugins/extending-cli.md)
104+
- [Creating your own plugins](./plugins/creating-plugins.md)
105+
106+
---
101107
[Appendix: The TODO Landing Page](./TODO.md)
108+
109+
110+
[plugins]: ./plugins/plugins.md

docs/book/src/migration/manually_migration_guide_v2_v3.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ The default plugin layout which is equivalent to the previous version is `go.kub
4343

4444
```yaml
4545
...
46-
layout: go.kubebuilder.io/v2
46+
layout:
47+
- go.kubebuilder.io/v2
4748
...
4849
```
4950

@@ -221,7 +222,8 @@ For the QuickStart example, the `PROJECT` file manually updated to use `go.kubeb
221222

222223
```yaml
223224
domain: my.domain
224-
layout: go.kubebuilder.io/v2
225+
layout:
226+
- go.kubebuilder.io/v2
225227
projectName: example
226228
repo: example
227229
resources:
@@ -261,7 +263,8 @@ version: "2"
261263

262264
```yaml
263265
domain: testproject.org
264-
layout: go.kubebuilder.io/v2
266+
layout:
267+
- go.kubebuilder.io/v2
265268
projectName: example
266269
repo: sigs.k8s.io/kubebuilder/example
267270
resources:
@@ -338,7 +341,8 @@ Before updating the `layout`, please ensure you have followed the above steps to
338341

339342
```yaml
340343
domain: my.domain
341-
layout: go.kubebuilder.io/v3
344+
layout:
345+
- go.kubebuilder.io/v3
342346
...
343347
```
344348

docs/book/src/migration/v2vsv3.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ v3 projects use Go modules and request Go 1.15+. Dep is no longer supported for
1313

1414
## Kubebuilder
1515

16-
- Preliminary support for plugins was added. For more info see the [Extensible CLI and Scaffolding Plugins][plugins-phase1-design-doc].
16+
- Preliminary support for plugins was added. For more info see the [Extensible CLI and Scaffolding Plugins: phase 1][plugins-phase1-design-doc] and [Extensible CLI and Scaffolding Plugins: phase 1.5][plugins-phase1-design-doc-1.5]
1717

1818
- The `PROJECT` file now has a new layout. It stores more information about what resources are in use, to better enable plugins to make useful decisions when scaffolding.
1919

@@ -73,6 +73,7 @@ You will check that you can still using the previous layout by using the `go/v2`
7373
- [Migrating to Kubebuilder v3 by updating the files manually][manually-upgrade]
7474

7575
[plugins-phase1-design-doc]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/extensible-cli-and-scaffolding-plugins-phase-1.md
76+
[plugins-phase1-design-doc-1.5]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/extensible-cli-and-scaffolding-plugins-phase-1-5.md
7677
[manually-upgrade]: manually_migration_guide_v2_v3.md
7778
[component-config-tutorial]: ../component-config-tutorial/tutorial.md
7879
[issue-1893]: https://github.com/kubernetes-sigs/kubebuilder/issues/1839
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Creating your own plugins
2+
3+
## Overview
4+
5+
You can extend the Kubebuilder API to create your own plugins. If [extending the CLI][extending-cli], your plugin will be implemented in your project and registered to the CLI as has been done by the [SDK][sdk] project. See its [cli code][sdk-cli-pkg] as an example.
6+
7+
## Language-based Plugins
8+
9+
Kubebuilder offers the Golang-based operator plugins, which will help its CLI tool users create projects following the [Operator Pattern][operator-pattern].
10+
11+
The [SDK][sdk] project, for example, has language plugins for [Ansible][sdk-ansible] and [Helm][sdk-helm], which are similar options but for users who would like to work with these respective languages and stacks instead of Golang.
12+
13+
Note that Kubebuilder provides the `kustomize.common.kubebuilder.io` to help in these efforts. This plugin will scaffold the common base without any specific language scaffold file to allow you to extend the Kubebuilder style for your plugins.
14+
15+
In this way, currently, you can [Extend the CLI][extending-cli] and use the `Bundle Plugin` to create your language plugins such as:
16+
17+
```go
18+
mylanguagev1Bundle, _ := plugin.NewBundle(language.DefaultNameQualifier, plugin.Version{Number: 1},
19+
kustomizecommonv1.Plugin{}, // extend the common base from Kuebebuilder
20+
mylanguagev1.Plugin{}, // your plugin language which will do the scaffolds for the specific language on top of the common base
21+
)
22+
```
23+
24+
If you do not want to develop your plugin using Golang, you can follow its standard by using the binary as follows:
25+
26+
```sh
27+
kubebuilder init --plugins=kustomize
28+
```
29+
30+
Then you can, for example, create your implementations for the sub-commands `create api` and `create webhook` using your language of preference.
31+
32+
<aside class="note">
33+
<h1>Why use the Kubebuilder style?</h1>
34+
35+
Kubebuilder and SDK are both broadly adopted projects which leverage the [controller-runtime][controller-runtime] project. They both allow users to build solutions using the [Operator Pattern][operator-pattern] and follow common standards.
36+
37+
Adopting these standards can bring significant benefits, such as joining forces on maintaining the common standards as the features provided by Kubebuilder and take advantage of the contributions made by the community. This allows you to focus on the specific needs and requirements for your plugin and use-case.
38+
39+
And then, you will also be able to use custom plugins and options currently or in the future which might to be provided by these projects as any other which decides to persuade the same standards.
40+
41+
</aside>
42+
43+
## Custom Plugins
44+
45+
Note that users are also able to use plugins to customize their scaffold and address specific needs. See that Kubebuilder provides the [declarative][declarative-code] plugin which can be used when for example an API is scaffold:
46+
47+
```sh
48+
kubebuider create api [options] --plugins=go/v3,declarative/v1
49+
```
50+
51+
This plugin will perform a custom scaffold using the [kubebuilder declarative pattern][kubebuilder-declarative-pattern].
52+
53+
In this way, by [Extending the Kubebuilder CLI][extending-cli], you can also create custom plugins such this one. Feel free to check its implementation in [`pkg/plugins/golang/declarative`][declarative-code].
54+
55+
## Future vision for Kubebuilder Plugins
56+
57+
As the next steps for the plugins, its possible to highlight three initiatives so far, which are:
58+
59+
- [Plugin phase 2.0][plugin-2.0]: allow the Kubebuilder CLI or any other CLI, which is [Extending the Kubebuilder CLI][extending-cli], to discover external plugins, in this way, allow the users to use these external options as helpers to perform the scaffolds with the tool.
60+
- [Config-gen][config-gen]: the config-gen option has been provided as an alpha option in the Kubebuilder CLI(`kubebuilder alpha config-gen`) to encourage its contributions. The idea of this option would simplify the config scaffold. For further information see its [README][config-gen-readme].
61+
- [New Plugin (`deploy-image.go.kubebuilder.io/v1beta1`) to generate code][new-plugin-gen]: its purpose is to provide an arch-type that will scaffold the APIs and Controllers with the required code to deploy and manage solutions on the cluster.
62+
63+
Please, feel to contribute with them as well. Your contribution to the project is very welcome.
64+
65+
[sdk-cli-pkg]: https://github.com/operator-framework/operator-sdk/blob/master/internal/cmd/operator-sdk/cli/cli.go
66+
[sdk-ansible]: https://github.com/operator-framework/operator-sdk/tree/master/internal/plugins/ansible/v1
67+
[sdk-helm]: https://github.com/operator-framework/operator-sdk/tree/master/internal/plugins/helm/v1
68+
[operator-pattern]: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/
69+
[controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime
70+
[plugin-2.0]: https://github.com/kubernetes-sigs/kubebuilder/issues/1378
71+
[config-gen-readme]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/cli/alpha/config-gen/README.md
72+
[config-gen]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/cli/alpha/config-gen
73+
[plugins-phase1-design-doc-1.5]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/extensible-cli-and-scaffolding-plugins-phase-1-5.md
74+
[extending-cli]: extending-cli.md
75+
[new-plugin-gen]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/code-generate-image-plugin.md
76+
[kubebuilder-declarative-pattern]: https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern
77+
[declarative-code]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/plugins/golang/declarative
78+
[sdk]: https://github.com/operator-framework/operator-sdk
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# Extending the CLI and Scaffolds
2+
3+
## Overview
4+
5+
You can extend Kubebuilder to allow your project to have the same CLI features and provide the plugins scaffolds.
6+
7+
## CLI system
8+
9+
Plugins are run using a [`CLI`][cli] object, which maps a plugin type to a subcommand and calls that plugin's methods.
10+
For example, writing a program that injects an `Init` plugin into a `CLI` then calling `CLI.Run()` will call the
11+
plugin's [SubcommandMetadata][plugin-sub-command], [UpdatesMetadata][plugin-update-meta] and `Run` methods with information a user has passed to the
12+
program in `kubebuilder init`. Following an example:
13+
14+
```go
15+
package cli
16+
17+
import (
18+
log "github.com/sirupsen/logrus"
19+
"github.com/spf13/cobra"
20+
21+
"sigs.k8s.io/kubebuilder/v3/pkg/cli"
22+
cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3"
23+
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
24+
kustomizecommonv1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v1"
25+
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang"
26+
declarativev1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/declarative/v1"
27+
golangv3 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3"
28+
29+
)
30+
31+
var (
32+
// The following is an example of the commands
33+
// that you might have in your own binary
34+
commands = []*cobra.Command{
35+
myExampleCommand.NewCmd(),
36+
}
37+
alphaCommands = []*cobra.Command{
38+
myExampleAlphaCommand.NewCmd(),
39+
}
40+
)
41+
42+
// GetPluginsCLI returns the plugins based CLI configured to be used in your CLI binary
43+
func GetPluginsCLI() (*cli.CLI) {
44+
// Bundle plugin which built the golang projects scaffold by Kubebuilder go/v3
45+
gov3Bundle, _ := plugin.NewBundle(golang.DefaultNameQualifier, plugin.Version{Number: 3},
46+
kustomizecommonv1.Plugin{},
47+
golangv3.Plugin{},
48+
)
49+
50+
51+
c, err := cli.New(
52+
// Add the name of your CLI binary
53+
cli.WithCommandName("example-cli"),
54+
55+
// Add the version of your CLI binary
56+
cli.WithVersion(versionString()),
57+
58+
// Register the plugins options which can be used to do the scaffolds via your CLI tool. See that we are using as example here the plugins which are implemented and provided by Kubebuilder
59+
cli.WithPlugins(
60+
gov3Bundle,
61+
&declarativev1.Plugin{},
62+
),
63+
64+
// Defines what will be the default plugin used by your binary. It means that will be the plugin used if no info be provided such as when the user runs `kubebuilder init`
65+
cli.WithDefaultPlugins(cfgv3.Version, gov3Bundle),
66+
67+
// Define the default project configuration version which will be used by the CLI when none is informed by --project-version flag.
68+
cli.WithDefaultProjectVersion(cfgv3.Version),
69+
70+
// Adds your own commands to the CLI
71+
cli.WithExtraCommands(commands...),
72+
73+
// Add your own alpha commands to the CLI
74+
cli.WithExtraAlphaCommands(alphaCommands...),
75+
76+
// Adds the completion option for your CLI
77+
cli.WithCompletion(),
78+
)
79+
if err != nil {
80+
log.Fatal(err)
81+
}
82+
83+
return c
84+
}
85+
86+
// versionString returns the CLI version
87+
func versionString() string {
88+
// return your binary project version
89+
}
90+
```
91+
92+
This program can then be built and run in the following ways:
93+
94+
Default behavior:
95+
96+
```sh
97+
# Initialize a project with the default Init plugin, "go.example.com/v1".
98+
# This key is automatically written to a PROJECT config file.
99+
$ my-bin-builder init
100+
# Create an API and webhook with "go.example.com/v1" CreateAPI and
101+
# CreateWebhook plugin methods. This key was read from the config file.
102+
$ my-bin-builder create api [flags]
103+
$ my-bin-builder create webhook [flags]
104+
```
105+
106+
Selecting a plugin using `--plugins`:
107+
108+
```sh
109+
# Initialize a project with the "ansible.example.com/v1" Init plugin.
110+
# Like above, this key is written to a config file.
111+
$ my-bin-builder init --plugins ansible
112+
# Create an API and webhook with "ansible.example.com/v1" CreateAPI
113+
# and CreateWebhook plugin methods. This key was read from the config file.
114+
$ my-bin-builder create api [flags]
115+
$ my-bin-builder create webhook [flags]
116+
```
117+
118+
### CLI manages the PROJECT file
119+
120+
The CLI is responsible for managing the [PROJECT file config][project-file-config], representing the configuration of the projects that are scaffold by the CLI tool.
121+
122+
## Plugins
123+
124+
Kubebuilder provides scaffolding options via plugins. Plugins are responsible for implementing the code that will be executed when the sub-commands are called. You can create a new plugin by implementing the [Plugin interface][plugin-interface].
125+
126+
On top of being a `Base`, a plugin should also implement the [`SubcommandMetadata`][plugin-subc] interface so it can be run with a CLI. It optionally to set custom help text for the target command; this method can be a no-op, which will preserve the default help text set by the [cobra][cobra] command constructors.
127+
128+
Kubebuilder CLI plugins wrap scaffolding and CLI features in conveniently packaged Go types that are executed by the
129+
`kubebuilder` binary, or any binary which imports them. More specifically, a plugin configures the execution of one
130+
of the following CLI commands:
131+
132+
- `init`: project initialization.
133+
- `create api`: scaffold Kubernetes API definitions.
134+
- `create webhook`: scaffold Kubernetes webhooks.
135+
136+
Plugins are identified by a key of the form `<name>/<version>`. There are two ways to specify a plugin to run:
137+
138+
- Setting `kubebuilder init --plugins=<plugin key>`, which will initialize a project configured for plugin with key
139+
`<plugin key>`.
140+
141+
- A `layout: <plugin key>` in the scaffolded [PROJECT configuration file][project-file]. Commands (except for `init`, which scaffolds this file) will look at this value before running to choose which plugin to run.
142+
143+
By default, `<plugin key>` will be `go.kubebuilder.io/vX`, where `X` is some integer.
144+
145+
For a full implementation example, check out Kubebuilder's native [`go.kubebuilder.io`][kb-go-plugin] plugin.
146+
147+
### Plugin naming
148+
149+
Plugin names must be DNS1123 labels and should be fully qualified, i.e. they have a suffix like
150+
`.example.com`. For example, the base Go scaffold used with `kubebuilder` commands has name `go.kubebuilder.io`.
151+
Qualified names prevent conflicts between plugin names; both `go.kubebuilder.io` and `go.example.com` can both scaffold
152+
Go code and can be specified by a user.
153+
154+
### Plugin versioning
155+
156+
A plugin's `Version()` method returns a [`plugin.Version`][plugin-version-type] object containing an integer value
157+
and optionally a stage string of either "alpha" or "beta". The integer denotes the current version of a plugin.
158+
Two different integer values between versions of plugins indicate that the two plugins are incompatible. The stage
159+
string denotes plugin stability:
160+
161+
- `alpha`: should be used for plugins that are frequently changed and may break between uses.
162+
- `beta`: should be used for plugins that are only changed in minor ways, ex. bug fixes.
163+
164+
### Breaking changes
165+
166+
Any change that will break a project scaffolded by the previous plugin version is a breaking change.
167+
168+
### Plugins Deprecation
169+
170+
Once a plugin is deprecated, have it implement a [Deprecated][deprecate-plugin-doc] interface so a deprecation warning will be printed when it is used.
171+
172+
## Bundle Plugins
173+
174+
[Bundle Plugins][bundle-plugin-doc] allow you to create a plugin that is a composition of many plugins:
175+
176+
```go
177+
// see that will be like myplugin.example/v1`
178+
myPluginBundle, _ := plugin.NewBundle(`<plugin-name>`,`<plugin-version>`,
179+
pluginA.Plugin{},
180+
pluginB.Plugin{},
181+
pluginC.Plugin{},
182+
)
183+
184+
```
185+
186+
Note that it means that when a user of your CLI calls this plugin, the execution of the sub-commands will be sorted by the order to which they were added in a chain:
187+
188+
189+
> sub-command of plugin A -> sub-command of plugin B -> sub-command of plugin C
190+
191+
Then, to initialize using this "Plugin Bundle" which will run the chain of plugins:
192+
193+
```
194+
kubebuider init --plugins=myplugin.example/v1
195+
```
196+
197+
- Runs init sub-command of the plugin A
198+
- And then, runs init sub-command of the plugin B
199+
- And then, runs init sub-command of the plugin C
200+
201+
[project-file-config]: ../reference/project-config.md
202+
[plugin-interface]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#Plugin
203+
[go-dev-doc]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3
204+
[plugin-sub-command]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#Subcommand
205+
[project-file]: ../reference/project-config.md
206+
[plugin-subc]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#Subcommand
207+
[cobra]:https://pkg.go.dev/github.com/spf13/cobra
208+
[kb-go-plugin]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3
209+
[bundle-plugin-doc]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#Bundle
210+
[deprecate-plugin-doc]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#Deprecated
211+
[plugin-update-meta]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#UpdatesMetadata
212+
[cli]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/cli
213+
[plugin-version-type]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#Version

0 commit comments

Comments
 (0)