Skip to content

Commit

Permalink
Add the rest of the missing fields and stabilize config v3
Browse files Browse the repository at this point in the history
Signed-off-by: Adrian Orive Oneca <adrian.orive.oneca@gmail.com>
  • Loading branch information
Adirio committed Jan 26, 2021
1 parent 7b84f60 commit 9797cf5
Show file tree
Hide file tree
Showing 20 changed files with 273 additions and 189 deletions.
21 changes: 10 additions & 11 deletions VERSIONING.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ take care of building and publishing the artifacts.
| Name | Example | Description |
|--- |--- |--- |
| KubeBuilder version | `v2.2.0`, `v2.3.0`, `v2.3.1` | Tagged versions of the KubeBuilder project, representing changes to the source code in this repository. See the [releases][kb-releases] page for binary releases. |
| Project version | `"1"`, `"2"`, `"3-alpha"` | Project version defines the scheme of a `PROJECT` configuration file. This version is defined in a `PROJECT` file's `version`. |
| Plugin version | `v2`, `v3-alpha` | Represents the version of an individual plugin, as well as the corresponding scaffolding that it generates. This version is defined in a plugin key, ex. `go.kubebuilder.io/v2`. See the [design doc][cli-plugins-versioning] for more details. |
| Project version | `"1"`, `"2"`, `"3"` | Project version defines the scheme of a `PROJECT` configuration file. This version is defined in a `PROJECT` file's `version`. |
| Plugin version | `v2`, `v3` | Represents the version of an individual plugin, as well as the corresponding scaffolding that it generates. This version is defined in a plugin key, ex. `go.kubebuilder.io/v2`. See the [design doc][cli-plugins-versioning] for more details. |

### Incrementing versions

Expand All @@ -76,32 +76,31 @@ Project versions should only be increased if a breaking change is introduced in
Similarly, the introduction of a new plugin version might only lead to a new minor version release of KubeBuilder, since no breaking change is being made to the CLI itself. It'd only be a breaking change to KubeBuilder if we remove support for an older plugin version. See the plugins design doc [versioning section][cli-plugins-versioning]
for more details on plugin versioning.

**NOTE:** the scheme for project version `"2"` was defined before the concept of plugins was introduced, so plugin `go.kubebuilder.io/v2` is implicitly used for those project types. Schema for project versions `"3-alpha"` and beyond define a `layout` key that informs the plugin system of which plugin to use.
**NOTE:** the scheme for project version `"2"` was defined before the concept of plugins was introduced, so plugin `go.kubebuilder.io/v2` is implicitly used for those project types. Schema for project versions `"3"` and beyond define a `layout` key that informs the plugin system of which plugin to use.

## Introducing changes to plugins

Changes made to plugins only require a plugin version increase if and only if a change is made to a plugin
that breaks projects scaffolded with the previous plugin version. Once a plugin version `vX` is stabilized (it doesn't
have an "alpha" or "beta" suffix), a new plugin package should be created containing a new plugin with version
`v(X+1)-alpha`. Typically this is done by (semantically) `cp -r pkg/plugin/vX pkg/plugin/v(X+1)` then updating
`v(X+1)-alpha`. Typically this is done by (semantically) `cp -r pkg/plugins/golang/vX pkg/plugins/golang/v(X+1)` then updating
version numbers and paths. All further breaking changes to the plugin should be made in this package; the `vX`
plugin would then be frozen to breaking changes.

