diff --git a/cmd/main.go b/cmd/main.go
index 4faf3193533..032470b987b 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -24,6 +24,7 @@ import (
cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3"
"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"
@@ -46,6 +47,7 @@ func main() {
golangv3.Plugin{},
gov3Bundle,
&kustomizecommonv1.Plugin{},
+ &kustomizecommonv2.Plugin{},
&declarativev1.Plugin{},
),
cli.WithDefaultPlugins(cfgv2.Version, golangv2.Plugin{}),
diff --git a/docs/book/src/plugins/available-plugins.md b/docs/book/src/plugins/available-plugins.md
index 1f6a614c18a..ca259eef030 100644
--- a/docs/book/src/plugins/available-plugins.md
+++ b/docs/book/src/plugins/available-plugins.md
@@ -2,4 +2,5 @@
This section details how to use the currently available plugins in Kubebuilder.
- - [Declarative V1](declarative-v1.md)
\ No newline at end of file
+ - [Declarative V1](declarative-v1.md)
+ - [Kustomize V2-alpha (Requires kustomize >= v4)](kustomize-v2-alpha.md)
\ No newline at end of file
diff --git a/docs/book/src/plugins/kustomize-v2-alpha.md b/docs/book/src/plugins/kustomize-v2-alpha.md
new file mode 100644
index 00000000000..520da39883c
--- /dev/null
+++ b/docs/book/src/plugins/kustomize-v2-alpha.md
@@ -0,0 +1,111 @@
+# Kustomize v2-alpha Plugin
+
+The kustomize plugin allows you to scaffold all kustomize manifests used to work with the language base plugin `base.go.kubebuilder.io/v3`.
+
+
+
+## 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
+
+
+
+
+## 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
+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, you can use kustomize alone via the tool:
+
+```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]`)
+
+
+
+## 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
\ No newline at end of file
diff --git a/pkg/plugins/common/kustomize/v1/plugin.go b/pkg/plugins/common/kustomize/v1/plugin.go
index 46e756ca43c..749811a6685 100644
--- a/pkg/plugins/common/kustomize/v1/plugin.go
+++ b/pkg/plugins/common/kustomize/v1/plugin.go
@@ -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"
+
const pluginName = "kustomize.common." + plugins.DefaultNameQualifier
var (
diff --git a/pkg/plugins/common/kustomize/v2/api.go b/pkg/plugins/common/kustomize/v2/api.go
new file mode 100644
index 00000000000..98059f0ae32
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/api.go
@@ -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()
+}
diff --git a/pkg/plugins/common/kustomize/v2/create.go b/pkg/plugins/common/kustomize/v2/create.go
new file mode 100644
index 00000000000..a0aac27649a
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/create.go
@@ -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
+}
diff --git a/pkg/plugins/common/kustomize/v2/init.go b/pkg/plugins/common/kustomize/v2/init.go
new file mode 100644
index 00000000000..418b9f1c0fc
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/init.go
@@ -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()
+}
diff --git a/pkg/plugins/common/kustomize/v2/plugin.go b/pkg/plugins/common/kustomize/v2/plugin.go
new file mode 100644
index 00000000000..a15620b6ee3
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/plugin.go
@@ -0,0 +1,68 @@
+/*
+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/config"
+ cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3"
+ "sigs.k8s.io/kubebuilder/v3/pkg/model/stage"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugin"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins"
+)
+
+// KustomizeVersion is the kubernetes-sigs/kustomize version to be used in the project
+const KustomizeVersion = "v4.4.1"
+
+const pluginName = "kustomize.common." + plugins.DefaultNameQualifier
+
+var (
+ pluginVersion = plugin.Version{Number: 2, Stage: stage.Alpha}
+ supportedProjectVersions = []config.Version{cfgv3.Version}
+)
+
+var (
+ _ plugin.Init = Plugin{}
+ _ plugin.CreateAPI = Plugin{}
+ _ plugin.CreateWebhook = Plugin{}
+)
+
+// Plugin implements the plugin.Full interface
+type Plugin struct {
+ initSubcommand
+ createAPISubcommand
+ createWebhookSubcommand
+}
+
+// Name returns the name of the plugin
+func (Plugin) Name() string { return pluginName }
+
+// Version returns the version of the plugin
+func (Plugin) Version() plugin.Version { return pluginVersion }
+
+// SupportedProjectVersions returns an array with all project versions supported by the plugin
+func (Plugin) SupportedProjectVersions() []config.Version { return supportedProjectVersions }
+
+// GetInitSubcommand will return the subcommand which is responsible for scaffolding init project
+func (p Plugin) GetInitSubcommand() plugin.InitSubcommand { return &p.initSubcommand }
+
+// GetCreateAPISubcommand will return the subcommand which is responsible for scaffolding apis
+func (p Plugin) GetCreateAPISubcommand() plugin.CreateAPISubcommand { return &p.createAPISubcommand }
+
+// GetCreateWebhookSubcommand will return the subcommand which is responsible for scaffolding webhooks
+func (p Plugin) GetCreateWebhookSubcommand() plugin.CreateWebhookSubcommand {
+ return &p.createWebhookSubcommand
+}
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/api.go b/pkg/plugins/common/kustomize/v2/scaffolds/api.go
new file mode 100644
index 00000000000..9c90c8bf168
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/api.go
@@ -0,0 +1,87 @@
+/*
+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 scaffolds
+
+import (
+ "fmt"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/config"
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+ "sigs.k8s.io/kubebuilder/v3/pkg/model/resource"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/patches"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/samples"
+)
+
+var _ plugins.Scaffolder = &apiScaffolder{}
+
+// apiScaffolder contains configuration for generating scaffolding for Go type
+// representing the API and controller that implements the behavior for the API.
+type apiScaffolder struct {
+ config config.Config
+ resource resource.Resource
+
+ // fs is the filesystem that will be used by the scaffolder
+ fs machinery.Filesystem
+
+ // force indicates whether to scaffold files even if they exist.
+ force bool
+}
+
+// NewAPIScaffolder returns a new Scaffolder for API/controller creation operations
+func NewAPIScaffolder(config config.Config, res resource.Resource, force bool) plugins.Scaffolder {
+ return &apiScaffolder{
+ config: config,
+ resource: res,
+ force: force,
+ }
+}
+
+// InjectFS implements cmdutil.Scaffolder
+func (s *apiScaffolder) InjectFS(fs machinery.Filesystem) {
+ s.fs = fs
+}
+
+// Scaffold implements cmdutil.Scaffolder
+func (s *apiScaffolder) Scaffold() error {
+ fmt.Println("Writing kustomize manifests for you to edit...")
+
+ // Initialize the machinery.Scaffold that will write the files to disk
+ scaffold := machinery.NewScaffold(s.fs,
+ machinery.WithConfig(s.config),
+ machinery.WithResource(&s.resource),
+ )
+
+ // Keep track of these values before the update
+ if s.resource.HasAPI() {
+ if err := scaffold.Execute(
+ &samples.CRDSample{Force: s.force},
+ &rbac.CRDEditorRole{},
+ &rbac.CRDViewerRole{},
+ &patches.EnableWebhookPatch{},
+ &patches.EnableCAInjectionPatch{},
+ &crd.Kustomization{},
+ &crd.KustomizeConfig{},
+ ); err != nil {
+ return fmt.Errorf("error scaffolding kustomize API manifests: %v", err)
+ }
+ }
+
+ return nil
+}
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/init.go b/pkg/plugins/common/kustomize/v2/scaffolds/init.go
new file mode 100644
index 00000000000..d43bee9279c
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/init.go
@@ -0,0 +1,84 @@
+/*
+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 scaffolds
+
+import (
+ "fmt"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/config"
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac"
+)
+
+const (
+ imageName = "controller:latest"
+)
+
+var _ plugins.Scaffolder = &initScaffolder{}
+
+type initScaffolder struct {
+ config config.Config
+
+ // fs is the filesystem that will be used by the scaffolder
+ fs machinery.Filesystem
+}
+
+// NewInitScaffolder returns a new Scaffolder for project initialization operations
+func NewInitScaffolder(config config.Config) plugins.Scaffolder {
+ return &initScaffolder{
+ config: config,
+ }
+}
+
+// InjectFS implements cmdutil.Scaffolder
+func (s *initScaffolder) InjectFS(fs machinery.Filesystem) {
+ s.fs = fs
+}
+
+// Scaffold implements cmdutil.Scaffolder
+func (s *initScaffolder) Scaffold() error {
+ fmt.Println("Writing kustomize manifests for you to edit...")
+
+ // Initialize the machinery.Scaffold that will write the files to disk
+ scaffold := machinery.NewScaffold(s.fs,
+ machinery.WithConfig(s.config),
+ )
+
+ return scaffold.Execute(
+ &rbac.Kustomization{},
+ &rbac.AuthProxyRole{},
+ &rbac.AuthProxyRoleBinding{},
+ &rbac.AuthProxyService{},
+ &rbac.AuthProxyClientRole{},
+ &rbac.RoleBinding{},
+ &rbac.LeaderElectionRole{},
+ &rbac.LeaderElectionRoleBinding{},
+ &rbac.ServiceAccount{},
+ &manager.Kustomization{},
+ &manager.Config{Image: imageName},
+ &manager.ControllerManagerConfig{},
+ &kdefault.Kustomization{},
+ &kdefault.ManagerAuthProxyPatch{},
+ &kdefault.ManagerConfigPatch{},
+ &prometheus.Kustomization{},
+ &prometheus.Monitor{},
+ )
+}
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/certificate.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/certificate.go
new file mode 100644
index 00000000000..fc449472db2
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/certificate.go
@@ -0,0 +1,71 @@
+/*
+Copyright 2020 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 certmanager
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &Certificate{}
+
+// Certificate scaffolds a file that defines the issuer CR and the certificate CR
+type Certificate struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *Certificate) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "certmanager", "certificate.yaml")
+ }
+
+ f.TemplateBody = certManagerTemplate
+
+ // If file exists (ex. because a webhook was already created), skip creation.
+ f.IfExistsAction = machinery.SkipFile
+
+ return nil
+}
+
+const certManagerTemplate = `# The following manifests contain a self-signed issuer CR and a certificate CR.
+# More document can be found at https://docs.cert-manager.io
+# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes.
+apiVersion: cert-manager.io/v1
+kind: Issuer
+metadata:
+ name: selfsigned-issuer
+ namespace: system
+spec:
+ selfSigned: {}
+---
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+ name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
+ namespace: system
+spec:
+ # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize
+ dnsNames:
+ - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc
+ - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local
+ issuerRef:
+ kind: Issuer
+ name: selfsigned-issuer
+ secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/kustomization.go
new file mode 100644
index 00000000000..2e31a62d4ae
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/kustomization.go
@@ -0,0 +1,51 @@
+/*
+Copyright 2020 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 certmanager
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &Kustomization{}
+
+// Kustomization scaffolds a file that defines the kustomization scheme for the certmanager folder
+type Kustomization struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *Kustomization) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "certmanager", "kustomization.yaml")
+ }
+
+ f.TemplateBody = kustomizationTemplate
+
+ // If file exists (ex. because a webhook was already created), skip creation.
+ f.IfExistsAction = machinery.SkipFile
+
+ return nil
+}
+
+const kustomizationTemplate = `resources:
+- certificate.yaml
+
+configurations:
+- kustomizeconfig.yaml
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/kustomizeconfig.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/kustomizeconfig.go
new file mode 100644
index 00000000000..02bda5e7341
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/kustomizeconfig.go
@@ -0,0 +1,63 @@
+/*
+Copyright 2020 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 certmanager
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &KustomizeConfig{}
+
+// KustomizeConfig scaffolds a file that configures the kustomization for the certmanager folder
+type KustomizeConfig struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *KustomizeConfig) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "certmanager", "kustomizeconfig.yaml")
+ }
+
+ f.TemplateBody = kustomizeConfigTemplate
+
+ // If file exists (ex. because a webhook was already created), skip creation.
+ f.IfExistsAction = machinery.SkipFile
+
+ return nil
+}
+
+//nolint:lll
+const kustomizeConfigTemplate = `# This configuration is for teaching kustomize how to update name ref and var substitution
+nameReference:
+- kind: Issuer
+ group: cert-manager.io
+ fieldSpecs:
+ - kind: Certificate
+ group: cert-manager.io
+ path: spec/issuerRef/name
+
+varReference:
+- kind: Certificate
+ group: cert-manager.io
+ path: spec/commonName
+- kind: Certificate
+ group: cert-manager.io
+ path: spec/dnsNames
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/kustomization.go
new file mode 100644
index 00000000000..25fbc18af85
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/kustomization.go
@@ -0,0 +1,125 @@
+/*
+Copyright 2020 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 crd
+
+import (
+ "fmt"
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var (
+ _ machinery.Template = &Kustomization{}
+ _ machinery.Inserter = &Kustomization{}
+)
+
+// Kustomization scaffolds a file that defines the kustomization scheme for the crd folder
+type Kustomization struct {
+ machinery.TemplateMixin
+ machinery.ResourceMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *Kustomization) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "crd", "kustomization.yaml")
+ }
+ f.Path = f.Resource.Replacer().Replace(f.Path)
+
+ f.TemplateBody = fmt.Sprintf(kustomizationTemplate,
+ machinery.NewMarkerFor(f.Path, resourceMarker),
+ machinery.NewMarkerFor(f.Path, webhookPatchMarker),
+ machinery.NewMarkerFor(f.Path, caInjectionPatchMarker),
+ )
+
+ return nil
+}
+
+const (
+ resourceMarker = "crdkustomizeresource"
+ webhookPatchMarker = "crdkustomizewebhookpatch"
+ caInjectionPatchMarker = "crdkustomizecainjectionpatch"
+)
+
+// GetMarkers implements file.Inserter
+func (f *Kustomization) GetMarkers() []machinery.Marker {
+ return []machinery.Marker{
+ machinery.NewMarkerFor(f.Path, resourceMarker),
+ machinery.NewMarkerFor(f.Path, webhookPatchMarker),
+ machinery.NewMarkerFor(f.Path, caInjectionPatchMarker),
+ }
+}
+
+const (
+ resourceCodeFragment = `- bases/%s_%s.yaml
+`
+ webhookPatchCodeFragment = `#- patches/webhook_in_%s.yaml
+`
+ caInjectionPatchCodeFragment = `#- patches/cainjection_in_%s.yaml
+`
+)
+
+// GetCodeFragments implements file.Inserter
+func (f *Kustomization) GetCodeFragments() machinery.CodeFragmentsMap {
+ fragments := make(machinery.CodeFragmentsMap, 3)
+
+ // Generate resource code fragments
+ res := make([]string, 0)
+ res = append(res, fmt.Sprintf(resourceCodeFragment, f.Resource.QualifiedGroup(), f.Resource.Plural))
+
+ // Generate resource code fragments
+ webhookPatch := make([]string, 0)
+ webhookPatch = append(webhookPatch, fmt.Sprintf(webhookPatchCodeFragment, f.Resource.Plural))
+
+ // Generate resource code fragments
+ caInjectionPatch := make([]string, 0)
+ caInjectionPatch = append(caInjectionPatch, fmt.Sprintf(caInjectionPatchCodeFragment, f.Resource.Plural))
+
+ // Only store code fragments in the map if the slices are non-empty
+ if len(res) != 0 {
+ fragments[machinery.NewMarkerFor(f.Path, resourceMarker)] = res
+ }
+ if len(webhookPatch) != 0 {
+ fragments[machinery.NewMarkerFor(f.Path, webhookPatchMarker)] = webhookPatch
+ }
+ if len(caInjectionPatch) != 0 {
+ fragments[machinery.NewMarkerFor(f.Path, caInjectionPatchMarker)] = caInjectionPatch
+ }
+
+ return fragments
+}
+
+var kustomizationTemplate = `# This kustomization.yaml is not intended to be run by itself,
+# since it depends on service name and namespace that are out of this kustomize package.
+# It should be run by config/default
+resources:
+%s
+
+patchesStrategicMerge:
+# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
+# patches here are for enabling the conversion webhook for each CRD
+%s
+
+# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
+# patches here are for enabling the CA injection for each CRD
+%s
+
+# the following config is for teaching kustomize how to do kustomization for CRDs.
+configurations:
+- kustomizeconfig.yaml
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/kustomizeconfig.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/kustomizeconfig.go
new file mode 100644
index 00000000000..428bfde8b88
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/kustomizeconfig.go
@@ -0,0 +1,72 @@
+/*
+Copyright 2020 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 crd
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &KustomizeConfig{}
+
+// KustomizeConfig scaffolds a file that configures the kustomization for the crd folder
+type KustomizeConfig struct {
+ machinery.TemplateMixin
+ machinery.ResourceMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *KustomizeConfig) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "crd", "kustomizeconfig.yaml")
+ }
+
+ f.TemplateBody = kustomizeConfigTemplate
+
+ return nil
+}
+
+//nolint:lll
+const kustomizeConfigTemplate = `# This file is for teaching kustomize how to substitute name and namespace reference in CRD
+nameReference:
+- kind: Service
+ version: v1
+ fieldSpecs:
+ - kind: CustomResourceDefinition
+ version: {{ .Resource.API.CRDVersion }}
+ group: apiextensions.k8s.io
+ {{- if ne .Resource.API.CRDVersion "v1" }}
+ path: spec/conversion/webhookClientConfig/service/name
+ {{- else }}
+ path: spec/conversion/webhook/clientConfig/service/name
+ {{- end }}
+
+namespace:
+- kind: CustomResourceDefinition
+ version: {{ .Resource.API.CRDVersion }}
+ group: apiextensions.k8s.io
+ {{- if ne .Resource.API.CRDVersion "v1" }}
+ path: spec/conversion/webhookClientConfig/service/namespace
+ {{- else }}
+ path: spec/conversion/webhook/clientConfig/service/namespace
+ {{- end }}
+ create: false
+
+varReference:
+- path: metadata/annotations
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/patches/enablecainjection_patch.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/patches/enablecainjection_patch.go
new file mode 100644
index 00000000000..042f2228add
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/patches/enablecainjection_patch.go
@@ -0,0 +1,61 @@
+/*
+Copyright 2020 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 patches
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &EnableCAInjectionPatch{}
+
+// EnableCAInjectionPatch scaffolds a file that defines the patch that injects CA into the CRD
+type EnableCAInjectionPatch struct {
+ machinery.TemplateMixin
+ machinery.MultiGroupMixin
+ machinery.ResourceMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *EnableCAInjectionPatch) SetTemplateDefaults() error {
+ if f.Path == "" {
+ if f.MultiGroup {
+ f.Path = filepath.Join("config", "crd", "patches", "cainjection_in_%[group]_%[plural].yaml")
+ } else {
+ f.Path = filepath.Join("config", "crd", "patches", "cainjection_in_%[plural].yaml")
+ }
+ }
+ f.Path = f.Resource.Replacer().Replace(f.Path)
+
+ f.TemplateBody = enableCAInjectionPatchTemplate
+
+ return nil
+}
+
+//nolint:lll
+const enableCAInjectionPatchTemplate = `# The following patch adds a directive for certmanager to inject CA into the CRD
+{{- if ne .Resource.API.CRDVersion "v1" }}
+# CRD conversion requires k8s 1.13 or later.
+{{- end }}
+apiVersion: apiextensions.k8s.io/{{ .Resource.API.CRDVersion }}
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+ name: {{ .Resource.Plural }}.{{ .Resource.QualifiedGroup }}
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/patches/enablewebhook_patch.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/patches/enablewebhook_patch.go
new file mode 100644
index 00000000000..35662c647ae
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/patches/enablewebhook_patch.go
@@ -0,0 +1,78 @@
+/*
+Copyright 2020 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 patches
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &EnableWebhookPatch{}
+
+// EnableWebhookPatch scaffolds a file that defines the patch that enables conversion webhook for the CRD
+type EnableWebhookPatch struct {
+ machinery.TemplateMixin
+ machinery.MultiGroupMixin
+ machinery.ResourceMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *EnableWebhookPatch) SetTemplateDefaults() error {
+ if f.Path == "" {
+ if f.MultiGroup {
+ f.Path = filepath.Join("config", "crd", "patches", "webhook_in_%[group]_%[plural].yaml")
+ } else {
+ f.Path = filepath.Join("config", "crd", "patches", "webhook_in_%[plural].yaml")
+ }
+
+ }
+ f.Path = f.Resource.Replacer().Replace(f.Path)
+
+ f.TemplateBody = enableWebhookPatchTemplate
+
+ return nil
+}
+
+const enableWebhookPatchTemplate = `# The following patch enables a conversion webhook for the CRD
+{{- if ne .Resource.API.CRDVersion "v1" }}
+# CRD conversion requires k8s 1.13 or later.
+{{- end }}
+apiVersion: apiextensions.k8s.io/{{ .Resource.API.CRDVersion }}
+kind: CustomResourceDefinition
+metadata:
+ name: {{ .Resource.Plural }}.{{ .Resource.QualifiedGroup }}
+spec:
+ conversion:
+ strategy: Webhook
+ {{- if ne .Resource.API.CRDVersion "v1" }}
+ webhookClientConfig:
+ service:
+ namespace: system
+ name: webhook-service
+ path: /convert
+ {{- else }}
+ webhook:
+ clientConfig:
+ service:
+ namespace: system
+ name: webhook-service
+ path: /convert
+ conversionReviewVersions:
+ - {{ .Resource.API.CRDVersion }}
+ {{- end }}
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go
new file mode 100644
index 00000000000..d93780f7dfa
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go
@@ -0,0 +1,62 @@
+/*
+Copyright 2020 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 kdefault
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &WebhookCAInjectionPatch{}
+
+// WebhookCAInjectionPatch scaffolds a file that defines the patch that adds annotation to webhooks
+type WebhookCAInjectionPatch struct {
+ machinery.TemplateMixin
+ machinery.ResourceMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *WebhookCAInjectionPatch) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "default", "webhookcainjection_patch.yaml")
+ }
+
+ f.TemplateBody = injectCAPatchTemplate
+
+ // If file exists (ex. because a webhook was already created), skip creation.
+ f.IfExistsAction = machinery.SkipFile
+
+ return nil
+}
+
+const injectCAPatchTemplate = `# This patch add annotation to admission webhook config and
+# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize.
+apiVersion: admissionregistration.k8s.io/{{ .Resource.Webhooks.WebhookVersion }}
+kind: MutatingWebhookConfiguration
+metadata:
+ name: mutating-webhook-configuration
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+---
+apiVersion: admissionregistration.k8s.io/{{ .Resource.Webhooks.WebhookVersion }}
+kind: ValidatingWebhookConfiguration
+metadata:
+ name: validating-webhook-configuration
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go
new file mode 100644
index 00000000000..6bf39262a8f
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go
@@ -0,0 +1,183 @@
+/*
+Copyright 2020 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 kdefault
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &Kustomization{}
+
+// Kustomization scaffolds a file that defines the kustomization scheme for the default overlay folder
+type Kustomization struct {
+ machinery.TemplateMixin
+ machinery.ProjectNameMixin
+ machinery.ComponentConfigMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *Kustomization) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "default", "kustomization.yaml")
+ }
+
+ f.TemplateBody = kustomizeTemplate
+
+ f.IfExistsAction = machinery.Error
+
+ return nil
+}
+
+const kustomizeTemplate = `# Adds namespace to all resources.
+namespace: {{ .ProjectName }}-system
+
+# Value of this field is prepended to the
+# names of all resources, e.g. a deployment named
+# "wordpress" becomes "alices-wordpress".
+# Note that it should also match with the prefix (text before '-') of the namespace
+# field above.
+namePrefix: {{ .ProjectName }}-
+
+# Labels to add to all resources and selectors.
+#commonLabels:
+# someName: someValue
+
+bases:
+- ../crd
+- ../rbac
+- ../manager
+# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
+# crd/kustomization.yaml
+#- ../webhook
+# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required.
+#- ../certmanager
+# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
+#- ../prometheus
+
+patchesStrategicMerge:
+# Protect the /metrics endpoint by putting it behind auth.
+# If you want your controller-manager to expose the /metrics
+# endpoint w/o any authn/z, please comment the following line.
+- manager_auth_proxy_patch.yaml
+
+# Mount the controller config file for loading manager configurations
+# through a ComponentConfig type
+{{ if not .ComponentConfig }}#{{ end }}- manager_config_patch.yaml
+
+# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
+# crd/kustomization.yaml
+#- manager_webhook_patch.yaml
+
+# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'.
+# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks.
+# 'CERTMANAGER' needs to be enabled to use ca injection
+#- webhookcainjection_patch.yaml
+
+# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix.
+# Uncomment the following replacements to add the cert-manager CA injection annotations
+#replacements:
+# - source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# name: serving-cert # this name should match the one in certificate.yaml
+# fieldPath: .metadata.namespace # namespace of the certificate CR
+# targets:
+# - select:
+# kind: ValidatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 0
+# - select:
+# kind: MutatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 0
+# - select:
+# kind: CustomResourceDefinition
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 0
+# - source:
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# name: serving-cert # this name should match the one in certificate.yaml
+# fieldPath: .metadata.name
+# targets:
+# - select:
+# kind: ValidatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 1
+# - select:
+# kind: MutatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 1
+# - select:
+# kind: CustomResourceDefinition
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 1
+# - source: # Add cert-manager annotation to the webhook Service
+# kind: Service
+# version: v1
+# name: webhook-service
+# fieldPath: .metadata.name # namespace of the service
+# targets:
+# - select:
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# fieldPaths:
+# - .spec.dnsNames.0
+# - .spec.dnsNames.1
+# options:
+# delimiter: '.'
+# index: 0
+# - source:
+# kind: Service
+# version: v1
+# name: webhook-service
+# fieldPath: .metadata.namespace # namespace of the service
+# targets:
+# - select:
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# fieldPaths:
+# - .spec.dnsNames.0
+# - .spec.dnsNames.1
+# options:
+# delimiter: '.'
+# index: 1
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go
new file mode 100644
index 00000000000..7b44ee7f867
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go
@@ -0,0 +1,82 @@
+/*
+Copyright 2020 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 kdefault
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &ManagerAuthProxyPatch{}
+
+// ManagerAuthProxyPatch scaffolds a file that defines the patch that enables prometheus metrics for the manager
+type ManagerAuthProxyPatch struct {
+ machinery.TemplateMixin
+ machinery.ComponentConfigMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *ManagerAuthProxyPatch) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "default", "manager_auth_proxy_patch.yaml")
+ }
+
+ f.TemplateBody = kustomizeAuthProxyPatchTemplate
+
+ f.IfExistsAction = machinery.Error
+
+ return nil
+}
+
+const kustomizeAuthProxyPatchTemplate = `# This patch inject a sidecar container which is a HTTP proxy for the
+# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews.
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: controller-manager
+ namespace: system
+spec:
+ template:
+ spec:
+ containers:
+ - name: kube-rbac-proxy
+ image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0
+ args:
+ - "--secure-listen-address=0.0.0.0:8443"
+ - "--upstream=http://127.0.0.1:8080/"
+ - "--logtostderr=true"
+ - "--v=0"
+ ports:
+ - containerPort: 8443
+ protocol: TCP
+ name: https
+ resources:
+ limits:
+ cpu: 500m
+ memory: 128Mi
+ requests:
+ cpu: 5m
+ memory: 64Mi
+{{- if not .ComponentConfig }}
+ - name: manager
+ args:
+ - "--health-probe-bind-address=:8081"
+ - "--metrics-bind-address=127.0.0.1:8080"
+ - "--leader-elect"
+{{- end }}
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/manager_config_patch.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/manager_config_patch.go
new file mode 100644
index 00000000000..fb620573bbe
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/manager_config_patch.go
@@ -0,0 +1,63 @@
+/*
+Copyright 2020 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 kdefault
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &ManagerConfigPatch{}
+
+// ManagerConfigPatch scaffolds a ManagerConfigPatch for a Resource
+type ManagerConfigPatch struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements input.Template
+func (f *ManagerConfigPatch) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "default", "manager_config_patch.yaml")
+ }
+
+ f.TemplateBody = managerConfigPatchTemplate
+
+ return nil
+}
+
+const managerConfigPatchTemplate = `apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: controller-manager
+ namespace: system
+spec:
+ template:
+ spec:
+ containers:
+ - name: manager
+ args:
+ - "--config=controller_manager_config.yaml"
+ volumeMounts:
+ - name: manager-config
+ mountPath: /controller_manager_config.yaml
+ subPath: controller_manager_config.yaml
+ volumes:
+ - name: manager-config
+ configMap:
+ name: manager-config
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go
new file mode 100644
index 00000000000..7f993dbd31c
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go
@@ -0,0 +1,75 @@
+/*
+Copyright 2020 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 kdefault
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &ManagerWebhookPatch{}
+
+// ManagerWebhookPatch scaffolds a file that defines the patch that enables webhooks on the manager
+type ManagerWebhookPatch struct {
+ machinery.TemplateMixin
+
+ Force bool
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *ManagerWebhookPatch) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "default", "manager_webhook_patch.yaml")
+ }
+
+ f.TemplateBody = managerWebhookPatchTemplate
+
+ if f.Force {
+ f.IfExistsAction = machinery.OverwriteFile
+ } else {
+ // If file exists (ex. because a webhook was already created), skip creation.
+ f.IfExistsAction = machinery.SkipFile
+ }
+
+ return nil
+}
+
+const managerWebhookPatchTemplate = `apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: controller-manager
+ namespace: system
+spec:
+ template:
+ spec:
+ containers:
+ - name: manager
+ ports:
+ - containerPort: 9443
+ name: webhook-server
+ protocol: TCP
+ volumeMounts:
+ - mountPath: /tmp/k8s-webhook-server/serving-certs
+ name: cert
+ readOnly: true
+ volumes:
+ - name: cert
+ secret:
+ defaultMode: 420
+ secretName: webhook-server-cert
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/config.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/config.go
new file mode 100644
index 00000000000..1c9e6842dfd
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/config.go
@@ -0,0 +1,109 @@
+/*
+Copyright 2020 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 manager
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &Config{}
+
+// Config scaffolds a file that defines the namespace and the manager deployment
+type Config struct {
+ machinery.TemplateMixin
+ machinery.ComponentConfigMixin
+
+ // Image is controller manager image name
+ Image string
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *Config) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "manager", "manager.yaml")
+ }
+
+ f.TemplateBody = configTemplate
+
+ return nil
+}
+
+const configTemplate = `apiVersion: v1
+kind: Namespace
+metadata:
+ labels:
+ control-plane: controller-manager
+ name: system
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: controller-manager
+ namespace: system
+ labels:
+ control-plane: controller-manager
+spec:
+ selector:
+ matchLabels:
+ control-plane: controller-manager
+ replicas: 1
+ template:
+ metadata:
+ annotations:
+ kubectl.kubernetes.io/default-container: manager
+ labels:
+ control-plane: controller-manager
+ spec:
+ securityContext:
+ runAsNonRoot: true
+ containers:
+ - command:
+ - /manager
+{{- if not .ComponentConfig }}
+ args:
+ - --leader-elect
+{{- end }}
+ image: {{ .Image }}
+ name: manager
+ securityContext:
+ allowPrivilegeEscalation: false
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: 8081
+ initialDelaySeconds: 15
+ periodSeconds: 20
+ readinessProbe:
+ httpGet:
+ path: /readyz
+ port: 8081
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ # TODO(user): Configure the resources accordingly based on the project requirements.
+ # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+ resources:
+ limits:
+ cpu: 500m
+ memory: 128Mi
+ requests:
+ cpu: 10m
+ memory: 64Mi
+ serviceAccountName: controller-manager
+ terminationGracePeriodSeconds: 10
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/controller_manager_config.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/controller_manager_config.go
new file mode 100644
index 00000000000..fa977d90ecb
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/controller_manager_config.go
@@ -0,0 +1,58 @@
+/*
+Copyright 2020 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 manager
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &ControllerManagerConfig{}
+
+// ControllerManagerConfig scaffolds the config file in config/manager folder.
+type ControllerManagerConfig struct {
+ machinery.TemplateMixin
+ machinery.DomainMixin
+ machinery.RepositoryMixin
+}
+
+// SetTemplateDefaults implements input.Template
+func (f *ControllerManagerConfig) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "manager", "controller_manager_config.yaml")
+ }
+
+ f.TemplateBody = controllerManagerConfigTemplate
+
+ f.IfExistsAction = machinery.Error
+
+ return nil
+}
+
+const controllerManagerConfigTemplate = `apiVersion: controller-runtime.sigs.k8s.io/v1alpha1
+kind: ControllerManagerConfig
+health:
+ healthProbeBindAddress: :8081
+metrics:
+ bindAddress: 127.0.0.1:8080
+webhook:
+ port: 9443
+leaderElection:
+ leaderElect: true
+ resourceName: {{ hashFNV .Repo }}.{{ .Domain }}
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/kustomization.go
new file mode 100644
index 00000000000..eec807da3d1
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/kustomization.go
@@ -0,0 +1,55 @@
+/*
+Copyright 2020 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 manager
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &Kustomization{}
+
+// Kustomization scaffolds a file that defines the kustomization scheme for the manager folder
+type Kustomization struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *Kustomization) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "manager", "kustomization.yaml")
+ }
+
+ f.TemplateBody = kustomizeManagerTemplate
+
+ f.IfExistsAction = machinery.Error
+
+ return nil
+}
+
+const kustomizeManagerTemplate = `resources:
+- manager.yaml
+
+generatorOptions:
+ disableNameSuffixHash: true
+
+configMapGenerator:
+- name: manager-config
+ files:
+ - controller_manager_config.yaml
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/kustomization.go
new file mode 100644
index 00000000000..76bf6e1c5e1
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/kustomization.go
@@ -0,0 +1,45 @@
+/*
+Copyright 2020 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 prometheus
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &Kustomization{}
+
+// Kustomization scaffolds a file that defines the kustomization scheme for the prometheus folder
+type Kustomization struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *Kustomization) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "prometheus", "kustomization.yaml")
+ }
+
+ f.TemplateBody = kustomizationTemplate
+
+ return nil
+}
+
+const kustomizationTemplate = `resources:
+- monitor.yaml
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/monitor.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/monitor.go
new file mode 100644
index 00000000000..261282075ec
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/monitor.go
@@ -0,0 +1,63 @@
+/*
+Copyright 2020 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 prometheus
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &Monitor{}
+
+// Monitor scaffolds a file that defines the prometheus service monitor
+type Monitor struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *Monitor) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "prometheus", "monitor.yaml")
+ }
+
+ f.TemplateBody = serviceMonitorTemplate
+
+ return nil
+}
+
+const serviceMonitorTemplate = `
+# Prometheus Monitor Service (Metrics)
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ labels:
+ control-plane: controller-manager
+ name: controller-manager-metrics-monitor
+ namespace: system
+spec:
+ endpoints:
+ - path: /metrics
+ port: https
+ scheme: https
+ bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
+ tlsConfig:
+ insecureSkipVerify: true
+ selector:
+ matchLabels:
+ control-plane: controller-manager
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_client_role.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_client_role.go
new file mode 100644
index 00000000000..75cbeac0b90
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_client_role.go
@@ -0,0 +1,52 @@
+/*
+Copyright 2020 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 rbac
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &AuthProxyClientRole{}
+
+// AuthProxyClientRole scaffolds a file that defines the role for the metrics reader
+type AuthProxyClientRole struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *AuthProxyClientRole) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "rbac", "auth_proxy_client_clusterrole.yaml")
+ }
+
+ f.TemplateBody = clientClusterRoleTemplate
+
+ return nil
+}
+
+const clientClusterRoleTemplate = `apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: metrics-reader
+rules:
+- nonResourceURLs:
+ - "/metrics"
+ verbs:
+ - get
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role.go
new file mode 100644
index 00000000000..1b7780920d6
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role.go
@@ -0,0 +1,60 @@
+/*
+Copyright 2020 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 rbac
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &AuthProxyRole{}
+
+// AuthProxyRole scaffolds a file that defines the role for the auth proxy
+type AuthProxyRole struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *AuthProxyRole) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "rbac", "auth_proxy_role.yaml")
+ }
+
+ f.TemplateBody = proxyRoleTemplate
+
+ return nil
+}
+
+const proxyRoleTemplate = `apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: proxy-role
+rules:
+- apiGroups:
+ - authentication.k8s.io
+ resources:
+ - tokenreviews
+ verbs:
+ - create
+- apiGroups:
+ - authorization.k8s.io
+ resources:
+ - subjectaccessreviews
+ verbs:
+ - create
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role_binding.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role_binding.go
new file mode 100644
index 00000000000..9bbc09da9a2
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role_binding.go
@@ -0,0 +1,55 @@
+/*
+Copyright 2020 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 rbac
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &AuthProxyRoleBinding{}
+
+// AuthProxyRoleBinding scaffolds a file that defines the role binding for the auth proxy
+type AuthProxyRoleBinding struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *AuthProxyRoleBinding) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "rbac", "auth_proxy_role_binding.yaml")
+ }
+
+ f.TemplateBody = proxyRoleBindinggTemplate
+
+ return nil
+}
+
+const proxyRoleBindinggTemplate = `apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: proxy-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: proxy-role
+subjects:
+- kind: ServiceAccount
+ name: controller-manager
+ namespace: system
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_service.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_service.go
new file mode 100644
index 00000000000..66b99461de8
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/auth_proxy_service.go
@@ -0,0 +1,58 @@
+/*
+Copyright 2020 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 rbac
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &AuthProxyService{}
+
+// AuthProxyService scaffolds a file that defines the service for the auth proxy
+type AuthProxyService struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *AuthProxyService) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "rbac", "auth_proxy_service.yaml")
+ }
+
+ f.TemplateBody = authProxyServiceTemplate
+
+ return nil
+}
+
+const authProxyServiceTemplate = `apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ control-plane: controller-manager
+ name: controller-manager-metrics-service
+ namespace: system
+spec:
+ ports:
+ - name: https
+ port: 8443
+ protocol: TCP
+ targetPort: https
+ selector:
+ control-plane: controller-manager
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_editor_role.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_editor_role.go
new file mode 100644
index 00000000000..ebd32254be7
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_editor_role.go
@@ -0,0 +1,75 @@
+/*
+Copyright 2020 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 rbac
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &CRDEditorRole{}
+
+// CRDEditorRole scaffolds a file that defines the role that allows to edit plurals
+type CRDEditorRole struct {
+ machinery.TemplateMixin
+ machinery.MultiGroupMixin
+ machinery.ResourceMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *CRDEditorRole) SetTemplateDefaults() error {
+ if f.Path == "" {
+ if f.MultiGroup {
+ f.Path = filepath.Join("config", "rbac", "%[group]_%[kind]_editor_role.yaml")
+ } else {
+ f.Path = filepath.Join("config", "rbac", "%[kind]_editor_role.yaml")
+ }
+
+ }
+ f.Path = f.Resource.Replacer().Replace(f.Path)
+
+ f.TemplateBody = crdRoleEditorTemplate
+
+ return nil
+}
+
+const crdRoleEditorTemplate = `# permissions for end users to edit {{ .Resource.Plural }}.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ lower .Resource.Kind }}-editor-role
+rules:
+- apiGroups:
+ - {{ .Resource.QualifiedGroup }}
+ resources:
+ - {{ .Resource.Plural }}
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - {{ .Resource.QualifiedGroup }}
+ resources:
+ - {{ .Resource.Plural }}/status
+ verbs:
+ - get
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_viewer_role.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_viewer_role.go
new file mode 100644
index 00000000000..ba9edfca951
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_viewer_role.go
@@ -0,0 +1,71 @@
+/*
+Copyright 2020 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 rbac
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &CRDViewerRole{}
+
+// CRDViewerRole scaffolds a file that defines the role that allows to view plurals
+type CRDViewerRole struct {
+ machinery.TemplateMixin
+ machinery.MultiGroupMixin
+ machinery.ResourceMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *CRDViewerRole) SetTemplateDefaults() error {
+ if f.Path == "" {
+ if f.MultiGroup {
+ f.Path = filepath.Join("config", "rbac", "%[group]_%[kind]_viewer_role.yaml")
+ } else {
+ f.Path = filepath.Join("config", "rbac", "%[kind]_viewer_role.yaml")
+ }
+
+ }
+ f.Path = f.Resource.Replacer().Replace(f.Path)
+
+ f.TemplateBody = crdRoleViewerTemplate
+
+ return nil
+}
+
+const crdRoleViewerTemplate = `# permissions for end users to view {{ .Resource.Plural }}.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ lower .Resource.Kind }}-viewer-role
+rules:
+- apiGroups:
+ - {{ .Resource.QualifiedGroup }}
+ resources:
+ - {{ .Resource.Plural }}
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - {{ .Resource.QualifiedGroup }}
+ resources:
+ - {{ .Resource.Plural }}/status
+ verbs:
+ - get
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/kustomization.go
new file mode 100644
index 00000000000..d3ea9b22fd9
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/kustomization.go
@@ -0,0 +1,63 @@
+/*
+Copyright 2020 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 rbac
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &Kustomization{}
+
+// Kustomization scaffolds a file that defines the kustomization scheme for the rbac folder
+type Kustomization struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *Kustomization) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "rbac", "kustomization.yaml")
+ }
+
+ f.TemplateBody = kustomizeRBACTemplate
+
+ f.IfExistsAction = machinery.Error
+
+ return nil
+}
+
+const kustomizeRBACTemplate = `resources:
+# All RBAC will be applied under this service account in
+# the deployment namespace. You may comment out this resource
+# if your manager will use a service account that exists at
+# runtime. Be sure to update RoleBinding and ClusterRoleBinding
+# subjects if changing service account names.
+- service_account.yaml
+- role.yaml
+- role_binding.yaml
+- leader_election_role.yaml
+- leader_election_role_binding.yaml
+# Comment the following 4 lines if you want to disable
+# the auth proxy (https://github.com/brancz/kube-rbac-proxy)
+# which protects your /metrics endpoint.
+- auth_proxy_service.yaml
+- auth_proxy_role.yaml
+- auth_proxy_role_binding.yaml
+- auth_proxy_client_clusterrole.yaml
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/leader_election_role.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/leader_election_role.go
new file mode 100644
index 00000000000..8a510637c04
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/leader_election_role.go
@@ -0,0 +1,80 @@
+/*
+Copyright 2020 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 rbac
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &LeaderElectionRole{}
+
+// LeaderElectionRole scaffolds a file that defines the role that allows leader election
+type LeaderElectionRole struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *LeaderElectionRole) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "rbac", "leader_election_role.yaml")
+ }
+
+ f.TemplateBody = leaderElectionRoleTemplate
+
+ return nil
+}
+
+const leaderElectionRoleTemplate = `# permissions to do leader election.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: leader-election-role
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - configmaps
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - coordination.k8s.io
+ resources:
+ - leases
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - patch
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/leader_election_role_binding.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/leader_election_role_binding.go
new file mode 100644
index 00000000000..8148f9ab393
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/leader_election_role_binding.go
@@ -0,0 +1,55 @@
+/*
+Copyright 2020 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 rbac
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &LeaderElectionRoleBinding{}
+
+// LeaderElectionRoleBinding scaffolds a file that defines the role binding that allows leader election
+type LeaderElectionRoleBinding struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *LeaderElectionRoleBinding) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "rbac", "leader_election_role_binding.yaml")
+ }
+
+ f.TemplateBody = leaderElectionRoleBindingTemplate
+
+ return nil
+}
+
+const leaderElectionRoleBindingTemplate = `apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: leader-election-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: leader-election-role
+subjects:
+- kind: ServiceAccount
+ name: controller-manager
+ namespace: system
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/role_binding.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/role_binding.go
new file mode 100644
index 00000000000..9473660e03c
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/role_binding.go
@@ -0,0 +1,55 @@
+/*
+Copyright 2020 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 rbac
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &RoleBinding{}
+
+// RoleBinding scaffolds a file that defines the role binding for the manager
+type RoleBinding struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *RoleBinding) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "rbac", "role_binding.yaml")
+ }
+
+ f.TemplateBody = managerBindingTemplate
+
+ return nil
+}
+
+const managerBindingTemplate = `apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: manager-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: manager-role
+subjects:
+- kind: ServiceAccount
+ name: controller-manager
+ namespace: system
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/service_account.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/service_account.go
new file mode 100644
index 00000000000..8c772b3a748
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/service_account.go
@@ -0,0 +1,48 @@
+/*
+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 rbac
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &ServiceAccount{}
+
+// ServiceAccount scaffolds a file that defines the service account the manager is deployed in.
+type ServiceAccount struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *ServiceAccount) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "rbac", "service_account.yaml")
+ }
+
+ f.TemplateBody = serviceAccountTemplate
+
+ return nil
+}
+
+const serviceAccountTemplate = `apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: controller-manager
+ namespace: system
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/samples/crd_sample.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/samples/crd_sample.go
new file mode 100644
index 00000000000..3d83cd8fd9d
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/samples/crd_sample.go
@@ -0,0 +1,59 @@
+/*
+Copyright 2020 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 samples
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &CRDSample{}
+
+// CRDSample scaffolds a file that defines a sample manifest for the CRD
+type CRDSample struct {
+ machinery.TemplateMixin
+ machinery.ResourceMixin
+
+ Force bool
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *CRDSample) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "samples", "%[group]_%[version]_%[kind].yaml")
+ }
+ f.Path = f.Resource.Replacer().Replace(f.Path)
+
+ if f.Force {
+ f.IfExistsAction = machinery.OverwriteFile
+ } else {
+ f.IfExistsAction = machinery.Error
+ }
+
+ f.TemplateBody = crdSampleTemplate
+
+ return nil
+}
+
+const crdSampleTemplate = `apiVersion: {{ .Resource.QualifiedGroup }}/{{ .Resource.Version }}
+kind: {{ .Resource.Kind }}
+metadata:
+ name: {{ lower .Resource.Kind }}-sample
+spec:
+ # TODO(user): Add fields here
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/kustomization.go
new file mode 100644
index 00000000000..3f55f70a12f
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/kustomization.go
@@ -0,0 +1,59 @@
+/*
+Copyright 2020 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 webhook
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &Kustomization{}
+
+// Kustomization scaffolds a file that defines the kustomization scheme for the webhook folder
+type Kustomization struct {
+ machinery.TemplateMixin
+ machinery.ResourceMixin
+
+ Force bool
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *Kustomization) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "webhook", "kustomization.yaml")
+ }
+
+ f.TemplateBody = kustomizeWebhookTemplate
+
+ if f.Force {
+ f.IfExistsAction = machinery.OverwriteFile
+ } else {
+ // If file exists (ex. because a webhook was already created), skip creation.
+ f.IfExistsAction = machinery.SkipFile
+ }
+
+ return nil
+}
+
+const kustomizeWebhookTemplate = `resources:
+- manifests{{ if ne .Resource.Webhooks.WebhookVersion "v1" }}.{{ .Resource.Webhooks.WebhookVersion }}{{ end }}.yaml
+- service.yaml
+
+configurations:
+- kustomizeconfig.yaml
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/kustomizeconfig.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/kustomizeconfig.go
new file mode 100644
index 00000000000..524f11e71c1
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/kustomizeconfig.go
@@ -0,0 +1,72 @@
+/*
+Copyright 2020 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 webhook
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &KustomizeConfig{}
+
+// KustomizeConfig scaffolds a file that configures the kustomization for the webhook folder
+type KustomizeConfig struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *KustomizeConfig) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "webhook", "kustomizeconfig.yaml")
+ }
+
+ f.TemplateBody = kustomizeConfigWebhookTemplate
+
+ // If file exists (ex. because a webhook was already created), skip creation.
+ f.IfExistsAction = machinery.SkipFile
+
+ return nil
+}
+
+//nolint:lll
+const kustomizeConfigWebhookTemplate = `# the following config is for teaching kustomize where to look at when substituting vars.
+# It requires kustomize v2.1.0 or newer to work properly.
+nameReference:
+- kind: Service
+ version: v1
+ fieldSpecs:
+ - kind: MutatingWebhookConfiguration
+ group: admissionregistration.k8s.io
+ path: webhooks/clientConfig/service/name
+ - kind: ValidatingWebhookConfiguration
+ group: admissionregistration.k8s.io
+ path: webhooks/clientConfig/service/name
+
+namespace:
+- kind: MutatingWebhookConfiguration
+ group: admissionregistration.k8s.io
+ path: webhooks/clientConfig/service/namespace
+ create: true
+- kind: ValidatingWebhookConfiguration
+ group: admissionregistration.k8s.io
+ path: webhooks/clientConfig/service/namespace
+ create: true
+
+varReference:
+- path: metadata/annotations
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/service.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/service.go
new file mode 100644
index 00000000000..35741bdd7d4
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/service.go
@@ -0,0 +1,59 @@
+/*
+Copyright 2020 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 webhook
+
+import (
+ "path/filepath"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+)
+
+var _ machinery.Template = &Service{}
+
+// Service scaffolds a file that defines the webhook service
+type Service struct {
+ machinery.TemplateMixin
+}
+
+// SetTemplateDefaults implements file.Template
+func (f *Service) SetTemplateDefaults() error {
+ if f.Path == "" {
+ f.Path = filepath.Join("config", "webhook", "service.yaml")
+ }
+
+ f.TemplateBody = serviceTemplate
+
+ // If file exists (ex. because a webhook was already created), skip creation.
+ f.IfExistsAction = machinery.SkipFile
+
+ return nil
+}
+
+const serviceTemplate = `
+apiVersion: v1
+kind: Service
+metadata:
+ name: webhook-service
+ namespace: system
+spec:
+ ports:
+ - port: 443
+ protocol: TCP
+ targetPort: 9443
+ selector:
+ control-plane: controller-manager
+`
diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/webhook.go b/pkg/plugins/common/kustomize/v2/scaffolds/webhook.go
new file mode 100644
index 00000000000..422e198fc8d
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/scaffolds/webhook.go
@@ -0,0 +1,84 @@
+/*
+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 scaffolds
+
+import (
+ "fmt"
+
+ "sigs.k8s.io/kubebuilder/v3/pkg/config"
+ "sigs.k8s.io/kubebuilder/v3/pkg/machinery"
+ "sigs.k8s.io/kubebuilder/v3/pkg/model/resource"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook"
+)
+
+var _ plugins.Scaffolder = &webhookScaffolder{}
+
+type webhookScaffolder struct {
+ config config.Config
+ resource resource.Resource
+
+ // fs is the filesystem that will be used by the scaffolder
+ fs machinery.Filesystem
+
+ // force indicates whether to scaffold files even if they exist.
+ force bool
+}
+
+// NewWebhookScaffolder returns a new Scaffolder for v2 webhook creation operations
+func NewWebhookScaffolder(config config.Config, resource resource.Resource, force bool) plugins.Scaffolder {
+ return &webhookScaffolder{
+ config: config,
+ resource: resource,
+ force: force,
+ }
+}
+
+// InjectFS implements cmdutil.Scaffolder
+func (s *webhookScaffolder) InjectFS(fs machinery.Filesystem) { s.fs = fs }
+
+// Scaffold implements cmdutil.Scaffolder
+func (s *webhookScaffolder) Scaffold() error {
+ fmt.Println("Writing kustomize manifests for you to edit...")
+
+ // Initialize the machinery.Scaffold that will write the files to disk
+ scaffold := machinery.NewScaffold(s.fs,
+ machinery.WithConfig(s.config),
+ machinery.WithResource(&s.resource),
+ )
+
+ if err := s.config.UpdateResource(s.resource); err != nil {
+ return fmt.Errorf("error updating resource: %w", err)
+ }
+
+ if err := scaffold.Execute(
+ &kdefault.WebhookCAInjectionPatch{},
+ &kdefault.ManagerWebhookPatch{},
+ &webhook.Kustomization{Force: s.force},
+ &webhook.KustomizeConfig{},
+ &webhook.Service{},
+ &certmanager.Certificate{},
+ &certmanager.Kustomization{},
+ &certmanager.KustomizeConfig{},
+ ); err != nil {
+ return fmt.Errorf("error scaffolding kustomize webhook manifests: %v", err)
+ }
+
+ return nil
+}
diff --git a/pkg/plugins/common/kustomize/v2/webhook.go b/pkg/plugins/common/kustomize/v2/webhook.go
new file mode 100644
index 00000000000..d7964b2c086
--- /dev/null
+++ b/pkg/plugins/common/kustomize/v2/webhook.go
@@ -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.CreateWebhookSubcommand = &createWebhookSubcommand{}
+
+type createWebhookSubcommand struct {
+ createSubcommand
+}
+
+func (p *createWebhookSubcommand) Scaffold(fs machinery.Filesystem) error {
+ if err := p.configure(); err != nil {
+ return err
+ }
+ scaffolder := scaffolds.NewWebhookScaffolder(p.config, *p.resource, p.force)
+ scaffolder.InjectFS(fs)
+ return scaffolder.Scaffold()
+}
diff --git a/pkg/plugins/golang/v3/scaffolds/init.go b/pkg/plugins/golang/v3/scaffolds/init.go
index a109771ad65..de30c14d8da 100644
--- a/pkg/plugins/golang/v3/scaffolds/init.go
+++ b/pkg/plugins/golang/v3/scaffolds/init.go
@@ -19,11 +19,15 @@ package scaffolds
import (
"fmt"
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugin"
+
"github.com/spf13/afero"
"sigs.k8s.io/kubebuilder/v3/pkg/config"
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins"
+ 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/v3/scaffolds/internal/templates"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/hack"
)
@@ -33,14 +37,14 @@ const (
ControllerRuntimeVersion = "v0.11.0"
// ControllerToolsVersion is the kubernetes-sigs/controller-tools version to be used in the project
ControllerToolsVersion = "v0.8.0"
- // KustomizeVersion is the kubernetes-sigs/kustomize version to be used in the project
- KustomizeVersion = "v3.8.7"
imageName = "controller:latest"
)
var _ plugins.Scaffolder = &initScaffolder{}
+var kustomizeVersion string
+
type initScaffolder struct {
config config.Config
boilerplatePath string
@@ -97,6 +101,20 @@ func (s *initScaffolder) Scaffold() error {
machinery.WithBoilerplate(string(boilerplate)),
)
+ // If the KustomizeV2 was used to do the scaffold then
+ // we need to ensure that we use its supported Kustomize Version
+ // in order to support it
+ kustomizeVersion = kustomizecommonv1.KustomizeVersion
+ kustomizev2 := kustomizecommonv2.Plugin{}
+ pluginKeyForKustomizeV2 := plugin.KeyFor(kustomizev2)
+
+ for _, pluginKey := range s.config.GetPluginChain() {
+ if pluginKey == pluginKeyForKustomizeV2 {
+ kustomizeVersion = kustomizecommonv2.KustomizeVersion
+ break
+ }
+ }
+
return scaffold.Execute(
&templates.Main{},
&templates.GoMod{
@@ -107,7 +125,7 @@ func (s *initScaffolder) Scaffold() error {
Image: imageName,
BoilerplatePath: s.boilerplatePath,
ControllerToolsVersion: ControllerToolsVersion,
- KustomizeVersion: KustomizeVersion,
+ KustomizeVersion: kustomizeVersion,
ControllerRuntimeVersion: ControllerRuntimeVersion,
},
&templates.Dockerfile{},
diff --git a/test/e2e/v3/generate_test.go b/test/e2e/v3/generate_test.go
index 0840b1ab2e4..4def9abc492 100644
--- a/test/e2e/v3/generate_test.go
+++ b/test/e2e/v3/generate_test.go
@@ -229,3 +229,164 @@ Count int `+"`"+`json:"count,omitempty"`+"`"+`
_ = pluginutil.RunCmd("Update dependencies", "go", "mod", "tidy")
}
}
+
+// GenerateV3 implements a go/v3(-alpha) plugin project defined by a TestContext.
+func GenerateV3WithKustomizeV2(kbc *utils.TestContext, crdAndWebhookVersion string) {
+ var err error
+
+ By("initializing a project")
+ err = kbc.Init(
+ "--plugins", "kustomize/v2-alpha,base.go.kubebuilder.io/v3",
+ "--project-version", "3",
+ "--domain", kbc.Domain,
+ "--fetch-deps=false",
+ )
+ ExpectWithOffset(1, err).NotTo(HaveOccurred())
+
+ By("creating API definition")
+ err = kbc.CreateAPI(
+ "--group", kbc.Group,
+ "--version", kbc.Version,
+ "--kind", kbc.Kind,
+ "--namespaced",
+ "--resource",
+ "--controller",
+ "--make=false",
+ "--crd-version", crdAndWebhookVersion,
+ )
+ ExpectWithOffset(1, err).NotTo(HaveOccurred())
+
+ By("implementing the API")
+ ExpectWithOffset(1, pluginutil.InsertCode(
+ filepath.Join(kbc.Dir, "api", kbc.Version, fmt.Sprintf("%s_types.go", strings.ToLower(kbc.Kind))),
+ fmt.Sprintf(`type %sSpec struct {
+`, kbc.Kind),
+ ` // +optional
+Count int `+"`"+`json:"count,omitempty"`+"`"+`
+`)).Should(Succeed())
+
+ By("scaffolding mutating and validating webhooks")
+ err = kbc.CreateWebhook(
+ "--group", kbc.Group,
+ "--version", kbc.Version,
+ "--kind", kbc.Kind,
+ "--defaulting",
+ "--programmatic-validation",
+ "--webhook-version", crdAndWebhookVersion,
+ )
+ ExpectWithOffset(1, err).NotTo(HaveOccurred())
+
+ By("implementing the mutating and validating webhooks")
+ err = pluginutil.ImplementWebhooks(filepath.Join(
+ kbc.Dir, "api", kbc.Version,
+ fmt.Sprintf("%s_webhook.go", strings.ToLower(kbc.Kind))))
+ ExpectWithOffset(1, err).NotTo(HaveOccurred())
+
+ By("uncomment kustomization.yaml to enable webhook and ca injection")
+ ExpectWithOffset(1, pluginutil.UncommentCode(
+ filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"),
+ "#- ../webhook", "#")).To(Succeed())
+ ExpectWithOffset(1, pluginutil.UncommentCode(
+ filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"),
+ "#- ../certmanager", "#")).To(Succeed())
+ ExpectWithOffset(1, pluginutil.UncommentCode(
+ filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"),
+ "#- ../prometheus", "#")).To(Succeed())
+ ExpectWithOffset(1, pluginutil.UncommentCode(
+ filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"),
+ "#- manager_webhook_patch.yaml", "#")).To(Succeed())
+ ExpectWithOffset(1, pluginutil.UncommentCode(
+ filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"),
+ "#- webhookcainjection_patch.yaml", "#")).To(Succeed())
+ ExpectWithOffset(1, pluginutil.UncommentCode(filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"),
+ `#replacements:
+# - source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# name: serving-cert # this name should match the one in certificate.yaml
+# fieldPath: .metadata.namespace # namespace of the certificate CR
+# targets:
+# - select:
+# kind: ValidatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 0
+# - select:
+# kind: MutatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 0
+# - select:
+# kind: CustomResourceDefinition
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 0
+# - source:
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# name: serving-cert # this name should match the one in certificate.yaml
+# fieldPath: .metadata.name
+# targets:
+# - select:
+# kind: ValidatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 1
+# - select:
+# kind: MutatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 1
+# - select:
+# kind: CustomResourceDefinition
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 1
+# - source: # Add cert-manager annotation to the webhook Service
+# kind: Service
+# version: v1
+# name: webhook-service
+# fieldPath: .metadata.name # namespace of the service
+# targets:
+# - select:
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# fieldPaths:
+# - .spec.dnsNames.0
+# - .spec.dnsNames.1
+# options:
+# delimiter: '.'
+# index: 0
+# - source:
+# kind: Service
+# version: v1
+# name: webhook-service
+# fieldPath: .metadata.namespace # namespace of the service
+# targets:
+# - select:
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# fieldPaths:
+# - .spec.dnsNames.0
+# - .spec.dnsNames.1
+# options:
+# delimiter: '.'
+# index: 1`, "#")).To(Succeed())
+
+}
diff --git a/test/e2e/v3/plugin_cluster_test.go b/test/e2e/v3/plugin_cluster_test.go
index a129abe2c42..5b7ed63ed3a 100644
--- a/test/e2e/v3/plugin_cluster_test.go
+++ b/test/e2e/v3/plugin_cluster_test.go
@@ -115,6 +115,15 @@ var _ = Describe("kubebuilder", func() {
GenerateV3(kbc, "v1")
Run(kbc)
})
+ It("should generate a runnable project with the golang base plugin v3 and kustomize v4-alpha", func() {
+ // Skip if cluster version < 1.16, when v1 CRDs and webhooks did not exist.
+ if srvVer := kbc.K8sVersion.ServerVersion; srvVer.GetMajorInt() <= 1 && srvVer.GetMinorInt() < 17 {
+ Skip(fmt.Sprintf("cluster version %s does not support v1 CRDs or webhooks", srvVer.GitVersion))
+ }
+
+ GenerateV3WithKustomizeV2(kbc, "v1")
+ Run(kbc)
+ })
It("should generate a runnable project with v1beta1 CRDs and Webhooks", func() {
// Skip if cluster version < 1.15, when `.spec.preserveUnknownFields` was not a v1beta1 CRD field.
// Skip if cluster version >= 1.22 because pre v1 CRDs and webhooks no longer exist.
diff --git a/test/testdata/generate.sh b/test/testdata/generate.sh
index 9296b2260b4..3885f4597ba 100755
--- a/test/testdata/generate.sh
+++ b/test/testdata/generate.sh
@@ -45,7 +45,7 @@ function scaffold_test_project {
header_text "Initializing project ..."
$kb init $init_flags --domain testproject.org --license apache2 --owner "The Kubernetes authors"
- if [ $project == "project-v2" ] || [ $project == "project-v3" ] || [ $project == "project-v3-config" ]; then
+ if [ $project == "project-v2" ] || [ $project == "project-v3" ] || [ $project == "project-v3-config" ] || [ $project == "project-v3-with-kustomize-v2" ]; then
header_text 'Creating APIs ...'
$kb create api --group crew --version v1 --kind Captain --controller=true --resource=true --make=false
$kb create api --group crew --version v1 --kind Captain --controller=true --resource=true --make=false --force
@@ -131,3 +131,4 @@ scaffold_test_project project-v3-multigroup
scaffold_test_project project-v3-addon --plugins="go/v3,declarative"
scaffold_test_project project-v3-config --component-config
scaffold_test_project project-v3-v1beta1
+scaffold_test_project project-v3-with-kustomize-v2 --plugins="kustomize/v2-alpha,base.go.kubebuilder.io/v3"
diff --git a/testdata/project-v3-with-kustomize-v2/.dockerignore b/testdata/project-v3-with-kustomize-v2/.dockerignore
new file mode 100644
index 00000000000..0f046820f18
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/.dockerignore
@@ -0,0 +1,4 @@
+# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file
+# Ignore build and test binaries.
+bin/
+testbin/
diff --git a/testdata/project-v3-with-kustomize-v2/.gitignore b/testdata/project-v3-with-kustomize-v2/.gitignore
new file mode 100644
index 00000000000..c0a7a54cac5
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/.gitignore
@@ -0,0 +1,25 @@
+
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+bin
+testbin/*
+
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Kubernetes Generated files - skip generated files, except for vendored files
+
+!vendor/**/zz_generated.*
+
+# editor and IDE paraphernalia
+.idea
+*.swp
+*.swo
+*~
diff --git a/testdata/project-v3-with-kustomize-v2/Dockerfile b/testdata/project-v3-with-kustomize-v2/Dockerfile
new file mode 100644
index 00000000000..456533d4c2d
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/Dockerfile
@@ -0,0 +1,27 @@
+# Build the manager binary
+FROM golang:1.17 as builder
+
+WORKDIR /workspace
+# Copy the Go Modules manifests
+COPY go.mod go.mod
+COPY go.sum go.sum
+# cache deps before building and copying source so that we don't need to re-download as much
+# and so that source changes don't invalidate our downloaded layer
+RUN go mod download
+
+# Copy the go source
+COPY main.go main.go
+COPY api/ api/
+COPY controllers/ controllers/
+
+# Build
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager main.go
+
+# Use distroless as minimal base image to package the manager binary
+# Refer to https://github.com/GoogleContainerTools/distroless for more details
+FROM gcr.io/distroless/static:nonroot
+WORKDIR /
+COPY --from=builder /workspace/manager .
+USER 65532:65532
+
+ENTRYPOINT ["/manager"]
diff --git a/testdata/project-v3-with-kustomize-v2/Makefile b/testdata/project-v3-with-kustomize-v2/Makefile
new file mode 100644
index 00000000000..b780252f1d9
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/Makefile
@@ -0,0 +1,133 @@
+
+# Image URL to use all building/pushing image targets
+IMG ?= controller:latest
+# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
+ENVTEST_K8S_VERSION = 1.23
+
+# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
+ifeq (,$(shell go env GOBIN))
+GOBIN=$(shell go env GOPATH)/bin
+else
+GOBIN=$(shell go env GOBIN)
+endif
+
+# Setting SHELL to bash allows bash commands to be executed by recipes.
+# This is a requirement for 'setup-envtest.sh' in the test target.
+# Options are set to exit when a recipe line exits non-zero or a piped command fails.
+SHELL = /usr/bin/env bash -o pipefail
+.SHELLFLAGS = -ec
+
+.PHONY: all
+all: build
+
+##@ General
+
+# The help target prints out all targets with their descriptions organized
+# beneath their categories. The categories are represented by '##@' and the
+# target descriptions by '##'. The awk commands is responsible for reading the
+# entire set of makefiles included in this invocation, looking for lines of the
+# file as xyz: ## something, and then pretty-format the target and help. Then,
+# if there's a line with ##@ something, that gets pretty-printed as a category.
+# More info on the usage of ANSI control characters for terminal formatting:
+# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
+# More info on the awk command:
+# http://linuxcommand.org/lc3_adv_awk.php
+
+.PHONY: help
+help: ## Display this help.
+ @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
+
+##@ Development
+
+.PHONY: manifests
+manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
+ $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
+
+.PHONY: generate
+generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
+ $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
+
+.PHONY: fmt
+fmt: ## Run go fmt against code.
+ go fmt ./...
+
+.PHONY: vet
+vet: ## Run go vet against code.
+ go vet ./...
+
+.PHONY: test
+test: manifests generate fmt vet envtest ## Run tests.
+ KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ./... -coverprofile cover.out
+
+##@ Build
+
+.PHONY: build
+build: generate fmt vet ## Build manager binary.
+ go build -o bin/manager main.go
+
+.PHONY: run
+run: manifests generate fmt vet ## Run a controller from your host.
+ go run ./main.go
+
+.PHONY: docker-build
+docker-build: test ## Build docker image with the manager.
+ docker build -t ${IMG} .
+
+.PHONY: docker-push
+docker-push: ## Push docker image with the manager.
+ docker push ${IMG}
+
+##@ Deployment
+
+ifndef ignore-not-found
+ ignore-not-found = false
+endif
+
+.PHONY: install
+install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
+ $(KUSTOMIZE) build config/crd | kubectl apply -f -
+
+.PHONY: uninstall
+uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
+ $(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
+
+.PHONY: deploy
+deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
+ cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
+ $(KUSTOMIZE) build config/default | kubectl apply -f -
+
+.PHONY: undeploy
+undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
+ $(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
+
+##@ Build Dependencies
+
+## Location to install dependencies to
+LOCALBIN ?= $(shell pwd)/bin
+$(LOCALBIN):
+ mkdir -p $(LOCALBIN)
+
+## Tool Binaries
+KUSTOMIZE ?= $(LOCALBIN)/kustomize
+CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
+ENVTEST ?= $(LOCALBIN)/setup-envtest
+
+## Tool Versions
+KUSTOMIZE_VERSION ?= v4.4.1
+CONTROLLER_TOOLS_VERSION ?= v0.8.0
+
+KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
+.PHONY: kustomize
+kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
+$(KUSTOMIZE): $(LOCALBIN)
+ curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN)
+
+.PHONY: controller-gen
+controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
+$(CONTROLLER_GEN): $(LOCALBIN)
+ GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
+
+.PHONY: envtest
+envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
+$(ENVTEST): $(LOCALBIN)
+ GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
diff --git a/testdata/project-v3-with-kustomize-v2/PROJECT b/testdata/project-v3-with-kustomize-v2/PROJECT
new file mode 100644
index 00000000000..2d6d3f73d52
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/PROJECT
@@ -0,0 +1,49 @@
+domain: testproject.org
+layout:
+- kustomize.common.kubebuilder.io/v2-alpha
+- base.go.kubebuilder.io/v3
+projectName: project-v3-with-kustomize-v2
+repo: sigs.k8s.io/kubebuilder/testdata/project-v3-with-kustomize-v2
+resources:
+- api:
+ crdVersion: v1
+ namespaced: true
+ controller: true
+ domain: testproject.org
+ group: crew
+ kind: Captain
+ path: sigs.k8s.io/kubebuilder/testdata/project-v3-with-kustomize-v2/api/v1
+ version: v1
+ webhooks:
+ defaulting: true
+ validation: true
+ webhookVersion: v1
+- api:
+ crdVersion: v1
+ namespaced: true
+ controller: true
+ domain: testproject.org
+ group: crew
+ kind: FirstMate
+ path: sigs.k8s.io/kubebuilder/testdata/project-v3-with-kustomize-v2/api/v1
+ version: v1
+ webhooks:
+ conversion: true
+ webhookVersion: v1
+- api:
+ crdVersion: v1
+ controller: true
+ domain: testproject.org
+ group: crew
+ kind: Admiral
+ path: sigs.k8s.io/kubebuilder/testdata/project-v3-with-kustomize-v2/api/v1
+ version: v1
+ webhooks:
+ defaulting: true
+ webhookVersion: v1
+- controller: true
+ domain: testproject.org
+ group: crew
+ kind: Laker
+ version: v1
+version: "3"
diff --git a/testdata/project-v3-with-kustomize-v2/api/v1/admiral_types.go b/testdata/project-v3-with-kustomize-v2/api/v1/admiral_types.go
new file mode 100644
index 00000000000..55d2b767089
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/api/v1/admiral_types.go
@@ -0,0 +1,65 @@
+/*
+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 v1
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
+// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
+
+// AdmiralSpec defines the desired state of Admiral
+type AdmiralSpec struct {
+ // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+
+ // Foo is an example field of Admiral. Edit admiral_types.go to remove/update
+ Foo string `json:"foo,omitempty"`
+}
+
+// AdmiralStatus defines the observed state of Admiral
+type AdmiralStatus struct {
+ // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+}
+
+//+kubebuilder:object:root=true
+//+kubebuilder:subresource:status
+//+kubebuilder:resource:scope=Cluster
+
+// Admiral is the Schema for the admirals API
+type Admiral struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec AdmiralSpec `json:"spec,omitempty"`
+ Status AdmiralStatus `json:"status,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+
+// AdmiralList contains a list of Admiral
+type AdmiralList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []Admiral `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&Admiral{}, &AdmiralList{})
+}
diff --git a/testdata/project-v3-with-kustomize-v2/api/v1/admiral_webhook.go b/testdata/project-v3-with-kustomize-v2/api/v1/admiral_webhook.go
new file mode 100644
index 00000000000..52fbc5ce79f
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/api/v1/admiral_webhook.go
@@ -0,0 +1,45 @@
+/*
+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 v1
+
+import (
+ ctrl "sigs.k8s.io/controller-runtime"
+ logf "sigs.k8s.io/controller-runtime/pkg/log"
+ "sigs.k8s.io/controller-runtime/pkg/webhook"
+)
+
+// log is for logging in this package.
+var admirallog = logf.Log.WithName("admiral-resource")
+
+func (r *Admiral) SetupWebhookWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewWebhookManagedBy(mgr).
+ For(r).
+ Complete()
+}
+
+// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
+
+//+kubebuilder:webhook:path=/mutate-crew-testproject-org-v1-admiral,mutating=true,failurePolicy=fail,sideEffects=None,groups=crew.testproject.org,resources=admirals,verbs=create;update,versions=v1,name=madmiral.kb.io,admissionReviewVersions=v1
+
+var _ webhook.Defaulter = &Admiral{}
+
+// Default implements webhook.Defaulter so a webhook will be registered for the type
+func (r *Admiral) Default() {
+ admirallog.Info("default", "name", r.Name)
+
+ // TODO(user): fill in your defaulting logic.
+}
diff --git a/testdata/project-v3-with-kustomize-v2/api/v1/captain_types.go b/testdata/project-v3-with-kustomize-v2/api/v1/captain_types.go
new file mode 100644
index 00000000000..e81debb719c
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/api/v1/captain_types.go
@@ -0,0 +1,64 @@
+/*
+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 v1
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
+// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
+
+// CaptainSpec defines the desired state of Captain
+type CaptainSpec struct {
+ // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+
+ // Foo is an example field of Captain. Edit captain_types.go to remove/update
+ Foo string `json:"foo,omitempty"`
+}
+
+// CaptainStatus defines the observed state of Captain
+type CaptainStatus struct {
+ // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+}
+
+//+kubebuilder:object:root=true
+//+kubebuilder:subresource:status
+
+// Captain is the Schema for the captains API
+type Captain struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec CaptainSpec `json:"spec,omitempty"`
+ Status CaptainStatus `json:"status,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+
+// CaptainList contains a list of Captain
+type CaptainList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []Captain `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&Captain{}, &CaptainList{})
+}
diff --git a/testdata/project-v3-with-kustomize-v2/api/v1/captain_webhook.go b/testdata/project-v3-with-kustomize-v2/api/v1/captain_webhook.go
new file mode 100644
index 00000000000..ba00000c137
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/api/v1/captain_webhook.go
@@ -0,0 +1,75 @@
+/*
+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 v1
+
+import (
+ "k8s.io/apimachinery/pkg/runtime"
+ ctrl "sigs.k8s.io/controller-runtime"
+ logf "sigs.k8s.io/controller-runtime/pkg/log"
+ "sigs.k8s.io/controller-runtime/pkg/webhook"
+)
+
+// log is for logging in this package.
+var captainlog = logf.Log.WithName("captain-resource")
+
+func (r *Captain) SetupWebhookWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewWebhookManagedBy(mgr).
+ For(r).
+ Complete()
+}
+
+// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
+
+//+kubebuilder:webhook:path=/mutate-crew-testproject-org-v1-captain,mutating=true,failurePolicy=fail,sideEffects=None,groups=crew.testproject.org,resources=captains,verbs=create;update,versions=v1,name=mcaptain.kb.io,admissionReviewVersions=v1
+
+var _ webhook.Defaulter = &Captain{}
+
+// Default implements webhook.Defaulter so a webhook will be registered for the type
+func (r *Captain) Default() {
+ captainlog.Info("default", "name", r.Name)
+
+ // TODO(user): fill in your defaulting logic.
+}
+
+// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
+//+kubebuilder:webhook:path=/validate-crew-testproject-org-v1-captain,mutating=false,failurePolicy=fail,sideEffects=None,groups=crew.testproject.org,resources=captains,verbs=create;update,versions=v1,name=vcaptain.kb.io,admissionReviewVersions=v1
+
+var _ webhook.Validator = &Captain{}
+
+// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
+func (r *Captain) ValidateCreate() error {
+ captainlog.Info("validate create", "name", r.Name)
+
+ // TODO(user): fill in your validation logic upon object creation.
+ return nil
+}
+
+// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
+func (r *Captain) ValidateUpdate(old runtime.Object) error {
+ captainlog.Info("validate update", "name", r.Name)
+
+ // TODO(user): fill in your validation logic upon object update.
+ return nil
+}
+
+// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
+func (r *Captain) ValidateDelete() error {
+ captainlog.Info("validate delete", "name", r.Name)
+
+ // TODO(user): fill in your validation logic upon object deletion.
+ return nil
+}
diff --git a/testdata/project-v3-with-kustomize-v2/api/v1/firstmate_types.go b/testdata/project-v3-with-kustomize-v2/api/v1/firstmate_types.go
new file mode 100644
index 00000000000..7515759833a
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/api/v1/firstmate_types.go
@@ -0,0 +1,64 @@
+/*
+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 v1
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
+// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
+
+// FirstMateSpec defines the desired state of FirstMate
+type FirstMateSpec struct {
+ // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+
+ // Foo is an example field of FirstMate. Edit firstmate_types.go to remove/update
+ Foo string `json:"foo,omitempty"`
+}
+
+// FirstMateStatus defines the observed state of FirstMate
+type FirstMateStatus struct {
+ // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+}
+
+//+kubebuilder:object:root=true
+//+kubebuilder:subresource:status
+
+// FirstMate is the Schema for the firstmates API
+type FirstMate struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec FirstMateSpec `json:"spec,omitempty"`
+ Status FirstMateStatus `json:"status,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+
+// FirstMateList contains a list of FirstMate
+type FirstMateList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []FirstMate `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&FirstMate{}, &FirstMateList{})
+}
diff --git a/testdata/project-v3-with-kustomize-v2/api/v1/firstmate_webhook.go b/testdata/project-v3-with-kustomize-v2/api/v1/firstmate_webhook.go
new file mode 100644
index 00000000000..5fa6046165d
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/api/v1/firstmate_webhook.go
@@ -0,0 +1,33 @@
+/*
+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 v1
+
+import (
+ ctrl "sigs.k8s.io/controller-runtime"
+ logf "sigs.k8s.io/controller-runtime/pkg/log"
+)
+
+// log is for logging in this package.
+var firstmatelog = logf.Log.WithName("firstmate-resource")
+
+func (r *FirstMate) SetupWebhookWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewWebhookManagedBy(mgr).
+ For(r).
+ Complete()
+}
+
+// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
diff --git a/testdata/project-v3-with-kustomize-v2/api/v1/groupversion_info.go b/testdata/project-v3-with-kustomize-v2/api/v1/groupversion_info.go
new file mode 100644
index 00000000000..33458c7506e
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/api/v1/groupversion_info.go
@@ -0,0 +1,36 @@
+/*
+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 v1 contains API Schema definitions for the crew v1 API group
+//+kubebuilder:object:generate=true
+//+groupName=crew.testproject.org
+package v1
+
+import (
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "sigs.k8s.io/controller-runtime/pkg/scheme"
+)
+
+var (
+ // GroupVersion is group version used to register these objects
+ GroupVersion = schema.GroupVersion{Group: "crew.testproject.org", Version: "v1"}
+
+ // SchemeBuilder is used to add go types to the GroupVersionKind scheme
+ SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
+
+ // AddToScheme adds the types in this group-version to the given scheme.
+ AddToScheme = SchemeBuilder.AddToScheme
+)
diff --git a/testdata/project-v3-with-kustomize-v2/api/v1/webhook_suite_test.go b/testdata/project-v3-with-kustomize-v2/api/v1/webhook_suite_test.go
new file mode 100644
index 00000000000..2795330aeb2
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/api/v1/webhook_suite_test.go
@@ -0,0 +1,139 @@
+/*
+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 v1
+
+import (
+ "context"
+ "crypto/tls"
+ "fmt"
+ "net"
+ "path/filepath"
+ "testing"
+ "time"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ admissionv1beta1 "k8s.io/api/admission/v1beta1"
+ //+kubebuilder:scaffold:imports
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/client-go/rest"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/envtest"
+ "sigs.k8s.io/controller-runtime/pkg/envtest/printer"
+ logf "sigs.k8s.io/controller-runtime/pkg/log"
+ "sigs.k8s.io/controller-runtime/pkg/log/zap"
+)
+
+// These tests use Ginkgo (BDD-style Go testing framework). Refer to
+// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
+
+var cfg *rest.Config
+var k8sClient client.Client
+var testEnv *envtest.Environment
+var ctx context.Context
+var cancel context.CancelFunc
+
+func TestAPIs(t *testing.T) {
+ RegisterFailHandler(Fail)
+
+ RunSpecsWithDefaultAndCustomReporters(t,
+ "Webhook Suite",
+ []Reporter{printer.NewlineReporter{}})
+}
+
+var _ = BeforeSuite(func() {
+ logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
+
+ ctx, cancel = context.WithCancel(context.TODO())
+
+ By("bootstrapping test environment")
+ testEnv = &envtest.Environment{
+ CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")},
+ ErrorIfCRDPathMissing: false,
+ WebhookInstallOptions: envtest.WebhookInstallOptions{
+ Paths: []string{filepath.Join("..", "..", "config", "webhook")},
+ },
+ }
+
+ cfg, err := testEnv.Start()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(cfg).NotTo(BeNil())
+
+ scheme := runtime.NewScheme()
+ err = AddToScheme(scheme)
+ Expect(err).NotTo(HaveOccurred())
+
+ err = admissionv1beta1.AddToScheme(scheme)
+ Expect(err).NotTo(HaveOccurred())
+
+ err = admissionv1beta1.AddToScheme(scheme)
+ Expect(err).NotTo(HaveOccurred())
+
+ //+kubebuilder:scaffold:scheme
+
+ k8sClient, err = client.New(cfg, client.Options{Scheme: scheme})
+ Expect(err).NotTo(HaveOccurred())
+ Expect(k8sClient).NotTo(BeNil())
+
+ // start webhook server using Manager
+ webhookInstallOptions := &testEnv.WebhookInstallOptions
+ mgr, err := ctrl.NewManager(cfg, ctrl.Options{
+ Scheme: scheme,
+ Host: webhookInstallOptions.LocalServingHost,
+ Port: webhookInstallOptions.LocalServingPort,
+ CertDir: webhookInstallOptions.LocalServingCertDir,
+ LeaderElection: false,
+ MetricsBindAddress: "0",
+ })
+ Expect(err).NotTo(HaveOccurred())
+
+ err = (&Captain{}).SetupWebhookWithManager(mgr)
+ Expect(err).NotTo(HaveOccurred())
+
+ err = (&Admiral{}).SetupWebhookWithManager(mgr)
+ Expect(err).NotTo(HaveOccurred())
+
+ //+kubebuilder:scaffold:webhook
+
+ go func() {
+ defer GinkgoRecover()
+ err = mgr.Start(ctx)
+ Expect(err).NotTo(HaveOccurred())
+ }()
+
+ // wait for the webhook server to get ready
+ dialer := &net.Dialer{Timeout: time.Second}
+ addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort)
+ Eventually(func() error {
+ conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true})
+ if err != nil {
+ return err
+ }
+ conn.Close()
+ return nil
+ }).Should(Succeed())
+
+}, 60)
+
+var _ = AfterSuite(func() {
+ cancel()
+ By("tearing down the test environment")
+ err := testEnv.Stop()
+ Expect(err).NotTo(HaveOccurred())
+})
diff --git a/testdata/project-v3-with-kustomize-v2/api/v1/zz_generated.deepcopy.go b/testdata/project-v3-with-kustomize-v2/api/v1/zz_generated.deepcopy.go
new file mode 100644
index 00000000000..eb076ea05ea
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/api/v1/zz_generated.deepcopy.go
@@ -0,0 +1,293 @@
+//go:build !ignore_autogenerated
+// +build !ignore_autogenerated
+
+/*
+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.
+*/
+
+// Code generated by controller-gen. DO NOT EDIT.
+
+package v1
+
+import (
+ "k8s.io/apimachinery/pkg/runtime"
+)
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Admiral) DeepCopyInto(out *Admiral) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ out.Spec = in.Spec
+ out.Status = in.Status
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Admiral.
+func (in *Admiral) DeepCopy() *Admiral {
+ if in == nil {
+ return nil
+ }
+ out := new(Admiral)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Admiral) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AdmiralList) DeepCopyInto(out *AdmiralList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]Admiral, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralList.
+func (in *AdmiralList) DeepCopy() *AdmiralList {
+ if in == nil {
+ return nil
+ }
+ out := new(AdmiralList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *AdmiralList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AdmiralSpec) DeepCopyInto(out *AdmiralSpec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralSpec.
+func (in *AdmiralSpec) DeepCopy() *AdmiralSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(AdmiralSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AdmiralStatus) DeepCopyInto(out *AdmiralStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralStatus.
+func (in *AdmiralStatus) DeepCopy() *AdmiralStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(AdmiralStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Captain) DeepCopyInto(out *Captain) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ out.Spec = in.Spec
+ out.Status = in.Status
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Captain.
+func (in *Captain) DeepCopy() *Captain {
+ if in == nil {
+ return nil
+ }
+ out := new(Captain)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Captain) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CaptainList) DeepCopyInto(out *CaptainList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]Captain, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CaptainList.
+func (in *CaptainList) DeepCopy() *CaptainList {
+ if in == nil {
+ return nil
+ }
+ out := new(CaptainList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *CaptainList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CaptainSpec) DeepCopyInto(out *CaptainSpec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CaptainSpec.
+func (in *CaptainSpec) DeepCopy() *CaptainSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(CaptainSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CaptainStatus) DeepCopyInto(out *CaptainStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CaptainStatus.
+func (in *CaptainStatus) DeepCopy() *CaptainStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(CaptainStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FirstMate) DeepCopyInto(out *FirstMate) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ out.Spec = in.Spec
+ out.Status = in.Status
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMate.
+func (in *FirstMate) DeepCopy() *FirstMate {
+ if in == nil {
+ return nil
+ }
+ out := new(FirstMate)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *FirstMate) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FirstMateList) DeepCopyInto(out *FirstMateList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]FirstMate, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateList.
+func (in *FirstMateList) DeepCopy() *FirstMateList {
+ if in == nil {
+ return nil
+ }
+ out := new(FirstMateList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *FirstMateList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FirstMateSpec) DeepCopyInto(out *FirstMateSpec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateSpec.
+func (in *FirstMateSpec) DeepCopy() *FirstMateSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(FirstMateSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FirstMateStatus) DeepCopyInto(out *FirstMateStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateStatus.
+func (in *FirstMateStatus) DeepCopy() *FirstMateStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(FirstMateStatus)
+ in.DeepCopyInto(out)
+ return out
+}
diff --git a/testdata/project-v3-with-kustomize-v2/config/certmanager/certificate.yaml b/testdata/project-v3-with-kustomize-v2/config/certmanager/certificate.yaml
new file mode 100644
index 00000000000..52d866183c7
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/certmanager/certificate.yaml
@@ -0,0 +1,25 @@
+# The following manifests contain a self-signed issuer CR and a certificate CR.
+# More document can be found at https://docs.cert-manager.io
+# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes.
+apiVersion: cert-manager.io/v1
+kind: Issuer
+metadata:
+ name: selfsigned-issuer
+ namespace: system
+spec:
+ selfSigned: {}
+---
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+ name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
+ namespace: system
+spec:
+ # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize
+ dnsNames:
+ - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc
+ - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local
+ issuerRef:
+ kind: Issuer
+ name: selfsigned-issuer
+ secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize
diff --git a/testdata/project-v3-with-kustomize-v2/config/certmanager/kustomization.yaml b/testdata/project-v3-with-kustomize-v2/config/certmanager/kustomization.yaml
new file mode 100644
index 00000000000..bebea5a595e
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/certmanager/kustomization.yaml
@@ -0,0 +1,5 @@
+resources:
+- certificate.yaml
+
+configurations:
+- kustomizeconfig.yaml
diff --git a/testdata/project-v3-with-kustomize-v2/config/certmanager/kustomizeconfig.yaml b/testdata/project-v3-with-kustomize-v2/config/certmanager/kustomizeconfig.yaml
new file mode 100644
index 00000000000..90d7c313ca1
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/certmanager/kustomizeconfig.yaml
@@ -0,0 +1,16 @@
+# This configuration is for teaching kustomize how to update name ref and var substitution
+nameReference:
+- kind: Issuer
+ group: cert-manager.io
+ fieldSpecs:
+ - kind: Certificate
+ group: cert-manager.io
+ path: spec/issuerRef/name
+
+varReference:
+- kind: Certificate
+ group: cert-manager.io
+ path: spec/commonName
+- kind: Certificate
+ group: cert-manager.io
+ path: spec/dnsNames
diff --git a/testdata/project-v3-with-kustomize-v2/config/crd/bases/crew.testproject.org_admirals.yaml b/testdata/project-v3-with-kustomize-v2/config/crd/bases/crew.testproject.org_admirals.yaml
new file mode 100644
index 00000000000..5b617849067
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/crd/bases/crew.testproject.org_admirals.yaml
@@ -0,0 +1,56 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.8.0
+ creationTimestamp: null
+ name: admirals.crew.testproject.org
+spec:
+ group: crew.testproject.org
+ names:
+ kind: Admiral
+ listKind: AdmiralList
+ plural: admirals
+ singular: admiral
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: Admiral is the Schema for the admirals API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: AdmiralSpec defines the desired state of Admiral
+ properties:
+ foo:
+ description: Foo is an example field of Admiral. Edit admiral_types.go
+ to remove/update
+ type: string
+ type: object
+ status:
+ description: AdmiralStatus defines the observed state of Admiral
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/testdata/project-v3-with-kustomize-v2/config/crd/bases/crew.testproject.org_captains.yaml b/testdata/project-v3-with-kustomize-v2/config/crd/bases/crew.testproject.org_captains.yaml
new file mode 100644
index 00000000000..41b080622f6
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/crd/bases/crew.testproject.org_captains.yaml
@@ -0,0 +1,56 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.8.0
+ creationTimestamp: null
+ name: captains.crew.testproject.org
+spec:
+ group: crew.testproject.org
+ names:
+ kind: Captain
+ listKind: CaptainList
+ plural: captains
+ singular: captain
+ scope: Namespaced
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: Captain is the Schema for the captains API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: CaptainSpec defines the desired state of Captain
+ properties:
+ foo:
+ description: Foo is an example field of Captain. Edit captain_types.go
+ to remove/update
+ type: string
+ type: object
+ status:
+ description: CaptainStatus defines the observed state of Captain
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/testdata/project-v3-with-kustomize-v2/config/crd/bases/crew.testproject.org_firstmates.yaml b/testdata/project-v3-with-kustomize-v2/config/crd/bases/crew.testproject.org_firstmates.yaml
new file mode 100644
index 00000000000..5ccecbc8eb8
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/crd/bases/crew.testproject.org_firstmates.yaml
@@ -0,0 +1,56 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.8.0
+ creationTimestamp: null
+ name: firstmates.crew.testproject.org
+spec:
+ group: crew.testproject.org
+ names:
+ kind: FirstMate
+ listKind: FirstMateList
+ plural: firstmates
+ singular: firstmate
+ scope: Namespaced
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: FirstMate is the Schema for the firstmates API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: FirstMateSpec defines the desired state of FirstMate
+ properties:
+ foo:
+ description: Foo is an example field of FirstMate. Edit firstmate_types.go
+ to remove/update
+ type: string
+ type: object
+ status:
+ description: FirstMateStatus defines the observed state of FirstMate
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/testdata/project-v3-with-kustomize-v2/config/crd/kustomization.yaml b/testdata/project-v3-with-kustomize-v2/config/crd/kustomization.yaml
new file mode 100644
index 00000000000..37c36ffdebd
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/crd/kustomization.yaml
@@ -0,0 +1,27 @@
+# This kustomization.yaml is not intended to be run by itself,
+# since it depends on service name and namespace that are out of this kustomize package.
+# It should be run by config/default
+resources:
+- bases/crew.testproject.org_captains.yaml
+- bases/crew.testproject.org_firstmates.yaml
+- bases/crew.testproject.org_admirals.yaml
+#+kubebuilder:scaffold:crdkustomizeresource
+
+patchesStrategicMerge:
+# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
+# patches here are for enabling the conversion webhook for each CRD
+#- patches/webhook_in_captains.yaml
+#- patches/webhook_in_firstmates.yaml
+#- patches/webhook_in_admirals.yaml
+#+kubebuilder:scaffold:crdkustomizewebhookpatch
+
+# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
+# patches here are for enabling the CA injection for each CRD
+#- patches/cainjection_in_captains.yaml
+#- patches/cainjection_in_firstmates.yaml
+#- patches/cainjection_in_admirals.yaml
+#+kubebuilder:scaffold:crdkustomizecainjectionpatch
+
+# the following config is for teaching kustomize how to do kustomization for CRDs.
+configurations:
+- kustomizeconfig.yaml
diff --git a/testdata/project-v3-with-kustomize-v2/config/crd/kustomizeconfig.yaml b/testdata/project-v3-with-kustomize-v2/config/crd/kustomizeconfig.yaml
new file mode 100644
index 00000000000..ec5c150a9df
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/crd/kustomizeconfig.yaml
@@ -0,0 +1,19 @@
+# This file is for teaching kustomize how to substitute name and namespace reference in CRD
+nameReference:
+- kind: Service
+ version: v1
+ fieldSpecs:
+ - kind: CustomResourceDefinition
+ version: v1
+ group: apiextensions.k8s.io
+ path: spec/conversion/webhook/clientConfig/service/name
+
+namespace:
+- kind: CustomResourceDefinition
+ version: v1
+ group: apiextensions.k8s.io
+ path: spec/conversion/webhook/clientConfig/service/namespace
+ create: false
+
+varReference:
+- path: metadata/annotations
diff --git a/testdata/project-v3-with-kustomize-v2/config/crd/patches/cainjection_in_admirals.yaml b/testdata/project-v3-with-kustomize-v2/config/crd/patches/cainjection_in_admirals.yaml
new file mode 100644
index 00000000000..ba7fea6e88d
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/crd/patches/cainjection_in_admirals.yaml
@@ -0,0 +1,7 @@
+# The following patch adds a directive for certmanager to inject CA into the CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+ name: admirals.crew.testproject.org
diff --git a/testdata/project-v3-with-kustomize-v2/config/crd/patches/cainjection_in_captains.yaml b/testdata/project-v3-with-kustomize-v2/config/crd/patches/cainjection_in_captains.yaml
new file mode 100644
index 00000000000..9c9d61b0c97
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/crd/patches/cainjection_in_captains.yaml
@@ -0,0 +1,7 @@
+# The following patch adds a directive for certmanager to inject CA into the CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+ name: captains.crew.testproject.org
diff --git a/testdata/project-v3-with-kustomize-v2/config/crd/patches/cainjection_in_firstmates.yaml b/testdata/project-v3-with-kustomize-v2/config/crd/patches/cainjection_in_firstmates.yaml
new file mode 100644
index 00000000000..6849f00fb85
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/crd/patches/cainjection_in_firstmates.yaml
@@ -0,0 +1,7 @@
+# The following patch adds a directive for certmanager to inject CA into the CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+ name: firstmates.crew.testproject.org
diff --git a/testdata/project-v3-with-kustomize-v2/config/crd/patches/webhook_in_admirals.yaml b/testdata/project-v3-with-kustomize-v2/config/crd/patches/webhook_in_admirals.yaml
new file mode 100644
index 00000000000..0ce2808578a
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/crd/patches/webhook_in_admirals.yaml
@@ -0,0 +1,16 @@
+# The following patch enables a conversion webhook for the CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ name: admirals.crew.testproject.org
+spec:
+ conversion:
+ strategy: Webhook
+ webhook:
+ clientConfig:
+ service:
+ namespace: system
+ name: webhook-service
+ path: /convert
+ conversionReviewVersions:
+ - v1
diff --git a/testdata/project-v3-with-kustomize-v2/config/crd/patches/webhook_in_captains.yaml b/testdata/project-v3-with-kustomize-v2/config/crd/patches/webhook_in_captains.yaml
new file mode 100644
index 00000000000..f73ae2e8abc
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/crd/patches/webhook_in_captains.yaml
@@ -0,0 +1,16 @@
+# The following patch enables a conversion webhook for the CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ name: captains.crew.testproject.org
+spec:
+ conversion:
+ strategy: Webhook
+ webhook:
+ clientConfig:
+ service:
+ namespace: system
+ name: webhook-service
+ path: /convert
+ conversionReviewVersions:
+ - v1
diff --git a/testdata/project-v3-with-kustomize-v2/config/crd/patches/webhook_in_firstmates.yaml b/testdata/project-v3-with-kustomize-v2/config/crd/patches/webhook_in_firstmates.yaml
new file mode 100644
index 00000000000..76ee5acedbd
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/crd/patches/webhook_in_firstmates.yaml
@@ -0,0 +1,16 @@
+# The following patch enables a conversion webhook for the CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ name: firstmates.crew.testproject.org
+spec:
+ conversion:
+ strategy: Webhook
+ webhook:
+ clientConfig:
+ service:
+ namespace: system
+ name: webhook-service
+ path: /convert
+ conversionReviewVersions:
+ - v1
diff --git a/testdata/project-v3-with-kustomize-v2/config/default/kustomization.yaml b/testdata/project-v3-with-kustomize-v2/config/default/kustomization.yaml
new file mode 100644
index 00000000000..4307c0f2750
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/default/kustomization.yaml
@@ -0,0 +1,136 @@
+# Adds namespace to all resources.
+namespace: project-v3-with-kustomize-v2-system
+
+# Value of this field is prepended to the
+# names of all resources, e.g. a deployment named
+# "wordpress" becomes "alices-wordpress".
+# Note that it should also match with the prefix (text before '-') of the namespace
+# field above.
+namePrefix: project-v3-with-kustomize-v2-
+
+# Labels to add to all resources and selectors.
+#commonLabels:
+# someName: someValue
+
+bases:
+- ../crd
+- ../rbac
+- ../manager
+# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
+# crd/kustomization.yaml
+#- ../webhook
+# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required.
+#- ../certmanager
+# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
+#- ../prometheus
+
+patchesStrategicMerge:
+# Protect the /metrics endpoint by putting it behind auth.
+# If you want your controller-manager to expose the /metrics
+# endpoint w/o any authn/z, please comment the following line.
+- manager_auth_proxy_patch.yaml
+
+# Mount the controller config file for loading manager configurations
+# through a ComponentConfig type
+#- manager_config_patch.yaml
+
+# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
+# crd/kustomization.yaml
+#- manager_webhook_patch.yaml
+
+# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'.
+# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks.
+# 'CERTMANAGER' needs to be enabled to use ca injection
+#- webhookcainjection_patch.yaml
+
+# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix.
+# Uncomment the following replacements to add the cert-manager CA injection annotations
+#replacements:
+# - source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# name: serving-cert # this name should match the one in certificate.yaml
+# fieldPath: .metadata.namespace # namespace of the certificate CR
+# targets:
+# - select:
+# kind: ValidatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 0
+# - select:
+# kind: MutatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 0
+# - select:
+# kind: CustomResourceDefinition
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 0
+# - source:
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# name: serving-cert # this name should match the one in certificate.yaml
+# fieldPath: .metadata.name
+# targets:
+# - select:
+# kind: ValidatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 1
+# - select:
+# kind: MutatingWebhookConfiguration
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 1
+# - select:
+# kind: CustomResourceDefinition
+# fieldPaths:
+# - .metadata.annotations.[cert-manager.io/inject-ca-from]
+# options:
+# delimiter: '/'
+# index: 1
+# - source: # Add cert-manager annotation to the webhook Service
+# kind: Service
+# version: v1
+# name: webhook-service
+# fieldPath: .metadata.name # namespace of the service
+# targets:
+# - select:
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# fieldPaths:
+# - .spec.dnsNames.0
+# - .spec.dnsNames.1
+# options:
+# delimiter: '.'
+# index: 0
+# - source:
+# kind: Service
+# version: v1
+# name: webhook-service
+# fieldPath: .metadata.namespace # namespace of the service
+# targets:
+# - select:
+# kind: Certificate
+# group: cert-manager.io
+# version: v1
+# fieldPaths:
+# - .spec.dnsNames.0
+# - .spec.dnsNames.1
+# options:
+# delimiter: '.'
+# index: 1
diff --git a/testdata/project-v3-with-kustomize-v2/config/default/manager_auth_proxy_patch.yaml b/testdata/project-v3-with-kustomize-v2/config/default/manager_auth_proxy_patch.yaml
new file mode 100644
index 00000000000..131a3142928
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/default/manager_auth_proxy_patch.yaml
@@ -0,0 +1,34 @@
+# This patch inject a sidecar container which is a HTTP proxy for the
+# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews.
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: controller-manager
+ namespace: system
+spec:
+ template:
+ spec:
+ containers:
+ - name: kube-rbac-proxy
+ image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0
+ args:
+ - "--secure-listen-address=0.0.0.0:8443"
+ - "--upstream=http://127.0.0.1:8080/"
+ - "--logtostderr=true"
+ - "--v=0"
+ ports:
+ - containerPort: 8443
+ protocol: TCP
+ name: https
+ resources:
+ limits:
+ cpu: 500m
+ memory: 128Mi
+ requests:
+ cpu: 5m
+ memory: 64Mi
+ - name: manager
+ args:
+ - "--health-probe-bind-address=:8081"
+ - "--metrics-bind-address=127.0.0.1:8080"
+ - "--leader-elect"
diff --git a/testdata/project-v3-with-kustomize-v2/config/default/manager_config_patch.yaml b/testdata/project-v3-with-kustomize-v2/config/default/manager_config_patch.yaml
new file mode 100644
index 00000000000..6c400155cfb
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/default/manager_config_patch.yaml
@@ -0,0 +1,20 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: controller-manager
+ namespace: system
+spec:
+ template:
+ spec:
+ containers:
+ - name: manager
+ args:
+ - "--config=controller_manager_config.yaml"
+ volumeMounts:
+ - name: manager-config
+ mountPath: /controller_manager_config.yaml
+ subPath: controller_manager_config.yaml
+ volumes:
+ - name: manager-config
+ configMap:
+ name: manager-config
diff --git a/testdata/project-v3-with-kustomize-v2/config/default/manager_webhook_patch.yaml b/testdata/project-v3-with-kustomize-v2/config/default/manager_webhook_patch.yaml
new file mode 100644
index 00000000000..738de350b71
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/default/manager_webhook_patch.yaml
@@ -0,0 +1,23 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: controller-manager
+ namespace: system
+spec:
+ template:
+ spec:
+ containers:
+ - name: manager
+ ports:
+ - containerPort: 9443
+ name: webhook-server
+ protocol: TCP
+ volumeMounts:
+ - mountPath: /tmp/k8s-webhook-server/serving-certs
+ name: cert
+ readOnly: true
+ volumes:
+ - name: cert
+ secret:
+ defaultMode: 420
+ secretName: webhook-server-cert
diff --git a/testdata/project-v3-with-kustomize-v2/config/default/webhookcainjection_patch.yaml b/testdata/project-v3-with-kustomize-v2/config/default/webhookcainjection_patch.yaml
new file mode 100644
index 00000000000..02ab515d428
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/default/webhookcainjection_patch.yaml
@@ -0,0 +1,15 @@
+# This patch add annotation to admission webhook config and
+# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize.
+apiVersion: admissionregistration.k8s.io/v1
+kind: MutatingWebhookConfiguration
+metadata:
+ name: mutating-webhook-configuration
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+---
+apiVersion: admissionregistration.k8s.io/v1
+kind: ValidatingWebhookConfiguration
+metadata:
+ name: validating-webhook-configuration
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
diff --git a/testdata/project-v3-with-kustomize-v2/config/manager/controller_manager_config.yaml b/testdata/project-v3-with-kustomize-v2/config/manager/controller_manager_config.yaml
new file mode 100644
index 00000000000..cd1b16d8c5e
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/manager/controller_manager_config.yaml
@@ -0,0 +1,11 @@
+apiVersion: controller-runtime.sigs.k8s.io/v1alpha1
+kind: ControllerManagerConfig
+health:
+ healthProbeBindAddress: :8081
+metrics:
+ bindAddress: 127.0.0.1:8080
+webhook:
+ port: 9443
+leaderElection:
+ leaderElect: true
+ resourceName: f4c39f8b.testproject.org
diff --git a/testdata/project-v3-with-kustomize-v2/config/manager/kustomization.yaml b/testdata/project-v3-with-kustomize-v2/config/manager/kustomization.yaml
new file mode 100644
index 00000000000..2bcd3eeaa94
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/manager/kustomization.yaml
@@ -0,0 +1,10 @@
+resources:
+- manager.yaml
+
+generatorOptions:
+ disableNameSuffixHash: true
+
+configMapGenerator:
+- name: manager-config
+ files:
+ - controller_manager_config.yaml
diff --git a/testdata/project-v3-with-kustomize-v2/config/manager/manager.yaml b/testdata/project-v3-with-kustomize-v2/config/manager/manager.yaml
new file mode 100644
index 00000000000..cf11cecc26a
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/manager/manager.yaml
@@ -0,0 +1,60 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ labels:
+ control-plane: controller-manager
+ name: system
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: controller-manager
+ namespace: system
+ labels:
+ control-plane: controller-manager
+spec:
+ selector:
+ matchLabels:
+ control-plane: controller-manager
+ replicas: 1
+ template:
+ metadata:
+ annotations:
+ kubectl.kubernetes.io/default-container: manager
+ labels:
+ control-plane: controller-manager
+ spec:
+ securityContext:
+ runAsNonRoot: true
+ containers:
+ - command:
+ - /manager
+ args:
+ - --leader-elect
+ image: controller:latest
+ name: manager
+ securityContext:
+ allowPrivilegeEscalation: false
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: 8081
+ initialDelaySeconds: 15
+ periodSeconds: 20
+ readinessProbe:
+ httpGet:
+ path: /readyz
+ port: 8081
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ # TODO(user): Configure the resources accordingly based on the project requirements.
+ # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+ resources:
+ limits:
+ cpu: 500m
+ memory: 128Mi
+ requests:
+ cpu: 10m
+ memory: 64Mi
+ serviceAccountName: controller-manager
+ terminationGracePeriodSeconds: 10
diff --git a/testdata/project-v3-with-kustomize-v2/config/prometheus/kustomization.yaml b/testdata/project-v3-with-kustomize-v2/config/prometheus/kustomization.yaml
new file mode 100644
index 00000000000..ed137168a1d
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/prometheus/kustomization.yaml
@@ -0,0 +1,2 @@
+resources:
+- monitor.yaml
diff --git a/testdata/project-v3-with-kustomize-v2/config/prometheus/monitor.yaml b/testdata/project-v3-with-kustomize-v2/config/prometheus/monitor.yaml
new file mode 100644
index 00000000000..d19136ae710
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/prometheus/monitor.yaml
@@ -0,0 +1,20 @@
+
+# Prometheus Monitor Service (Metrics)
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ labels:
+ control-plane: controller-manager
+ name: controller-manager-metrics-monitor
+ namespace: system
+spec:
+ endpoints:
+ - path: /metrics
+ port: https
+ scheme: https
+ bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
+ tlsConfig:
+ insecureSkipVerify: true
+ selector:
+ matchLabels:
+ control-plane: controller-manager
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/admiral_editor_role.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/admiral_editor_role.yaml
new file mode 100644
index 00000000000..7f2cc5cd99f
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/admiral_editor_role.yaml
@@ -0,0 +1,24 @@
+# permissions for end users to edit admirals.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: admiral-editor-role
+rules:
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - admirals
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - admirals/status
+ verbs:
+ - get
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/admiral_viewer_role.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/admiral_viewer_role.yaml
new file mode 100644
index 00000000000..ddbb0c2a85b
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/admiral_viewer_role.yaml
@@ -0,0 +1,20 @@
+# permissions for end users to view admirals.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: admiral-viewer-role
+rules:
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - admirals
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - admirals/status
+ verbs:
+ - get
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_client_clusterrole.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_client_clusterrole.yaml
new file mode 100644
index 00000000000..51a75db47a5
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_client_clusterrole.yaml
@@ -0,0 +1,9 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: metrics-reader
+rules:
+- nonResourceURLs:
+ - "/metrics"
+ verbs:
+ - get
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_role.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_role.yaml
new file mode 100644
index 00000000000..80e1857c594
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_role.yaml
@@ -0,0 +1,17 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: proxy-role
+rules:
+- apiGroups:
+ - authentication.k8s.io
+ resources:
+ - tokenreviews
+ verbs:
+ - create
+- apiGroups:
+ - authorization.k8s.io
+ resources:
+ - subjectaccessreviews
+ verbs:
+ - create
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_role_binding.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_role_binding.yaml
new file mode 100644
index 00000000000..ec7acc0a1b7
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_role_binding.yaml
@@ -0,0 +1,12 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: proxy-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: proxy-role
+subjects:
+- kind: ServiceAccount
+ name: controller-manager
+ namespace: system
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_service.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_service.yaml
new file mode 100644
index 00000000000..71f1797279e
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/auth_proxy_service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ control-plane: controller-manager
+ name: controller-manager-metrics-service
+ namespace: system
+spec:
+ ports:
+ - name: https
+ port: 8443
+ protocol: TCP
+ targetPort: https
+ selector:
+ control-plane: controller-manager
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/captain_editor_role.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/captain_editor_role.yaml
new file mode 100644
index 00000000000..4b53ae38ffa
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/captain_editor_role.yaml
@@ -0,0 +1,24 @@
+# permissions for end users to edit captains.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: captain-editor-role
+rules:
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - captains
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - captains/status
+ verbs:
+ - get
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/captain_viewer_role.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/captain_viewer_role.yaml
new file mode 100644
index 00000000000..f19e10439d2
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/captain_viewer_role.yaml
@@ -0,0 +1,20 @@
+# permissions for end users to view captains.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: captain-viewer-role
+rules:
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - captains
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - captains/status
+ verbs:
+ - get
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/firstmate_editor_role.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/firstmate_editor_role.yaml
new file mode 100644
index 00000000000..22a08be29dd
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/firstmate_editor_role.yaml
@@ -0,0 +1,24 @@
+# permissions for end users to edit firstmates.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: firstmate-editor-role
+rules:
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - firstmates
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - firstmates/status
+ verbs:
+ - get
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/firstmate_viewer_role.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/firstmate_viewer_role.yaml
new file mode 100644
index 00000000000..9fd6ba933c7
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/firstmate_viewer_role.yaml
@@ -0,0 +1,20 @@
+# permissions for end users to view firstmates.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: firstmate-viewer-role
+rules:
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - firstmates
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - firstmates/status
+ verbs:
+ - get
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/kustomization.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/kustomization.yaml
new file mode 100644
index 00000000000..731832a6ac3
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/kustomization.yaml
@@ -0,0 +1,18 @@
+resources:
+# All RBAC will be applied under this service account in
+# the deployment namespace. You may comment out this resource
+# if your manager will use a service account that exists at
+# runtime. Be sure to update RoleBinding and ClusterRoleBinding
+# subjects if changing service account names.
+- service_account.yaml
+- role.yaml
+- role_binding.yaml
+- leader_election_role.yaml
+- leader_election_role_binding.yaml
+# Comment the following 4 lines if you want to disable
+# the auth proxy (https://github.com/brancz/kube-rbac-proxy)
+# which protects your /metrics endpoint.
+- auth_proxy_service.yaml
+- auth_proxy_role.yaml
+- auth_proxy_role_binding.yaml
+- auth_proxy_client_clusterrole.yaml
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/leader_election_role.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/leader_election_role.yaml
new file mode 100644
index 00000000000..4190ec8059e
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/leader_election_role.yaml
@@ -0,0 +1,37 @@
+# permissions to do leader election.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: leader-election-role
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - configmaps
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - coordination.k8s.io
+ resources:
+ - leases
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - patch
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/leader_election_role_binding.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/leader_election_role_binding.yaml
new file mode 100644
index 00000000000..1d1321ed4f0
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/leader_election_role_binding.yaml
@@ -0,0 +1,12 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: leader-election-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: leader-election-role
+subjects:
+- kind: ServiceAccount
+ name: controller-manager
+ namespace: system
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/role.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/role.yaml
new file mode 100644
index 00000000000..ef9a7a2e8ed
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/role.yaml
@@ -0,0 +1,111 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ creationTimestamp: null
+ name: manager-role
+rules:
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - admirals
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - admirals/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - admirals/status
+ verbs:
+ - get
+ - patch
+ - update
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - captains
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - captains/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - captains/status
+ verbs:
+ - get
+ - patch
+ - update
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - firstmates
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - firstmates/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - firstmates/status
+ verbs:
+ - get
+ - patch
+ - update
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - lakers
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - lakers/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - crew.testproject.org
+ resources:
+ - lakers/status
+ verbs:
+ - get
+ - patch
+ - update
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/role_binding.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/role_binding.yaml
new file mode 100644
index 00000000000..2070ede4462
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/role_binding.yaml
@@ -0,0 +1,12 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: manager-rolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: manager-role
+subjects:
+- kind: ServiceAccount
+ name: controller-manager
+ namespace: system
diff --git a/testdata/project-v3-with-kustomize-v2/config/rbac/service_account.yaml b/testdata/project-v3-with-kustomize-v2/config/rbac/service_account.yaml
new file mode 100644
index 00000000000..7cd6025bfc4
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/rbac/service_account.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: controller-manager
+ namespace: system
diff --git a/testdata/project-v3-with-kustomize-v2/config/samples/crew_v1_admiral.yaml b/testdata/project-v3-with-kustomize-v2/config/samples/crew_v1_admiral.yaml
new file mode 100644
index 00000000000..588448f7801
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/samples/crew_v1_admiral.yaml
@@ -0,0 +1,6 @@
+apiVersion: crew.testproject.org/v1
+kind: Admiral
+metadata:
+ name: admiral-sample
+spec:
+ # TODO(user): Add fields here
diff --git a/testdata/project-v3-with-kustomize-v2/config/samples/crew_v1_captain.yaml b/testdata/project-v3-with-kustomize-v2/config/samples/crew_v1_captain.yaml
new file mode 100644
index 00000000000..d0dcfc6cb4d
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/samples/crew_v1_captain.yaml
@@ -0,0 +1,6 @@
+apiVersion: crew.testproject.org/v1
+kind: Captain
+metadata:
+ name: captain-sample
+spec:
+ # TODO(user): Add fields here
diff --git a/testdata/project-v3-with-kustomize-v2/config/samples/crew_v1_firstmate.yaml b/testdata/project-v3-with-kustomize-v2/config/samples/crew_v1_firstmate.yaml
new file mode 100644
index 00000000000..61749572695
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/samples/crew_v1_firstmate.yaml
@@ -0,0 +1,6 @@
+apiVersion: crew.testproject.org/v1
+kind: FirstMate
+metadata:
+ name: firstmate-sample
+spec:
+ # TODO(user): Add fields here
diff --git a/testdata/project-v3-with-kustomize-v2/config/webhook/kustomization.yaml b/testdata/project-v3-with-kustomize-v2/config/webhook/kustomization.yaml
new file mode 100644
index 00000000000..9cf26134e4d
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/webhook/kustomization.yaml
@@ -0,0 +1,6 @@
+resources:
+- manifests.yaml
+- service.yaml
+
+configurations:
+- kustomizeconfig.yaml
diff --git a/testdata/project-v3-with-kustomize-v2/config/webhook/kustomizeconfig.yaml b/testdata/project-v3-with-kustomize-v2/config/webhook/kustomizeconfig.yaml
new file mode 100644
index 00000000000..25e21e3c963
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/webhook/kustomizeconfig.yaml
@@ -0,0 +1,25 @@
+# the following config is for teaching kustomize where to look at when substituting vars.
+# It requires kustomize v2.1.0 or newer to work properly.
+nameReference:
+- kind: Service
+ version: v1
+ fieldSpecs:
+ - kind: MutatingWebhookConfiguration
+ group: admissionregistration.k8s.io
+ path: webhooks/clientConfig/service/name
+ - kind: ValidatingWebhookConfiguration
+ group: admissionregistration.k8s.io
+ path: webhooks/clientConfig/service/name
+
+namespace:
+- kind: MutatingWebhookConfiguration
+ group: admissionregistration.k8s.io
+ path: webhooks/clientConfig/service/namespace
+ create: true
+- kind: ValidatingWebhookConfiguration
+ group: admissionregistration.k8s.io
+ path: webhooks/clientConfig/service/namespace
+ create: true
+
+varReference:
+- path: metadata/annotations
diff --git a/testdata/project-v3-with-kustomize-v2/config/webhook/manifests.yaml b/testdata/project-v3-with-kustomize-v2/config/webhook/manifests.yaml
new file mode 100644
index 00000000000..80eb36fdc3f
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/webhook/manifests.yaml
@@ -0,0 +1,74 @@
+---
+apiVersion: admissionregistration.k8s.io/v1
+kind: MutatingWebhookConfiguration
+metadata:
+ creationTimestamp: null
+ name: mutating-webhook-configuration
+webhooks:
+- admissionReviewVersions:
+ - v1
+ clientConfig:
+ service:
+ name: webhook-service
+ namespace: system
+ path: /mutate-crew-testproject-org-v1-admiral
+ failurePolicy: Fail
+ name: madmiral.kb.io
+ rules:
+ - apiGroups:
+ - crew.testproject.org
+ apiVersions:
+ - v1
+ operations:
+ - CREATE
+ - UPDATE
+ resources:
+ - admirals
+ sideEffects: None
+- admissionReviewVersions:
+ - v1
+ clientConfig:
+ service:
+ name: webhook-service
+ namespace: system
+ path: /mutate-crew-testproject-org-v1-captain
+ failurePolicy: Fail
+ name: mcaptain.kb.io
+ rules:
+ - apiGroups:
+ - crew.testproject.org
+ apiVersions:
+ - v1
+ operations:
+ - CREATE
+ - UPDATE
+ resources:
+ - captains
+ sideEffects: None
+---
+apiVersion: admissionregistration.k8s.io/v1
+kind: ValidatingWebhookConfiguration
+metadata:
+ creationTimestamp: null
+ name: validating-webhook-configuration
+webhooks:
+- admissionReviewVersions:
+ - v1
+ clientConfig:
+ service:
+ name: webhook-service
+ namespace: system
+ path: /validate-crew-testproject-org-v1-captain
+ failurePolicy: Fail
+ name: vcaptain.kb.io
+ rules:
+ - apiGroups:
+ - crew.testproject.org
+ apiVersions:
+ - v1
+ operations:
+ - CREATE
+ - UPDATE
+ resources:
+ - captains
+ sideEffects: None
diff --git a/testdata/project-v3-with-kustomize-v2/config/webhook/service.yaml b/testdata/project-v3-with-kustomize-v2/config/webhook/service.yaml
new file mode 100644
index 00000000000..3f638bd9c68
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/config/webhook/service.yaml
@@ -0,0 +1,13 @@
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: webhook-service
+ namespace: system
+spec:
+ ports:
+ - port: 443
+ protocol: TCP
+ targetPort: 9443
+ selector:
+ control-plane: controller-manager
diff --git a/testdata/project-v3-with-kustomize-v2/controllers/admiral_controller.go b/testdata/project-v3-with-kustomize-v2/controllers/admiral_controller.go
new file mode 100644
index 00000000000..c6edc2243ef
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/controllers/admiral_controller.go
@@ -0,0 +1,62 @@
+/*
+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 controllers
+
+import (
+ "context"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+
+ crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v3-with-kustomize-v2/api/v1"
+)
+
+// AdmiralReconciler reconciles a Admiral object
+type AdmiralReconciler struct {
+ client.Client
+ Scheme *runtime.Scheme
+}
+
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=admirals,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=admirals/status,verbs=get;update;patch
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=admirals/finalizers,verbs=update
+
+// Reconcile is part of the main kubernetes reconciliation loop which aims to
+// move the current state of the cluster closer to the desired state.
+// TODO(user): Modify the Reconcile function to compare the state specified by
+// the Admiral object against the actual cluster state, and then
+// perform operations to make the cluster state reflect the state specified by
+// the user.
+//
+// For more details, check Reconcile and its Result here:
+// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.11.0/pkg/reconcile
+func (r *AdmiralReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
+ _ = log.FromContext(ctx)
+
+ // TODO(user): your logic here
+
+ return ctrl.Result{}, nil
+}
+
+// SetupWithManager sets up the controller with the Manager.
+func (r *AdmiralReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewControllerManagedBy(mgr).
+ For(&crewv1.Admiral{}).
+ Complete(r)
+}
diff --git a/testdata/project-v3-with-kustomize-v2/controllers/captain_controller.go b/testdata/project-v3-with-kustomize-v2/controllers/captain_controller.go
new file mode 100644
index 00000000000..25eb332522a
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/controllers/captain_controller.go
@@ -0,0 +1,62 @@
+/*
+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 controllers
+
+import (
+ "context"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+
+ crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v3-with-kustomize-v2/api/v1"
+)
+
+// CaptainReconciler reconciles a Captain object
+type CaptainReconciler struct {
+ client.Client
+ Scheme *runtime.Scheme
+}
+
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=captains,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=captains/status,verbs=get;update;patch
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=captains/finalizers,verbs=update
+
+// Reconcile is part of the main kubernetes reconciliation loop which aims to
+// move the current state of the cluster closer to the desired state.
+// TODO(user): Modify the Reconcile function to compare the state specified by
+// the Captain object against the actual cluster state, and then
+// perform operations to make the cluster state reflect the state specified by
+// the user.
+//
+// For more details, check Reconcile and its Result here:
+// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.11.0/pkg/reconcile
+func (r *CaptainReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
+ _ = log.FromContext(ctx)
+
+ // TODO(user): your logic here
+
+ return ctrl.Result{}, nil
+}
+
+// SetupWithManager sets up the controller with the Manager.
+func (r *CaptainReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewControllerManagedBy(mgr).
+ For(&crewv1.Captain{}).
+ Complete(r)
+}
diff --git a/testdata/project-v3-with-kustomize-v2/controllers/firstmate_controller.go b/testdata/project-v3-with-kustomize-v2/controllers/firstmate_controller.go
new file mode 100644
index 00000000000..e8a9bba6386
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/controllers/firstmate_controller.go
@@ -0,0 +1,62 @@
+/*
+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 controllers
+
+import (
+ "context"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+
+ crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v3-with-kustomize-v2/api/v1"
+)
+
+// FirstMateReconciler reconciles a FirstMate object
+type FirstMateReconciler struct {
+ client.Client
+ Scheme *runtime.Scheme
+}
+
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates/status,verbs=get;update;patch
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates/finalizers,verbs=update
+
+// Reconcile is part of the main kubernetes reconciliation loop which aims to
+// move the current state of the cluster closer to the desired state.
+// TODO(user): Modify the Reconcile function to compare the state specified by
+// the FirstMate object against the actual cluster state, and then
+// perform operations to make the cluster state reflect the state specified by
+// the user.
+//
+// For more details, check Reconcile and its Result here:
+// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.11.0/pkg/reconcile
+func (r *FirstMateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
+ _ = log.FromContext(ctx)
+
+ // TODO(user): your logic here
+
+ return ctrl.Result{}, nil
+}
+
+// SetupWithManager sets up the controller with the Manager.
+func (r *FirstMateReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewControllerManagedBy(mgr).
+ For(&crewv1.FirstMate{}).
+ Complete(r)
+}
diff --git a/testdata/project-v3-with-kustomize-v2/controllers/laker_controller.go b/testdata/project-v3-with-kustomize-v2/controllers/laker_controller.go
new file mode 100644
index 00000000000..b4b109f501e
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/controllers/laker_controller.go
@@ -0,0 +1,61 @@
+/*
+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 controllers
+
+import (
+ "context"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+)
+
+// LakerReconciler reconciles a Laker object
+type LakerReconciler struct {
+ client.Client
+ Scheme *runtime.Scheme
+}
+
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=lakers,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=lakers/status,verbs=get;update;patch
+//+kubebuilder:rbac:groups=crew.testproject.org,resources=lakers/finalizers,verbs=update
+
+// Reconcile is part of the main kubernetes reconciliation loop which aims to
+// move the current state of the cluster closer to the desired state.
+// TODO(user): Modify the Reconcile function to compare the state specified by
+// the Laker object against the actual cluster state, and then
+// perform operations to make the cluster state reflect the state specified by
+// the user.
+//
+// For more details, check Reconcile and its Result here:
+// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.11.0/pkg/reconcile
+func (r *LakerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
+ _ = log.FromContext(ctx)
+
+ // TODO(user): your logic here
+
+ return ctrl.Result{}, nil
+}
+
+// SetupWithManager sets up the controller with the Manager.
+func (r *LakerReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewControllerManagedBy(mgr).
+ // Uncomment the following line adding a pointer to an instance of the controlled resource as an argument
+ // For().
+ Complete(r)
+}
diff --git a/testdata/project-v3-with-kustomize-v2/controllers/suite_test.go b/testdata/project-v3-with-kustomize-v2/controllers/suite_test.go
new file mode 100644
index 00000000000..77e8315e783
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/controllers/suite_test.go
@@ -0,0 +1,80 @@
+/*
+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 controllers
+
+import (
+ "path/filepath"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "k8s.io/client-go/kubernetes/scheme"
+ "k8s.io/client-go/rest"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/envtest"
+ "sigs.k8s.io/controller-runtime/pkg/envtest/printer"
+ logf "sigs.k8s.io/controller-runtime/pkg/log"
+ "sigs.k8s.io/controller-runtime/pkg/log/zap"
+
+ crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v3-with-kustomize-v2/api/v1"
+ //+kubebuilder:scaffold:imports
+)
+
+// These tests use Ginkgo (BDD-style Go testing framework). Refer to
+// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
+
+var cfg *rest.Config
+var k8sClient client.Client
+var testEnv *envtest.Environment
+
+func TestAPIs(t *testing.T) {
+ RegisterFailHandler(Fail)
+
+ RunSpecsWithDefaultAndCustomReporters(t,
+ "Controller Suite",
+ []Reporter{printer.NewlineReporter{}})
+}
+
+var _ = BeforeSuite(func() {
+ logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
+
+ By("bootstrapping test environment")
+ testEnv = &envtest.Environment{
+ CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
+ ErrorIfCRDPathMissing: true,
+ }
+
+ cfg, err := testEnv.Start()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(cfg).NotTo(BeNil())
+
+ err = crewv1.AddToScheme(scheme.Scheme)
+ Expect(err).NotTo(HaveOccurred())
+
+ //+kubebuilder:scaffold:scheme
+
+ k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
+ Expect(err).NotTo(HaveOccurred())
+ Expect(k8sClient).NotTo(BeNil())
+
+}, 60)
+
+var _ = AfterSuite(func() {
+ By("tearing down the test environment")
+ err := testEnv.Stop()
+ Expect(err).NotTo(HaveOccurred())
+})
diff --git a/testdata/project-v3-with-kustomize-v2/go.mod b/testdata/project-v3-with-kustomize-v2/go.mod
new file mode 100644
index 00000000000..37b7065cd55
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/go.mod
@@ -0,0 +1,74 @@
+module sigs.k8s.io/kubebuilder/testdata/project-v3-with-kustomize-v2
+
+go 1.17
+
+require (
+ github.com/onsi/ginkgo v1.16.5
+ github.com/onsi/gomega v1.17.0
+ k8s.io/api v0.23.0
+ k8s.io/apimachinery v0.23.0
+ k8s.io/client-go v0.23.0
+ sigs.k8s.io/controller-runtime v0.11.0
+)
+
+require (
+ cloud.google.com/go v0.81.0 // indirect
+ github.com/Azure/go-autorest v14.2.0+incompatible // indirect
+ github.com/Azure/go-autorest/autorest v0.11.18 // indirect
+ github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect
+ github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
+ github.com/Azure/go-autorest/logger v0.2.1 // indirect
+ github.com/Azure/go-autorest/tracing v0.6.0 // indirect
+ github.com/beorn7/perks v1.0.1 // indirect
+ github.com/cespare/xxhash/v2 v2.1.1 // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/evanphx/json-patch v4.12.0+incompatible // indirect
+ github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
+ github.com/fsnotify/fsnotify v1.5.1 // indirect
+ github.com/go-logr/logr v1.2.0 // indirect
+ github.com/go-logr/zapr v1.2.0 // indirect
+ github.com/gogo/protobuf v1.3.2 // indirect
+ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+ github.com/golang/protobuf v1.5.2 // indirect
+ github.com/google/go-cmp v0.5.5 // indirect
+ github.com/google/gofuzz v1.1.0 // indirect
+ github.com/google/uuid v1.1.2 // indirect
+ github.com/googleapis/gnostic v0.5.5 // indirect
+ github.com/imdario/mergo v0.3.12 // indirect
+ github.com/json-iterator/go v1.1.12 // indirect
+ github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+ github.com/modern-go/reflect2 v1.0.2 // indirect
+ github.com/nxadm/tail v1.4.8 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/prometheus/client_golang v1.11.0 // indirect
+ github.com/prometheus/client_model v0.2.0 // indirect
+ github.com/prometheus/common v0.28.0 // indirect
+ github.com/prometheus/procfs v0.6.0 // indirect
+ github.com/spf13/pflag v1.0.5 // indirect
+ go.uber.org/atomic v1.7.0 // indirect
+ go.uber.org/multierr v1.6.0 // indirect
+ go.uber.org/zap v1.19.1 // indirect
+ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
+ golang.org/x/net v0.0.0-20210825183410-e898025ed96a // indirect
+ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
+ golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect
+ golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
+ golang.org/x/text v0.3.7 // indirect
+ golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
+ gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
+ google.golang.org/appengine v1.6.7 // indirect
+ google.golang.org/protobuf v1.27.1 // indirect
+ gopkg.in/inf.v0 v0.9.1 // indirect
+ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
+ gopkg.in/yaml.v2 v2.4.0 // indirect
+ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+ k8s.io/apiextensions-apiserver v0.23.0 // indirect
+ k8s.io/component-base v0.23.0 // indirect
+ k8s.io/klog/v2 v2.30.0 // indirect
+ k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
+ k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b // indirect
+ sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
+ sigs.k8s.io/structured-merge-diff/v4 v4.2.0 // indirect
+ sigs.k8s.io/yaml v1.3.0 // indirect
+)
diff --git a/testdata/project-v3-with-kustomize-v2/hack/boilerplate.go.txt b/testdata/project-v3-with-kustomize-v2/hack/boilerplate.go.txt
new file mode 100644
index 00000000000..b54e305f300
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/hack/boilerplate.go.txt
@@ -0,0 +1,15 @@
+/*
+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.
+*/
\ No newline at end of file
diff --git a/testdata/project-v3-with-kustomize-v2/main.go b/testdata/project-v3-with-kustomize-v2/main.go
new file mode 100644
index 00000000000..3c540a0d10d
--- /dev/null
+++ b/testdata/project-v3-with-kustomize-v2/main.go
@@ -0,0 +1,137 @@
+/*
+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 main
+
+import (
+ "flag"
+ "os"
+
+ // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
+ // to ensure that exec-entrypoint and run can make use of them.
+ _ "k8s.io/client-go/plugin/pkg/client/auth"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+ clientgoscheme "k8s.io/client-go/kubernetes/scheme"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/healthz"
+ "sigs.k8s.io/controller-runtime/pkg/log/zap"
+
+ crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v3-with-kustomize-v2/api/v1"
+ "sigs.k8s.io/kubebuilder/testdata/project-v3-with-kustomize-v2/controllers"
+ //+kubebuilder:scaffold:imports
+)
+
+var (
+ scheme = runtime.NewScheme()
+ setupLog = ctrl.Log.WithName("setup")
+)
+
+func init() {
+ utilruntime.Must(clientgoscheme.AddToScheme(scheme))
+
+ utilruntime.Must(crewv1.AddToScheme(scheme))
+ //+kubebuilder:scaffold:scheme
+}
+
+func main() {
+ var metricsAddr string
+ var enableLeaderElection bool
+ var probeAddr string
+ flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
+ flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
+ flag.BoolVar(&enableLeaderElection, "leader-elect", false,
+ "Enable leader election for controller manager. "+
+ "Enabling this will ensure there is only one active controller manager.")
+ opts := zap.Options{
+ Development: true,
+ }
+ opts.BindFlags(flag.CommandLine)
+ flag.Parse()
+
+ ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
+
+ mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
+ Scheme: scheme,
+ MetricsBindAddress: metricsAddr,
+ Port: 9443,
+ HealthProbeBindAddress: probeAddr,
+ LeaderElection: enableLeaderElection,
+ LeaderElectionID: "f4c39f8b.testproject.org",
+ })
+ if err != nil {
+ setupLog.Error(err, "unable to start manager")
+ os.Exit(1)
+ }
+
+ if err = (&controllers.CaptainReconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "Captain")
+ os.Exit(1)
+ }
+ if err = (&crewv1.Captain{}).SetupWebhookWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create webhook", "webhook", "Captain")
+ os.Exit(1)
+ }
+ if err = (&controllers.FirstMateReconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "FirstMate")
+ os.Exit(1)
+ }
+ if err = (&crewv1.FirstMate{}).SetupWebhookWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create webhook", "webhook", "FirstMate")
+ os.Exit(1)
+ }
+ if err = (&controllers.AdmiralReconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "Admiral")
+ os.Exit(1)
+ }
+ if err = (&crewv1.Admiral{}).SetupWebhookWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create webhook", "webhook", "Admiral")
+ os.Exit(1)
+ }
+ if err = (&controllers.LakerReconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "Laker")
+ os.Exit(1)
+ }
+ //+kubebuilder:scaffold:builder
+
+ if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
+ setupLog.Error(err, "unable to set up health check")
+ os.Exit(1)
+ }
+ if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
+ setupLog.Error(err, "unable to set up ready check")
+ os.Exit(1)
+ }
+
+ setupLog.Info("starting manager")
+ if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
+ setupLog.Error(err, "problem running manager")
+ os.Exit(1)
+ }
+}