Skip to content

Commit

Permalink
Add new Golang base for go/v4-alpha with changes requested by the com…
Browse files Browse the repository at this point in the history
…munity in the layout

- Add a new golang language base plugin (base.go/v4)
- Change the go/v4-alpha plugin to use the new base
- Address the layout changes requirements for go/v4. Now, the api and controllers are under the pkg dir.
- Change the Makefile to install kustomize with go install
- Remove crdVersion and webhook versions that is not supported and should no longer be served.

Closes: #932
Closes: #2531
Closes: #2822
  • Loading branch information
camilamacedo86 committed Oct 1, 2022
1 parent f5e0d94 commit 5a32d68
Show file tree
Hide file tree
Showing 191 changed files with 5,351 additions and 1,392 deletions.
4 changes: 3 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
deployimagev1alpha1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/deploy-image/v1alpha1"
golangv2 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2"
golangv3 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3"
golangv4 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v4"
grafanav1alpha1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/optional/grafana/v1alpha"
)

Expand All @@ -47,7 +48,7 @@ func main() {
// Bundle plugin which built the golang projects scaffold by Kubebuilder go/v3 with kustomize alpha-v2
gov4Bundle, _ := plugin.NewBundle(golang.DefaultNameQualifier, plugin.Version{Number: 4, Stage: stage.Alpha},
kustomizecommonv2alpha.Plugin{},
golangv3.Plugin{},
golangv4.Plugin{},
)

fs := machinery.Filesystem{
Expand All @@ -64,6 +65,7 @@ func main() {
cli.WithPlugins(
golangv2.Plugin{},
golangv3.Plugin{},
golangv4.Plugin{},
gov3Bundle,
gov4Bundle,
&kustomizecommonv1.Plugin{},
Expand Down
23 changes: 12 additions & 11 deletions docs/book/src/plugins/available-plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@

This section describes the plugins supported and shipped in with the Kubebuilder project.

| Plugin | Key | Description |
| ---------------------------------------------------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [go.kubebuilder.io/v2 - (Deprecated)](go-v2-plugin.md) | `go/v2` | Golang plugin responsible for scaffolding the legacy layout provided with Kubebuilder CLI >= `2.0.0` and < `3.0.0`. |
| [go.kubebuilder.io/v3 - (Default scaffold with Kubebuilder init)](go-v3-plugin.md) | `go/v3` | Default scaffold used for creating a project when no plugin(s) are provided. Responsible for scaffolding Golang projects and its configurations. |
| [go.kubebuilder.io/v4-alpha - (Add Apple Sillicom Support)](go-v4-plugin.md) | `go/v4` | Scaffold composite by `base.go.kubebuilder.io/v3` and [kustomize.common.kubebuilder.io/v2-alpha](kustomize-v2-alpha.md). Responsible for scaffolding Golang projects and its configurations. |
| [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 `config/` directory). This plugin is used in the composition to create the plugin (`go/v3`). |
| [kustomize.common.kubebuilder.io/v2-alpha](kustomize-v2-alpha.md) | `kustomize/v2-alpha` | It has the same purpose of `kustomize/v1`. However, it works with [kustomize][kustomize] version `v4` and addresses the required changes for 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`) |
| [grafana.kubebuilder.io/v1-alpha](grafana-v1-alpha.md) | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. |
| [deploy-image.go.kubebuilder.io/v1-alpha](deploy-image-plugin-v1-alpha) | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). |
| Plugin | Key | Description |
|------------------------------------------------------------------------------------|-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [go.kubebuilder.io/v2 - (Deprecated)](go-v2-plugin.md) | `go/v2` | Golang plugin responsible for scaffolding the legacy layout provided with Kubebuilder CLI >= `2.0.0` and < `3.0.0`. |
| [go.kubebuilder.io/v3 - (Default scaffold with Kubebuilder init)](go-v3-plugin.md) | `go/v3` | Default scaffold used for creating a project when no plugin(s) are provided. Responsible for scaffolding Golang projects and its configurations. |
| [go.kubebuilder.io/v4-alpha - (Add Apple Sillicom Support)](go-v4-plugin.md) | `go/v4` | Scaffold composite by `base.go.kubebuilder.io/v3` and [kustomize.common.kubebuilder.io/v2-alpha](kustomize-v2-alpha.md). Responsible for scaffolding Golang projects and its configurations. |
| [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 `config/` directory). This plugin is used in the composition to create the plugin (`go/v3`). |
| [kustomize.common.kubebuilder.io/v2-alpha](kustomize-v2-alpha.md) | `kustomize/v2-alpha` | It has the same purpose of `kustomize/v1`. However, it works with [kustomize][kustomize] version `v4` and addresses the required changes for 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`) |
| `base.go.kubebuilder.io/v4` | `base/v4` | Responsible for scaffold all files which specific requires Golang. This plugin is used in the composition to create the plugin (`go/v4`) |
| [grafana.kubebuilder.io/v1-alpha](grafana-v1-alpha.md) | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. |
| [deploy-image.go.kubebuilder.io/v1-alpha](deploy-image-plugin-v1-alpha) | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). |

> Note: **ALPHA** plugins can introduce breaking changes. For further info see [Plugins Versioning](./plugins/plugins-versioning.md).
Expand Down
3 changes: 2 additions & 1 deletion docs/book/src/plugins/go-v4-plugin.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# go/v4-alpha (go.kubebuilder.io/v4-alpha)

Kubebuilder will scaffold using the go/v4-alpha plugin only if specified when initializing the project.
This plugin is a composition of the plugins ` kustomize.common.kubebuilder.io/v2-alpha` and `base.go.kubebuilder.io/v3`.
This plugin is a composition of the plugins ` kustomize.common.kubebuilder.io/v2-alpha` and `base.go.kubebuilder.io/v4`.
It scaffolds a project template that helps in constructing sets of [controllers][controller-runtime].

It scaffolds boilerplate code to create and design controllers.
Expand All @@ -21,6 +21,7 @@ under the [testdata][testdata] directory on the root directory of the Kubebuilde
- If you are looking to experiment with the future default scaffold that will be provided by Kubebuilder CLI
- If your local environment is Apple Silicon (`darwin/arm64`)
- If you are looking to use [kubernetes-sigs/kustomize][kustomize] v4
- If you are looking for the new default layout where the "apis" and "controllers" are scaffold under the `pkg/` dir.

## How to use it ?

Expand Down
11 changes: 11 additions & 0 deletions pkg/model/resource/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ func safeImport(unsafe string) string {

// APIPackagePath returns the default path
func APIPackagePath(repo, group, version string, multiGroup bool) string {
if multiGroup {
if group != "" {
return path.Join(repo, "pkg", "apis", group, version)
}
return path.Join(repo, "pkg", "apis", version)
}
return path.Join(repo, "pkg", "api", version)
}

// APIPackagePathLegacy returns the default path
func APIPackagePathLegacy(repo, group, version string, multiGroup bool) string {
if multiGroup {
if group != "" {
return path.Join(repo, "apis", group, version)
Expand Down
6 changes: 3 additions & 3 deletions pkg/model/resource/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ var _ = Describe("APIPackagePath", func() {
func(repo, group, version string, multiGroup bool, p string) {
Expect(APIPackagePath(repo, group, version, multiGroup)).To(Equal(p))
},
Entry("single group setup", repo, group, version, false, path.Join(repo, "api", version)),
Entry("multiple group setup", repo, group, version, true, path.Join(repo, "apis", group, version)),
Entry("multiple group setup with empty group", repo, "", version, true, path.Join(repo, "apis", version)),
Entry("single group setup", repo, group, version, false, path.Join(repo, "pkg", "api", version)),
Entry("multiple group setup", repo, group, version, true, path.Join(repo, "pkg", "apis", group, version)),
Entry("multiple group setup with empty group", repo, "", version, true, path.Join(repo, "pkg", "apis", version)),
)
})

Expand Down
3 changes: 3 additions & 0 deletions pkg/plugin/util/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,19 @@ import (
"sigs.k8s.io/kubebuilder/v3/pkg/config"
)

// Deprecated: go/v4 no longer supports v1beta1 option
// HasDifferentCRDVersion returns true if any other CRD version is tracked in the project configuration.
func HasDifferentCRDVersion(config config.Config, crdVersion string) bool {
return hasDifferentAPIVersion(config.ListCRDVersions(), crdVersion)
}

// Deprecated: go/v4 no longer supports v1beta1 option
// HasDifferentWebhookVersion returns true if any other webhook version is tracked in the project configuration.
func HasDifferentWebhookVersion(config config.Config, webhookVersion string) bool {
return hasDifferentAPIVersion(config.ListWebhookVersions(), webhookVersion)
}

// Deprecated: go/v4 no longer supports v1beta1 option
func hasDifferentAPIVersion(versions []string, version string) bool {
return !(len(versions) == 0 || (len(versions) == 1 && versions[0] == version))
}
19 changes: 19 additions & 0 deletions pkg/plugin/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,25 @@ func EnsureExistAndReplace(input, match, replace string) (string, error) {
return strings.Replace(input, match, replace, -1), nil
}

func HasFragment(path, target string) (bool, error) {
_, err := os.Stat(path)
if err != nil {
return false, err
}

// false positive
// nolint:gosec
b, err := os.ReadFile(path)
if err != nil {
return false, err
}

if !strings.Contains(string(b), target) {
return false, nil
}
return true, nil
}

// ReplaceInFile replaces all instances of old with new in the file at path.
func ReplaceInFile(path, old, new string) error {
info, err := os.Stat(path)
Expand Down
37 changes: 20 additions & 17 deletions pkg/plugins/golang/declarative/v1/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,36 +41,39 @@ func (p *initSubcommand) InjectConfig(c config.Config) error {
}

func (p *initSubcommand) Scaffold(fs machinery.Filesystem) error {
err := updateDockerfile()
if err != nil {
return err
}
return nil
return updateDockerfile()
}

// updateDockerfile will add channels staging required for declarative plugin
func updateDockerfile() error {
fmt.Println("updating Dockerfile to add channels/ directory in the image")
managerFile := filepath.Join("Dockerfile")
dokerfile := filepath.Join("Dockerfile")

// nolint:lll
err := insertCodeIfDoesNotExist(managerFile,
"COPY controllers/ controllers/",
"\n# https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern/blob/master/docs/addon/walkthrough/README.md#adding-a-manifest\n# Stage channels and make readable\nCOPY channels/ /channels/\nRUN chmod -R a+rx /channels/")
isLegacyLayout, err := util.HasFragment(dokerfile, "COPY controllers/ controllers/")
if err != nil {
return err
}

err = insertCodeIfDoesNotExist(managerFile,
"COPY --from=builder /workspace/manager .",
"\n# copy channels\nCOPY --from=builder /channels /channels\n")
if err != nil {
return err
if isLegacyLayout {
// nolint:lll
err := insertCodeIfDoesNotExist(dokerfile, "COPY controllers/ controllers/",
"\n# https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern/blob/master/docs/addon/walkthrough/README.md#adding-a-manifest\n# Stage channels and make readable\nCOPY channels/ /channels/\nRUN chmod -R a+rx /channels/")
if err != nil {
return err
}
} else {
// nolint:lll
err := insertCodeIfDoesNotExist(dokerfile,
"COPY pkg/controllers/ pkg/controllers/",
"\n# https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern/blob/master/docs/addon/walkthrough/README.md#adding-a-manifest\n# Stage channels and make readable\nCOPY channels/ /channels/\nRUN chmod -R a+rx /channels/")
if err != nil {
return err
}
}

return nil
}

// insertCodeIfDoesNotExist insert code if it does not already exists
func insertCodeIfDoesNotExist(filename, target, code string) error {
// false positive
// nolint:gosec
Expand All @@ -85,4 +88,4 @@ func insertCodeIfDoesNotExist(filename, target, code string) error {
}

return util.InsertCode(filename, target, code)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package templates

import (
"fmt"
"path/filepath"

"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
Expand All @@ -43,6 +44,7 @@ func (f *Controller) SetTemplateDefaults() error {
}
}
f.Path = f.Resource.Replacer().Replace(f.Path)
fmt.Println(f.Path)

f.TemplateBody = controllerTemplate

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func (f *Types) SetTemplateDefaults() error {
}
}
f.Path = f.Resource.Replacer().Replace(f.Path)
fmt.Println(f.Path)

f.TemplateBody = typesTemplate

Expand Down
15 changes: 12 additions & 3 deletions pkg/plugins/golang/deploy-image/v1alpha1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import (
"errors"
"fmt"
"os"

goPlugin "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang"
"strings"

"sigs.k8s.io/kubebuilder/v3/pkg/plugin/util"
goPlugin "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang"

"github.com/spf13/pflag"
"sigs.k8s.io/kubebuilder/v3/pkg/config"
Expand Down Expand Up @@ -152,7 +152,14 @@ func (p *createAPISubcommand) InjectResource(res *resource.Resource) error {
p.options.DoAPI = true
p.options.DoController = true
p.options.Namespaced = true
p.options.UpdateResource(p.resource, p.config)

isLegacyLayout := false
for _, pluginKey := range p.config.GetPluginChain() {
if strings.Contains(pluginKey, "go.kubebuilder.io/v3") {
isLegacyLayout = true
}
}
p.options.UpdateResource(p.resource, p.config, isLegacyLayout)

if err := p.resource.Validate(); err != nil {
return err
Expand All @@ -165,12 +172,14 @@ func (p *createAPISubcommand) InjectResource(res *resource.Resource) error {
}

// Check CRDVersion against all other CRDVersions in p.config for compatibility.
// nolint:staticcheck
if util.HasDifferentCRDVersion(p.config, p.resource.API.CRDVersion) {
return fmt.Errorf("only one CRD version can be used for all resources, cannot add %q",
p.resource.API.CRDVersion)
}

// Check CRDVersion against all other CRDVersions in p.config for compatibility.
// nolint:staticcheck
if util.HasDifferentCRDVersion(p.config, p.resource.API.CRDVersion) {
return fmt.Errorf("only one CRD version can be used for all resources, cannot add %q",
p.resource.API.CRDVersion)
Expand Down
Loading

0 comments on commit 5a32d68

Please sign in to comment.