You must also add a migration guide to the [migrations](https://book.kubebuilder.io/migrations.html)
section of the KubeBuilder book in your PR. It should detail the steps required
for users to upgrade their projects from `vX` to `v(X+1)-alpha`.

### Example

KubeBuilder scaffolds projects with plugin `go.kubebuilder.io/v2` by default. A `v3-alpha` version
was created after `v2` stabilized.
KubeBuilder scaffolds projects with plugin `go.kubebuilder.io/v3` by default.

You create a feature that adds a new marker to the file `main.go` scaffolded by `init`
that `create api` will use to update that file. The changes introduced in your feature
would cause errors if used with projects built with plugins `go.kubebuilder.io/v2`
without users manually updating their projects. Thus, your changes introduce a breaking change
to plugin `go.kubebuilder.io`, and can only be merged into plugin version `v3-alpha`.
This plugin's package should exist already, so a PR must be made against the

You must also add a migration guide to the [migrations](https://book.kubebuilder.io/migrations.html)
section of the KubeBuilder book in your PR. It should detail the steps required
for users to upgrade their projects from `v2` to `v3-alpha`.
This plugin's package should exist already.

[kb-releases]:https://github.com/kubernetes-sigs/kubebuilder/releases
[cli-plugins-versioning]:docs/book/src/reference/cli-plugins.md
6 changes: 3 additions & 3 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (

"sigs.k8s.io/kubebuilder/v3/pkg/cli"
cfgv2 "sigs.k8s.io/kubebuilder/v3/pkg/config/v2"
cfgv3alpha "sigs.k8s.io/kubebuilder/v3/pkg/config/v3alpha"
cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3"
pluginv2 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2"
pluginv3 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3"
)
Expand All @@ -30,13 +30,13 @@ func main() {
c, err := cli.New(
cli.WithCommandName("kubebuilder"),
cli.WithVersion(versionString()),
cli.WithDefaultProjectVersion(cfgv3alpha.Version),
cli.WithDefaultProjectVersion(cfgv3.Version),
cli.WithPlugins(
&pluginv2.Plugin{},
&pluginv3.Plugin{},
),
cli.WithDefaultPlugins(cfgv2.Version, &pluginv2.Plugin{}),
cli.WithDefaultPlugins(cfgv3alpha.Version, &pluginv3.Plugin{}),
cli.WithDefaultPlugins(cfgv3.Version, &pluginv3.Plugin{}),
cli.WithCompletion,
)
if err != nil {
Expand Down
17 changes: 11 additions & 6 deletions docs/book/src/component-config-tutorial/testdata/project/PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@ multigroup: true
projectName: project
repo: tutorial.kubebuilder.io/project
resources:
- crdVersion: v1
- api:
crdVersion: v1
group: batch
kind: CronJob
version: v1
webhookVersion: v1
- crdVersion: v1
webhooks:
webhookVersion: v1
- api:
crdVersion: v1
group: batch
kind: CronJob
version: v2
webhookVersion: v1
- crdVersion: v1
webhooks:
webhookVersion: v1
- api:
crdVersion: v1
group: config
kind: ProjectConfig
version: v2
version: 3-alpha
version: "3"
38 changes: 6 additions & 32 deletions docs/book/src/migration/project/v2_v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ layout: go.kubebuilder.io/v2

- Update the `version`

The `version` field represents the version of Project layouts. So, you ought to update this to `3-alpha`:
The `version` field represents the version of Project layouts. So, you ought to update this to `"3"`:

```
...
version: 3-alpha`
version: "3"
...
```

Expand All @@ -58,7 +58,7 @@ resources:
- group: webapp
kind: Guestbook
version: v1
version: 3-alpha
version: "3"
```

### Verification
Expand All @@ -68,47 +68,21 @@ fine.

## Migrating your projects to use v3+ plugins

<aside class="note warning">

<h1>Note</h1>

`v3+` plugins are still in alpha phase and are not scaffolded by default. You are able to use them, try it out and get all improvements made so far by initializing projects with the arg `--plugins=go.kubebuilder.io/v3-alpha`:

```sh
kubebuilder init --domain my.domain --plugins=go.kubebuilder.io/v3-alpha
```

</aside>

<aside class="note warning">

<h1>Note</h1>

Currently, the plugin `v3-alpha` has NO breaking changes. However, until it is declared stable breaking changes can be made related to K8s API deprecations of `v1beta1` versions of `CustomResourceDefinition` and `ValidatingWebhookConfiguration` and to upgrade the `cert-manager`. More info:

- [cert-manager related configuration should be migrated to cert-manager.io/v1 #1666
](https://github.com/kubernetes-sigs/kubebuilder/issues/1666)
- [Set preserveUnknownFields to false in the CRD conversion webhook patch #933](https://github.com/kubernetes-sigs/kubebuilder/issues/933)
- [Migrate existing KB project to v1 CRDs and Webhooks with minimal user effort #1065
](https://github.com/kubernetes-sigs/kubebuilder/issues/1065)

</aside>

### Update your PROJECT file

Update the `layout` setting to the new plugin version ` go.kubebuilder.io/v3-alpha` as follows:
Update the `layout` setting to the new plugin version `go.kubebuilder.io/v3` as follows:

```sh
$ cat PROJECT
domain: my.domain
layout: go.kubebuilder.io/v3-alpha
layout: go.kubebuilder.io/v3
projectName: example
repo: example
resources:
- group: webapp
kind: Guestbook
version: v1
version: 3-alpha
version: "3"

```

Expand Down
4 changes: 2 additions & 2 deletions pkg/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (

internalconfig "sigs.k8s.io/kubebuilder/v3/pkg/cli/internal/config"
"sigs.k8s.io/kubebuilder/v3/pkg/config"
cfgv3alpha "sigs.k8s.io/kubebuilder/v3/pkg/config/v3alpha"
cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3"
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
)

Expand Down Expand Up @@ -131,7 +131,7 @@ func newCLI(opts ...Option) (*cli, error) {
// Default cli options.
c := &cli{
commandName: "kubebuilder",
defaultProjectVersion: cfgv3alpha.Version,
defaultProjectVersion: cfgv3.Version,
defaultPlugins: make(map[config.Version][]string),
plugins: make(map[string]plugin.Plugin),
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (

"sigs.k8s.io/kubebuilder/v3/pkg/config"
cfgv2 "sigs.k8s.io/kubebuilder/v3/pkg/config/v2"
cfgv3alpha "sigs.k8s.io/kubebuilder/v3/pkg/config/v3alpha"
cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3"
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
)

Expand Down Expand Up @@ -203,7 +203,7 @@ var _ = Describe("CLI", func() {

When("having layout field", func() {
It("should succeed", func() {
projectConfig = cfgv3alpha.New()
projectConfig = cfgv3.New()
Expect(projectConfig.SetLayout("go.kubebuilder.io/v2")).To(Succeed())
projectVersion, plugins, err = getInfoFromConfig(projectConfig)
Expect(err).NotTo(HaveOccurred())
Expand Down
20 changes: 9 additions & 11 deletions pkg/config/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,17 @@ type Config interface {
SetRepository(repository string) error

// GetProjectName returns the project name
// This method was introduced in project version 3-alpha.
// This method was introduced in project version 3.
GetProjectName() string
// SetProjectName sets the project name
// This method was introduced in project version 3-alpha.
// This method was introduced in project version 3.
SetProjectName(name string) error

// GetLayout returns the config layout
// This method was introduced in project version 3-alpha.
// This method was introduced in project version 3.
GetLayout() string
// SetLayout sets the Config layout
// This method was introduced in project version 3-alpha.
// This method was introduced in project version 3.
SetLayout(layout string) error

/* Boolean fields */
Expand All @@ -63,13 +63,13 @@ type Config interface {
ClearMultiGroup() error

// IsComponentConfig checks if component config is enabled
// This method was introduced in project version 3-alpha.
// This method was introduced in project version 3.
IsComponentConfig() bool
// SetComponentConfig enables component config
// This method was introduced in project version 3-alpha.
// This method was introduced in project version 3.
SetComponentConfig() error
// ClearComponentConfig disables component config
// This method was introduced in project version 3-alpha.
// This method was introduced in project version 3.
ClearComponentConfig() error

/* Resources */
Expand Down Expand Up @@ -97,12 +97,10 @@ type Config interface {
/* Plugins */

// DecodePluginConfig decodes a plugin config stored in Config into configObj, which must be a pointer.
// This method is intended to be used for custom configuration objects, which were introduced in project version
// 3-alpha.
// This method is intended to be used for custom configuration objects, which were introduced in project version 3.
DecodePluginConfig(key string, configObj interface{}) error
// EncodePluginConfig encodes a config object into Config by overwriting the existing object stored under key.
// This method is intended to be used for custom configuration objects, which were introduced in project version
// 3-alpha.
// This method is intended to be used for custom configuration objects, which were introduced in project version 3.
EncodePluginConfig(key string, configObj interface{}) error

/* Persistence */
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/v2/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ var _ = Describe("cfg", func() {
})
})

Context("Name", func() {
Context("ProjectName", func() {
It("GetProjectName should return an empty name", func() {
Expect(c.GetProjectName()).To(Equal(""))
})
Expand Down
54 changes: 27 additions & 27 deletions pkg/config/v3alpha/config.go → pkg/config/v3/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package v3alpha
package v3

import (
"fmt"
Expand All @@ -24,11 +24,10 @@ import (

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

// Version is the config.Version for project configuration 3-alpha
var Version = config.Version{Number: 3, Stage: stage.Alpha}
// Version is the config.Version for project configuration 3
var Version = config.Version{Number: 3}

type cfg struct {
// Version
Expand Down Expand Up @@ -157,8 +156,6 @@ func (c cfg) ResourcesLength() int {

// HasResource implements config.Config
func (c cfg) HasResource(gvk resource.GVK) bool {
gvk.Domain = "" // Version 3 alpha does not include domain per resource

for _, res := range c.Resources {
if gvk.IsEqualTo(res.GVK) {
return true
Expand All @@ -170,11 +167,16 @@ func (c cfg) HasResource(gvk resource.GVK) bool {

// GetResource implements config.Config
func (c cfg) GetResource(gvk resource.GVK) (resource.Resource, error) {
gvk.Domain = "" // Version 3 alpha does not include domain per resource

for _, res := range c.Resources {
if gvk.IsEqualTo(res.GVK) {
return res.Copy(), nil
r := res.Copy()

// Plural is only stored if irregular, so if it is empty recover the regular form
if r.Plural == "" {
r.Plural = resource.RegularPlural(r.Kind)
}

return r, nil
}
}

Expand All @@ -185,33 +187,28 @@ func (c cfg) GetResource(gvk resource.GVK) (resource.Resource, error) {
func (c cfg) GetResources() ([]resource.Resource, error) {
resources := make([]resource.Resource, 0, len(c.Resources))
for _, res := range c.Resources {
resources = append(resources, res.Copy())
}
r := res.Copy()

return resources, nil
}
// Plural is only stored if irregular, so if it is empty recover the regular form
if r.Plural == "" {
r.Plural = resource.RegularPlural(r.Kind)
}

func discardNonIncludedFields(res *resource.Resource) {
res.Domain = "" // Version 3 alpha does not include domain per resource
res.Plural = "" // Version 3 alpha does not include plural forms
res.Path = "" // Version 3 alpha does not include paths
if res.API != nil {
res.API.Namespaced = false // Version 3 alpha does not include if the api was namespaced
}
res.Controller = false // Version 3 alpha does not include if the controller was scaffolded
if res.Webhooks != nil {
res.Webhooks.Defaulting = false // Version 3 alpha does not include if the defaulting webhook was scaffolded
res.Webhooks.Validation = false // Version 3 alpha does not include if the validation webhook was scaffolded
res.Webhooks.Conversion = false // Version 3 alpha does not include if the conversion webhook was scaffolded
resources = append(resources, r)
}

return resources, nil
}

// AddResource implements config.Config
func (c *cfg) AddResource(res resource.Resource) error {
// As res is passed by value it is already a shallow copy, but we need to make a deep copy
res = res.Copy()

discardNonIncludedFields(&res) // Version 3 alpha does not include several fields from the Resource model
// Plural is only stored if irregular
if res.Plural == resource.RegularPlural(res.Kind) {
res.Plural = ""
}

if !c.HasResource(res.GVK) {
c.Resources = append(c.Resources, res)
Expand All @@ -224,7 +221,10 @@ func (c *cfg) UpdateResource(res resource.Resource) error {
// As res is passed by value it is already a shallow copy, but we need to make a deep copy
res = res.Copy()

discardNonIncludedFields(&res) // Version 3 alpha does not include several fields from the Resource model
// Plural is only stored if irregular
if res.Plural == resource.RegularPlural(res.Kind) {
res.Plural = ""
}

for i, r := range c.Resources {
if res.GVK.IsEqualTo(r.GVK) {
Expand Down
Loading

0 comments on commit 9797cf5

Please sign in to comment.