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) + } +}