Skip to content

Commit

Permalink
Any changes that break 'PROJECT' file backwards-compatibility require…
Browse files Browse the repository at this point in the history
… a version

bump. This new version will be '3-alpha', which will eventually be bumped to
'3' once the below config changes have stabilized.

*: add tests and checks for v3 where appropriate
  • Loading branch information
estroz committed Apr 14, 2020
1 parent e4b8d15 commit 5d5e7d2
Show file tree
Hide file tree
Showing 193 changed files with 6,851 additions and 42 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ bin/*
/testdata/project-v2/go.sum
/testdata/project-v2-addon/go.sum
/testdata/project-v2-multigroup/go.sum
/testdata/project-v3/go.sum
/testdata/project-v3-multigroup/go.sum
2 changes: 1 addition & 1 deletion cmd/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func (o *editOptions) bindFlags(cmd *cobra.Command) {
}

func (o *editOptions) Validate() error {
if !o.config.IsV2() {
if !o.config.IsV2() && !o.config.IsV3() {
if o.config.MultiGroup {
return fmt.Errorf("multiple group support can't be enabled for version %s", o.config.Version)
}
Expand Down
52 changes: 30 additions & 22 deletions designs/extensible-cli-and-scaffolding-plugins-phase-1.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,6 @@ existing qualifier defined by the plugin. FQ names prevent conflicts between
plugin names; the plugin runner will ask the user to add a name qualifier to
a conflicting plugin.

#### Project file plugin `layout`

The `PROJECT` file will specify what base plugin generated the project under
a `layout` key. `layout` will have the format: `Plugin.Name() + "/" + Plugin.Version()`.
`version` and `layout` have versions with different meanings: `version` is the
project config version, while `layout`'s version is the plugin semantic version.
The value in `version` will determine that in `layout` by a plugin's supported
project versions (via `SupportedProjectVersions()`).

Example `PROJECT` file:

```yaml
version: "2"
layout: go/v1.0.0
domain: testproject.org
repo: github.com/test-inc/testproject
resources:
- group: crew
kind: Captain
version: v1
```
### Optional

Next, a plugin could optionally implement further interfaces to declare its support for specific Kubebuilder subcommands. For example:
Expand Down Expand Up @@ -135,6 +113,36 @@ type Deprecated interface {
}
```

## Configuration

### Config version `3-alpha`

Any changes that break `PROJECT` file backwards-compatibility require a version
bump. This new version will be `3-alpha`, which will eventually be bumped to
`3` once the below config changes have stabilized.

### Project file plugin `layout`

The `PROJECT` file will specify what base plugin generated the project under
a `layout` key. `layout` will have the format: `Plugin.Name() + "/" + Plugin.Version()`.
`version` and `layout` have versions with different meanings: `version` is the
project config version, while `layout`'s version is the plugin semantic version.
The value in `version` will determine that in `layout` by a plugin's supported
project versions (via `SupportedProjectVersions()`).

Example `PROJECT` file:

```yaml
version: "3-alpha"
layout: go/v1.0.0
domain: testproject.org
repo: github.com/test-inc/testproject
resources:
- group: crew
kind: Captain
version: v1
```
## CLI
To make the above plugin system extensible and usable by other projects, we could add a new CLI package that Kubebuilder (and other projects) could use as their entrypoint.
Expand Down
8 changes: 5 additions & 3 deletions generate_testdata.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ scaffold_test_project() {
$kb create api --group core --version v1 --kind Namespace --example=false --controller=true --resource=false --namespaced=false --make=false
$kb alpha webhook --group core --version v1 --kind Namespace --type=mutating --operations=update --make=false
$kb create api --group policy --version v1beta1 --kind HealthCheckPolicy --example=false --controller=true --resource=true --namespaced=false --make=false
elif [ $version == "2" ]; then
elif [ $version == "2" ] || [ $version == "3-alpha" ]; then
header_text "Starting to generate projects with version $version"
header_text "Generating $project"

Expand All @@ -66,14 +66,14 @@ scaffold_test_project() {
header_text "initializing $project..."
$kb init --project-version $version --domain testproject.org --license apache2 --owner "The Kubernetes authors"

if [ $project == "project-v2" ]; then
if [ $project == "project-v2" ] || [ $project == "project-v3" ]; then
header_text 'Creating APIs ...'
$kb create api --group crew --version v1 --kind Captain --controller=true --resource=true --make=false
$kb create webhook --group crew --version v1 --kind Captain --defaulting --programmatic-validation
$kb create api --group crew --version v1 --kind FirstMate --controller=true --resource=true --make=false
$kb create webhook --group crew --version v1 --kind FirstMate --conversion
$kb create api --group crew --version v1 --kind Admiral --controller=true --resource=true --namespaced=false --make=false
elif [ $project == "project-v2-multigroup" ]; then
elif [ $project == "project-v2-multigroup" ] || [ $project == "project-v3-multigroup" ]; then
header_text 'Switching to multigroup layout ...'
$kb edit --multigroup=true

Expand Down Expand Up @@ -112,3 +112,5 @@ scaffold_test_project gopath/src/project 1
scaffold_test_project project-v2 2
scaffold_test_project project-v2-multigroup 2
scaffold_test_project project-v2-addon 2
scaffold_test_project project-v3 3-alpha
scaffold_test_project project-v3-multigroup 3-alpha
2 changes: 1 addition & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const (
DefaultPath = "PROJECT"

// DefaultVersion is the version which will be used when the version flag is not provided
DefaultVersion = config.Version2
DefaultVersion = config.Version3
)

func exists(fs afero.Fs, path string) (bool, error) {
Expand Down
6 changes: 3 additions & 3 deletions pkg/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ func (c *cli) initialize() error {
case len(c.cliPluginKeys) != 0:
// Filter plugins by keys passed in CLI.
filterKeys = c.cliPluginKeys
case c.configured && !projectConfig.IsV1():
case c.configured && projectConfig.IsV3():
// All non-v1 configs must have a layout key. This check will help with
// migration.
if projectConfig.Layout == "" {
Expand Down Expand Up @@ -300,9 +300,9 @@ func (c cli) validate() error {
if _, versionFound := c.pluginsFromOptions[c.projectVersion]; !versionFound {
return fmt.Errorf("no plugins for project version %q", c.projectVersion)
}
// If --plugins is not set, no layout exists (no config or project is v1),
// If --plugins is not set, no layout exists (no config or project is v1 or v2),
// and no defaults exist, we cannot know which plugins to use.
if (!c.configured || c.projectVersion == config.Version1) && len(c.cliPluginKeys) == 0 {
if (!c.configured || c.projectVersion != config.Version3) && len(c.cliPluginKeys) == 0 {
_, versionExists := c.defaultPluginsFromOptions[c.projectVersion]
if !versionExists {
return fmt.Errorf("no default plugins for project version %s", c.projectVersion)
Expand Down
6 changes: 6 additions & 0 deletions pkg/model/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
const (
Version1 = "1"
Version2 = "2"
Version3 = "3-alpha"
)

// Config is the unmarshalled representation of the configuration file
Expand Down Expand Up @@ -65,6 +66,11 @@ func (c Config) IsV2() bool {
return c.Version == Version2
}

// IsV3 returns true if it is a v3 project
func (c Config) IsV3() bool {
return c.Version == Version3
}

// HasResource returns true if API resource is already tracked
func (c Config) HasResource(target GVK) bool {
// Return true if the target resource is found in the tracked resources
Expand Down
3 changes: 2 additions & 1 deletion pkg/plugin/v1/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1

import (
"sigs.k8s.io/kubebuilder/pkg/model/config"
"sigs.k8s.io/kubebuilder/pkg/plugin"
)

Expand All @@ -28,7 +29,7 @@ const (
See how to upgrade your project to v2: https://book.kubebuilder.io/migration/guide.html`
)

var supportedProjectVersions = []string{"1"}
var supportedProjectVersions = []string{config.Version1}

var (
_ plugin.Base = Plugin{}
Expand Down
2 changes: 1 addition & 1 deletion pkg/plugin/v2/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func (p *createAPIPlugin) Validate() error {
}

// Check that the provided group can be added to the project
if p.config.IsV2() && !p.config.MultiGroup &&
if (p.config.IsV2() || p.config.IsV3()) && !p.config.MultiGroup &&
len(p.config.Resources) != 0 && !p.config.HasGroup(p.resource.Group) {
return fmt.Errorf("multiple groups are not allowed by default, to enable multi-group visit %s",
"kubebuilder.io/migration/multi-group.html")
Expand Down
6 changes: 4 additions & 2 deletions pkg/plugin/v2/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,10 @@ func (p *initPlugin) BindFlags(fs *pflag.FlagSet) {
}

func (p *initPlugin) InjectConfig(c *config.Config) {
// v2 project configs get a 'layout' value.
c.Layout = plugin.KeyFor(Plugin{})
// v3 project configs get a 'layout' value.
if c.IsV3() {
c.Layout = plugin.KeyFor(Plugin{})
}
p.config = c
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/plugin/v2/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v2

import (
"sigs.k8s.io/kubebuilder/pkg/model/config"
"sigs.k8s.io/kubebuilder/pkg/plugin"
)

Expand All @@ -25,7 +26,7 @@ const (
pluginVersion = "v2.0.0"
)

var supportedProjectVersions = []string{"2"}
var supportedProjectVersions = []string{config.Version2, config.Version3}

var (
_ plugin.Base = Plugin{}
Expand Down
2 changes: 1 addition & 1 deletion pkg/scaffold/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (s *apiScaffolder) Scaffold() error {
switch {
case s.config.IsV1():
return s.scaffoldV1()
case s.config.IsV2():
case s.config.IsV2(), s.config.IsV3():
return s.scaffoldV2()
default:
return fmt.Errorf("unknown project version %v", s.config.Version)
Expand Down
2 changes: 1 addition & 1 deletion pkg/scaffold/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (s *initScaffolder) Scaffold() error {
switch {
case s.config.IsV1():
return s.scaffoldV1()
case s.config.IsV2():
case s.config.IsV2(), s.config.IsV3():
return s.scaffoldV2()
default:
return fmt.Errorf("unknown project version %v", s.config.Version)
Expand Down
2 changes: 1 addition & 1 deletion pkg/scaffold/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (s *webhookScaffolder) Scaffold() error {
switch {
case s.config.IsV1():
return s.scaffoldV1()
case s.config.IsV2():
case s.config.IsV2(), s.config.IsV3():
return s.scaffoldV2()
default:
return fmt.Errorf("unknown project version %v", s.config.Version)
Expand Down
4 changes: 4 additions & 0 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,8 @@ GO111MODULE=on test_project project-v2 2
GO111MODULE=on test_project project-v2-multigroup 2
GO111MODULE=on test_project project-v2-addon 2

# test project v3
GO111MODULE=on test_project project-v3 3-alpha
GO111MODULE=on test_project project-v3-multigroup 3-alpha

exit $rc
Loading

0 comments on commit 5d5e7d2

Please sign in to comment.