From a33c027b7e2dc204204c7451acf6298cfe1465aa Mon Sep 17 00:00:00 2001 From: Chris Hein Date: Wed, 4 Nov 2020 21:01:32 -0800 Subject: [PATCH 1/2] adding support for scaffolding componentconfig type Signed-off-by: Chris Hein --- generate_testdata.sh | 1 + pkg/model/config/config.go | 4 ++ pkg/model/file/interfaces.go | 6 ++ pkg/model/file/mixins.go | 11 ++++ pkg/model/universe.go | 3 + pkg/plugins/golang/v3/init.go | 2 + pkg/plugins/golang/v3/scaffolds/init.go | 2 + .../config/kdefault/kustomization.go | 11 +++- .../kdefault/manager_auth_proxy_patch.go | 5 +- .../config/kdefault/manager_config_patch.go | 63 +++++++++++++++++++ .../templates/config/manager/config.go | 3 + .../manager/controller_manager_config.go | 56 +++++++++++++++++ .../templates/config/manager/kustomization.go | 8 +++ .../v3/scaffolds/internal/templates/main.go | 24 ++++++- .../scaffolds/internal/templates/makefile.go | 1 + 15 files changed, 195 insertions(+), 5 deletions(-) create mode 100644 pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_config_patch.go create mode 100644 pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/controller_manager_config.go diff --git a/generate_testdata.sh b/generate_testdata.sh index f1329a2b677..2b59a78dd57 100755 --- a/generate_testdata.sh +++ b/generate_testdata.sh @@ -112,3 +112,4 @@ scaffold_test_project project-v2-addon --project-version=2 scaffold_test_project project-v3 --project-version=3-alpha --plugins=go/v3-alpha scaffold_test_project project-v3-multigroup --project-version=3-alpha --plugins=go/v3-alpha scaffold_test_project project-v3-addon --project-version=3-alpha --plugins=go/v3-alpha +scaffold_test_project project-v3-config --project-version=3-alpha --plugins=go/v3-alpha --component-config diff --git a/pkg/model/config/config.go b/pkg/model/config/config.go index 1a3ec594866..61940266420 100644 --- a/pkg/model/config/config.go +++ b/pkg/model/config/config.go @@ -50,6 +50,10 @@ type Config struct { // Multigroup tracks if the project has more than one group MultiGroup bool `json:"multigroup,omitempty"` + // ComponentConfig tracks if the project uses a config file for configuring + // the ctrl.Manager + ComponentConfig bool `json:"componentConfig,omitempty"` + // Layout contains a key specifying which plugin created a project. Layout string `json:"layout,omitempty"` diff --git a/pkg/model/file/interfaces.go b/pkg/model/file/interfaces.go index 7354a1ec12d..2469d6f3524 100644 --- a/pkg/model/file/interfaces.go +++ b/pkg/model/file/interfaces.go @@ -73,6 +73,12 @@ type HasMultiGroup interface { InjectMultiGroup(bool) } +// HasComponentConfig allows the component-config flag to be used on a template +type HasComponentConfig interface { + // InjectComponentConfig sets the template component-config flag + InjectComponentConfig(bool) +} + // HasBoilerplate allows a boilerplate to be used on a template type HasBoilerplate interface { // InjectBoilerplate sets the template boilerplate diff --git a/pkg/model/file/mixins.go b/pkg/model/file/mixins.go index 6125c0ca449..eee4dd7083c 100644 --- a/pkg/model/file/mixins.go +++ b/pkg/model/file/mixins.go @@ -104,6 +104,17 @@ func (m *MultiGroupMixin) InjectMultiGroup(flag bool) { m.MultiGroup = flag } +// ComponentConfigMixin provides templates with a injectable component-config flag field +type ComponentConfigMixin struct { + // ComponentConfig is the component-config flag + ComponentConfig bool +} + +// InjectComponentConfig implements HasComponentConfig +func (m *ComponentConfigMixin) InjectComponentConfig(flag bool) { + m.ComponentConfig = flag +} + // BoilerplateMixin provides templates with a injectable boilerplate field type BoilerplateMixin struct { // Boilerplate is the contents of a Boilerplate go header file diff --git a/pkg/model/universe.go b/pkg/model/universe.go index edda46fd77b..b00b6769585 100644 --- a/pkg/model/universe.go +++ b/pkg/model/universe.go @@ -91,6 +91,9 @@ func (u Universe) InjectInto(builder file.Builder) { if builderWithMultiGroup, hasMultiGroup := builder.(file.HasMultiGroup); hasMultiGroup { builderWithMultiGroup.InjectMultiGroup(u.Config.MultiGroup) } + if builderWithComponentConfig, hasComponentConfig := builder.(file.HasComponentConfig); hasComponentConfig { + builderWithComponentConfig.InjectComponentConfig(u.Config.ComponentConfig) + } if builderWithProjectName, hasProjectName := builder.(file.HasProjectName); hasProjectName { builderWithProjectName.InjectProjectName(u.Config.ProjectName) } diff --git a/pkg/plugins/golang/v3/init.go b/pkg/plugins/golang/v3/init.go index 9ebed6e498e..b3308e0ba32 100644 --- a/pkg/plugins/golang/v3/init.go +++ b/pkg/plugins/golang/v3/init.go @@ -86,6 +86,8 @@ func (p *initSubcommand) BindFlags(fs *pflag.FlagSet) { fs.StringVar(&p.license, "license", "apache2", "license to use to boilerplate, may be one of 'apache2', 'none'") fs.StringVar(&p.owner, "owner", "", "owner to add to the copyright") + fs.BoolVar(&p.config.ComponentConfig, "component-config", false, + "create a versioned ComponentConfig file, may be 'true' or 'false'") // project args fs.StringVar(&p.config.Repo, "repo", "", "name to use for go module (e.g., github.com/user/repo), "+ diff --git a/pkg/plugins/golang/v3/scaffolds/init.go b/pkg/plugins/golang/v3/scaffolds/init.go index 929552ff720..0e059df39c9 100644 --- a/pkg/plugins/golang/v3/scaffolds/init.go +++ b/pkg/plugins/golang/v3/scaffolds/init.go @@ -107,6 +107,7 @@ func (s *initScaffolder) scaffold() error { &rbac.LeaderElectionRoleBinding{}, &manager.Kustomization{}, &manager.Config{Image: imageName}, + &manager.ControllerManagerConfig{}, &templates.Main{}, &templates.GoMod{ControllerRuntimeVersion: ControllerRuntimeVersion}, &templates.GitIgnore{}, @@ -121,6 +122,7 @@ func (s *initScaffolder) scaffold() error { &templates.DockerIgnore{}, &kdefault.Kustomization{}, &kdefault.ManagerAuthProxyPatch{}, + &kdefault.ManagerConfigPatch{}, &prometheus.Kustomization{}, &prometheus.Monitor{}, &certmanager.Certificate{}, diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/kustomization.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/kustomization.go index 4dccd70cd0d..f56e6eed87e 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/kustomization.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/kustomization.go @@ -28,6 +28,7 @@ var _ file.Template = &Kustomization{} type Kustomization struct { file.TemplateMixin file.ProjectNameMixin + file.ComponentConfigMixin } // SetTemplateDefaults implements file.Template @@ -70,11 +71,15 @@ bases: #- ../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. +# 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 diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go index 585b31c1bb8..4b64700b08c 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go @@ -27,6 +27,7 @@ var _ file.Template = &ManagerAuthProxyPatch{} // ManagerAuthProxyPatch scaffolds a file that defines the patch that enables prometheus metrics for the manager type ManagerAuthProxyPatch struct { file.TemplateMixin + file.ComponentConfigMixin } // SetTemplateDefaults implements file.Template @@ -42,7 +43,7 @@ func (f *ManagerAuthProxyPatch) SetTemplateDefaults() error { return nil } -const kustomizeAuthProxyPatchTemplate = `# This patch inject a sidecar container which is a HTTP proxy for the +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 @@ -63,8 +64,10 @@ spec: ports: - containerPort: 8443 name: https +{{- if not .ComponentConfig }} - name: manager args: - "--metrics-addr=127.0.0.1:8080" - "--enable-leader-election" +{{- end }} ` diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_config_patch.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_config_patch.go new file mode 100644 index 00000000000..dbdb274c381 --- /dev/null +++ b/pkg/plugins/golang/v3/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/v2/pkg/model/file" +) + +var _ file.Template = &ManagerConfigPatch{} + +// ManagerConfigPatch scaffolds a ManagerConfigPatch for a Resource +type ManagerConfigPatch struct { + file.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/golang/v3/scaffolds/internal/templates/config/manager/config.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/config.go index 8d2fcdb99ab..fad74a0d855 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/config.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/config.go @@ -27,6 +27,7 @@ var _ file.Template = &Config{} // Config scaffolds a file that defines the namespace and the manager deployment type Config struct { file.TemplateMixin + file.ComponentConfigMixin // Image is controller manager image name Image string @@ -72,8 +73,10 @@ spec: containers: - command: - /manager +{{- if not .ComponentConfig }} args: - --enable-leader-election +{{- end }} image: {{ .Image }} name: manager securityContext: diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/controller_manager_config.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/controller_manager_config.go new file mode 100644 index 00000000000..cb7ea1d9171 --- /dev/null +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/controller_manager_config.go @@ -0,0 +1,56 @@ +/* +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/v2/pkg/model/file" +) + +var _ file.Template = &ControllerManagerConfig{} + +// ControllerManagerConfig scaffolds the config file in config/manager folder. +type ControllerManagerConfig struct { + file.TemplateMixin + file.DomainMixin + file.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 = file.Error + + return nil +} + +const controllerManagerConfigTemplate = `apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: {{ hashFNV .Repo }}.{{ .Domain }} +` diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/kustomization.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/kustomization.go index 0b0901f51ab..07d43a4dcdf 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/kustomization.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/kustomization.go @@ -44,4 +44,12 @@ func (f *Kustomization) SetTemplateDefaults() error { const kustomizeManagerTemplate = `resources: - manager.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: +- name: manager-config + files: + - controller_manager_config.yaml ` diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/main.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/main.go index 70e92540b94..d6f5b0f149a 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/main.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/main.go @@ -33,6 +33,7 @@ type Main struct { file.BoilerplateMixin file.DomainMixin file.RepositoryMixin + file.ComponentConfigMixin } // SetTemplateDefaults implements file.Template @@ -213,13 +214,20 @@ func init() { } func main() { +{{- if not .ComponentConfig }} var metricsAddr string var enableLeaderElection bool flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, "Enable leader election for controller manager. " + "Enabling this will ensure there is only one active controller manager.") - +{{- else }} + var configFile string + flag.StringVar(&configFile, "config", "", + "The controller will load its initial configuration from this file. " + + "Omit this flag to use the default configuration values. " + + "Command-line flags override configuration from this file.") +{{- end }} opts := zap.Options{ Development: true, } @@ -228,6 +236,7 @@ func main() { ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) +{{ if not .ComponentConfig }} mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, MetricsBindAddress: metricsAddr, @@ -235,6 +244,19 @@ func main() { LeaderElection: enableLeaderElection, LeaderElectionID: "{{ hashFNV .Repo }}.{{ .Domain }}", }) +{{- else }} + var err error + options := ctrl.Options{Scheme: scheme} + if configFile != "" { + options, err = options.AndFrom(ctrl.ConfigFile().AtPath(configFile)) + if err != nil { + setupLog.Error(err, "unable to load the config file") + os.Exit(1) + } + } + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options) +{{- end }} if err != nil { setupLog.Error(err, "unable to start manager") os.Exit(1) diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/makefile.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/makefile.go index 0b678ba35b1..6c31eae568a 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/makefile.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/makefile.go @@ -25,6 +25,7 @@ var _ file.Template = &Makefile{} // Makefile scaffolds a file that defines project management CLI commands type Makefile struct { file.TemplateMixin + file.ComponentConfigMixin // Image is controller manager image name Image string From 55b8fd7a6ab7004796b0cb8fc7e0c31333ad8bf2 Mon Sep 17 00:00:00 2001 From: Chris Hein Date: Wed, 18 Nov 2020 13:22:06 -0800 Subject: [PATCH 2/2] regenerating the testdata Signed-off-by: Chris Hein --- .../config/default/kustomization.yaml | 10 +- .../default/manager_auth_proxy_patch.yaml | 2 +- .../config/default/manager_config_patch.yaml | 20 ++ .../manager/controller_manager_config.yaml | 9 + .../config/manager/kustomization.yaml | 8 + testdata/project-v3-addon/main.go | 1 - testdata/project-v3-config/.dockerignore | 5 + testdata/project-v3-config/.gitignore | 25 ++ testdata/project-v3-config/Dockerfile | 27 ++ testdata/project-v3-config/Makefile | 94 ++++++ testdata/project-v3-config/PROJECT | 22 ++ .../project-v3-config/api/v1/admiral_types.go | 65 ++++ .../api/v1/admiral_webhook.go | 45 +++ .../project-v3-config/api/v1/captain_types.go | 64 ++++ .../api/v1/captain_webhook.go | 75 +++++ .../api/v1/firstmate_types.go | 64 ++++ .../api/v1/firstmate_webhook.go | 33 ++ .../api/v1/groupversion_info.go | 36 +++ .../api/v1/webhook_suite_test.go | 139 +++++++++ .../api/v1/zz_generated.deepcopy.go | 292 ++++++++++++++++++ .../config/certmanager/certificate.yaml | 25 ++ .../config/certmanager/kustomization.yaml | 5 + .../config/certmanager/kustomizeconfig.yaml | 16 + .../bases/crew.testproject.org_admirals.yaml | 57 ++++ .../bases/crew.testproject.org_captains.yaml | 57 ++++ .../crew.testproject.org_firstmates.yaml | 57 ++++ .../config/crd/kustomization.yaml | 27 ++ .../config/crd/kustomizeconfig.yaml | 19 ++ .../crd/patches/cainjection_in_admirals.yaml | 7 + .../crd/patches/cainjection_in_captains.yaml | 7 + .../patches/cainjection_in_firstmates.yaml | 7 + .../crd/patches/webhook_in_admirals.yaml | 14 + .../crd/patches/webhook_in_captains.yaml | 14 + .../crd/patches/webhook_in_firstmates.yaml | 14 + .../config/default/kustomization.yaml | 74 +++++ .../default/manager_auth_proxy_patch.yaml | 21 ++ .../config/default/manager_config_patch.yaml | 20 ++ .../config/default/manager_webhook_patch.yaml | 23 ++ .../default/webhookcainjection_patch.yaml | 15 + .../manager/controller_manager_config.yaml | 9 + .../config/manager/kustomization.yaml | 10 + .../config/manager/manager.yaml | 41 +++ .../config/prometheus/kustomization.yaml | 2 + .../config/prometheus/monitor.yaml | 16 + .../config/rbac/admiral_editor_role.yaml | 24 ++ .../config/rbac/admiral_viewer_role.yaml | 20 ++ .../rbac/auth_proxy_client_clusterrole.yaml | 7 + .../config/rbac/auth_proxy_role.yaml | 13 + .../config/rbac/auth_proxy_role_binding.yaml | 12 + .../config/rbac/auth_proxy_service.yaml | 14 + .../config/rbac/captain_editor_role.yaml | 24 ++ .../config/rbac/captain_viewer_role.yaml | 20 ++ .../config/rbac/firstmate_editor_role.yaml | 24 ++ .../config/rbac/firstmate_viewer_role.yaml | 20 ++ .../config/rbac/kustomization.yaml | 12 + .../config/rbac/leader_election_role.yaml | 27 ++ .../rbac/leader_election_role_binding.yaml | 12 + .../project-v3-config/config/rbac/role.yaml | 112 +++++++ .../config/rbac/role_binding.yaml | 12 + .../config/samples/crew_v1_admiral.yaml | 7 + .../config/samples/crew_v1_captain.yaml | 7 + .../config/samples/crew_v1_firstmate.yaml | 7 + .../config/webhook/kustomization.yaml | 6 + .../config/webhook/kustomizeconfig.yaml | 25 ++ .../config/webhook/manifests.yaml | 76 +++++ .../config/webhook/service.yaml | 12 + .../controllers/admiral_controller.go | 63 ++++ .../controllers/captain_controller.go | 63 ++++ .../controllers/firstmate_controller.go | 63 ++++ .../controllers/laker_controller.go | 62 ++++ .../controllers/suite_test.go | 85 +++++ testdata/project-v3-config/go.mod | 13 + .../project-v3-config/hack/boilerplate.go.txt | 15 + testdata/project-v3-config/main.go | 131 ++++++++ .../config/default/kustomization.yaml | 10 +- .../default/manager_auth_proxy_patch.yaml | 2 +- .../config/default/manager_config_patch.yaml | 20 ++ .../manager/controller_manager_config.yaml | 9 + .../config/manager/kustomization.yaml | 8 + testdata/project-v3-multigroup/main.go | 1 - .../config/default/kustomization.yaml | 10 +- .../default/manager_auth_proxy_patch.yaml | 2 +- .../config/default/manager_config_patch.yaml | 20 ++ .../manager/controller_manager_config.yaml | 9 + .../config/manager/kustomization.yaml | 8 + testdata/project-v3/main.go | 1 - 86 files changed, 2666 insertions(+), 15 deletions(-) create mode 100644 testdata/project-v3-addon/config/default/manager_config_patch.yaml create mode 100644 testdata/project-v3-addon/config/manager/controller_manager_config.yaml create mode 100644 testdata/project-v3-config/.dockerignore create mode 100644 testdata/project-v3-config/.gitignore create mode 100644 testdata/project-v3-config/Dockerfile create mode 100644 testdata/project-v3-config/Makefile create mode 100644 testdata/project-v3-config/PROJECT create mode 100644 testdata/project-v3-config/api/v1/admiral_types.go create mode 100644 testdata/project-v3-config/api/v1/admiral_webhook.go create mode 100644 testdata/project-v3-config/api/v1/captain_types.go create mode 100644 testdata/project-v3-config/api/v1/captain_webhook.go create mode 100644 testdata/project-v3-config/api/v1/firstmate_types.go create mode 100644 testdata/project-v3-config/api/v1/firstmate_webhook.go create mode 100644 testdata/project-v3-config/api/v1/groupversion_info.go create mode 100644 testdata/project-v3-config/api/v1/webhook_suite_test.go create mode 100644 testdata/project-v3-config/api/v1/zz_generated.deepcopy.go create mode 100644 testdata/project-v3-config/config/certmanager/certificate.yaml create mode 100644 testdata/project-v3-config/config/certmanager/kustomization.yaml create mode 100644 testdata/project-v3-config/config/certmanager/kustomizeconfig.yaml create mode 100644 testdata/project-v3-config/config/crd/bases/crew.testproject.org_admirals.yaml create mode 100644 testdata/project-v3-config/config/crd/bases/crew.testproject.org_captains.yaml create mode 100644 testdata/project-v3-config/config/crd/bases/crew.testproject.org_firstmates.yaml create mode 100644 testdata/project-v3-config/config/crd/kustomization.yaml create mode 100644 testdata/project-v3-config/config/crd/kustomizeconfig.yaml create mode 100644 testdata/project-v3-config/config/crd/patches/cainjection_in_admirals.yaml create mode 100644 testdata/project-v3-config/config/crd/patches/cainjection_in_captains.yaml create mode 100644 testdata/project-v3-config/config/crd/patches/cainjection_in_firstmates.yaml create mode 100644 testdata/project-v3-config/config/crd/patches/webhook_in_admirals.yaml create mode 100644 testdata/project-v3-config/config/crd/patches/webhook_in_captains.yaml create mode 100644 testdata/project-v3-config/config/crd/patches/webhook_in_firstmates.yaml create mode 100644 testdata/project-v3-config/config/default/kustomization.yaml create mode 100644 testdata/project-v3-config/config/default/manager_auth_proxy_patch.yaml create mode 100644 testdata/project-v3-config/config/default/manager_config_patch.yaml create mode 100644 testdata/project-v3-config/config/default/manager_webhook_patch.yaml create mode 100644 testdata/project-v3-config/config/default/webhookcainjection_patch.yaml create mode 100644 testdata/project-v3-config/config/manager/controller_manager_config.yaml create mode 100644 testdata/project-v3-config/config/manager/kustomization.yaml create mode 100644 testdata/project-v3-config/config/manager/manager.yaml create mode 100644 testdata/project-v3-config/config/prometheus/kustomization.yaml create mode 100644 testdata/project-v3-config/config/prometheus/monitor.yaml create mode 100644 testdata/project-v3-config/config/rbac/admiral_editor_role.yaml create mode 100644 testdata/project-v3-config/config/rbac/admiral_viewer_role.yaml create mode 100644 testdata/project-v3-config/config/rbac/auth_proxy_client_clusterrole.yaml create mode 100644 testdata/project-v3-config/config/rbac/auth_proxy_role.yaml create mode 100644 testdata/project-v3-config/config/rbac/auth_proxy_role_binding.yaml create mode 100644 testdata/project-v3-config/config/rbac/auth_proxy_service.yaml create mode 100644 testdata/project-v3-config/config/rbac/captain_editor_role.yaml create mode 100644 testdata/project-v3-config/config/rbac/captain_viewer_role.yaml create mode 100644 testdata/project-v3-config/config/rbac/firstmate_editor_role.yaml create mode 100644 testdata/project-v3-config/config/rbac/firstmate_viewer_role.yaml create mode 100644 testdata/project-v3-config/config/rbac/kustomization.yaml create mode 100644 testdata/project-v3-config/config/rbac/leader_election_role.yaml create mode 100644 testdata/project-v3-config/config/rbac/leader_election_role_binding.yaml create mode 100644 testdata/project-v3-config/config/rbac/role.yaml create mode 100644 testdata/project-v3-config/config/rbac/role_binding.yaml create mode 100644 testdata/project-v3-config/config/samples/crew_v1_admiral.yaml create mode 100644 testdata/project-v3-config/config/samples/crew_v1_captain.yaml create mode 100644 testdata/project-v3-config/config/samples/crew_v1_firstmate.yaml create mode 100644 testdata/project-v3-config/config/webhook/kustomization.yaml create mode 100644 testdata/project-v3-config/config/webhook/kustomizeconfig.yaml create mode 100644 testdata/project-v3-config/config/webhook/manifests.yaml create mode 100644 testdata/project-v3-config/config/webhook/service.yaml create mode 100644 testdata/project-v3-config/controllers/admiral_controller.go create mode 100644 testdata/project-v3-config/controllers/captain_controller.go create mode 100644 testdata/project-v3-config/controllers/firstmate_controller.go create mode 100644 testdata/project-v3-config/controllers/laker_controller.go create mode 100644 testdata/project-v3-config/controllers/suite_test.go create mode 100644 testdata/project-v3-config/go.mod create mode 100644 testdata/project-v3-config/hack/boilerplate.go.txt create mode 100644 testdata/project-v3-config/main.go create mode 100644 testdata/project-v3-multigroup/config/default/manager_config_patch.yaml create mode 100644 testdata/project-v3-multigroup/config/manager/controller_manager_config.yaml create mode 100644 testdata/project-v3/config/default/manager_config_patch.yaml create mode 100644 testdata/project-v3/config/manager/controller_manager_config.yaml diff --git a/testdata/project-v3-addon/config/default/kustomization.yaml b/testdata/project-v3-addon/config/default/kustomization.yaml index 98d3b4c1de1..8daaca8569b 100644 --- a/testdata/project-v3-addon/config/default/kustomization.yaml +++ b/testdata/project-v3-addon/config/default/kustomization.yaml @@ -25,11 +25,15 @@ bases: #- ../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. +# 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 diff --git a/testdata/project-v3-addon/config/default/manager_auth_proxy_patch.yaml b/testdata/project-v3-addon/config/default/manager_auth_proxy_patch.yaml index 77e743d1c1c..a945ed173a7 100644 --- a/testdata/project-v3-addon/config/default/manager_auth_proxy_patch.yaml +++ b/testdata/project-v3-addon/config/default/manager_auth_proxy_patch.yaml @@ -1,4 +1,4 @@ -# This patch inject a sidecar container which is a HTTP proxy for the +# 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 diff --git a/testdata/project-v3-addon/config/default/manager_config_patch.yaml b/testdata/project-v3-addon/config/default/manager_config_patch.yaml new file mode 100644 index 00000000000..6c400155cfb --- /dev/null +++ b/testdata/project-v3-addon/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-addon/config/manager/controller_manager_config.yaml b/testdata/project-v3-addon/config/manager/controller_manager_config.yaml new file mode 100644 index 00000000000..aa704ed90da --- /dev/null +++ b/testdata/project-v3-addon/config/manager/controller_manager_config.yaml @@ -0,0 +1,9 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: 52ea9610.testproject.org diff --git a/testdata/project-v3-addon/config/manager/kustomization.yaml b/testdata/project-v3-addon/config/manager/kustomization.yaml index 5c5f0b84cba..2bcd3eeaa94 100644 --- a/testdata/project-v3-addon/config/manager/kustomization.yaml +++ b/testdata/project-v3-addon/config/manager/kustomization.yaml @@ -1,2 +1,10 @@ resources: - manager.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: +- name: manager-config + files: + - controller_manager_config.yaml diff --git a/testdata/project-v3-addon/main.go b/testdata/project-v3-addon/main.go index b5f0dac2750..b612502c67c 100644 --- a/testdata/project-v3-addon/main.go +++ b/testdata/project-v3-addon/main.go @@ -54,7 +54,6 @@ func main() { flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") - opts := zap.Options{ Development: true, } diff --git a/testdata/project-v3-config/.dockerignore b/testdata/project-v3-config/.dockerignore new file mode 100644 index 00000000000..243f81a5080 --- /dev/null +++ b/testdata/project-v3-config/.dockerignore @@ -0,0 +1,5 @@ +# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Ignore all files which are not go type +!**/*.go +!**/*.mod +!**/*.sum diff --git a/testdata/project-v3-config/.gitignore b/testdata/project-v3-config/.gitignore new file mode 100644 index 00000000000..c0a7a54cac5 --- /dev/null +++ b/testdata/project-v3-config/.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-config/Dockerfile b/testdata/project-v3-config/Dockerfile new file mode 100644 index 00000000000..ce816f3b0e7 --- /dev/null +++ b/testdata/project-v3-config/Dockerfile @@ -0,0 +1,27 @@ +# Build the manager binary +FROM golang:1.15 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 GO111MODULE=on 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-config/Makefile b/testdata/project-v3-config/Makefile new file mode 100644 index 00000000000..ca60fbd4890 --- /dev/null +++ b/testdata/project-v3-config/Makefile @@ -0,0 +1,94 @@ + +# Image URL to use all building/pushing image targets +IMG ?= controller:latest +# Produce CRDs that work back to Kubernetes 1.11 (no version conversion) +CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false" + +# 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 + +all: manager + +# Run tests +ENVTEST_ASSETS_DIR=$(shell pwd)/testbin +test: generate fmt vet manifests + mkdir -p ${ENVTEST_ASSETS_DIR} + test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.7.0-alpha.6/hack/setup-envtest.sh + source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -coverprofile cover.out + +# Build manager binary +manager: generate fmt vet + go build -o bin/manager main.go + +# Run against the configured Kubernetes cluster in ~/.kube/config +run: generate fmt vet manifests + go run ./main.go + +# Install CRDs into a cluster +install: manifests kustomize + $(KUSTOMIZE) build config/crd | kubectl apply -f - + +# Uninstall CRDs from a cluster +uninstall: manifests kustomize + $(KUSTOMIZE) build config/crd | kubectl delete -f - + +# Deploy controller in the configured Kubernetes cluster in ~/.kube/config +deploy: manifests kustomize + cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} + $(KUSTOMIZE) build config/default | kubectl apply -f - + +# UnDeploy controller from the configured Kubernetes cluster in ~/.kube/config +undeploy: + $(KUSTOMIZE) build config/default | kubectl delete -f - + +# Generate manifests e.g. CRD, RBAC etc. +manifests: controller-gen + $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases + +# Run go fmt against code +fmt: + go fmt ./... + +# Run go vet against code +vet: + go vet ./... + +# Generate code +generate: controller-gen + $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." + +# Build the docker image +docker-build: test + docker build -t ${IMG} . + +# Push the docker image +docker-push: + docker push ${IMG} + +# Download controller-gen locally if necessary +CONTROLLER_GEN = $(shell pwd)/bin/controller-gen +controller-gen: + $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.1) + +# Download kustomize locally if necessary +KUSTOMIZE = $(shell pwd)/bin/kustomize +kustomize: + $(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v3@v3.8.7) + +# go-get-tool will 'go get' any package $2 and install it to $1. +PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) +define go-get-tool +@[ -f $(1) ] || { \ +set -e ;\ +TMP_DIR=$$(mktemp -d) ;\ +cd $$TMP_DIR ;\ +go mod init tmp ;\ +echo "Downloading $(2)" ;\ +GOBIN=$(PROJECT_DIR)/bin go get $(2) ;\ +rm -rf $$TMP_DIR ;\ +} +endef diff --git a/testdata/project-v3-config/PROJECT b/testdata/project-v3-config/PROJECT new file mode 100644 index 00000000000..5e22d5af4b1 --- /dev/null +++ b/testdata/project-v3-config/PROJECT @@ -0,0 +1,22 @@ +componentConfig: true +domain: testproject.org +layout: go.kubebuilder.io/v3-alpha +projectName: project-v3-config +repo: sigs.k8s.io/kubebuilder/testdata/project-v3-config +resources: +- crdVersion: v1 + group: crew + kind: Captain + version: v1 + webhookVersion: v1 +- crdVersion: v1 + group: crew + kind: FirstMate + version: v1 + webhookVersion: v1 +- crdVersion: v1 + group: crew + kind: Admiral + version: v1 + webhookVersion: v1 +version: 3-alpha diff --git a/testdata/project-v3-config/api/v1/admiral_types.go b/testdata/project-v3-config/api/v1/admiral_types.go new file mode 100644 index 00000000000..ab0e80fc432 --- /dev/null +++ b/testdata/project-v3-config/api/v1/admiral_types.go @@ -0,0 +1,65 @@ +/* +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 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-config/api/v1/admiral_webhook.go b/testdata/project-v3-config/api/v1/admiral_webhook.go new file mode 100644 index 00000000000..cb2f2c70bdb --- /dev/null +++ b/testdata/project-v3-config/api/v1/admiral_webhook.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 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() +} + +// 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={v1beta1} + +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-config/api/v1/captain_types.go b/testdata/project-v3-config/api/v1/captain_types.go new file mode 100644 index 00000000000..e2c00209e5d --- /dev/null +++ b/testdata/project-v3-config/api/v1/captain_types.go @@ -0,0 +1,64 @@ +/* +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 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-config/api/v1/captain_webhook.go b/testdata/project-v3-config/api/v1/captain_webhook.go new file mode 100644 index 00000000000..1c6b4211fb6 --- /dev/null +++ b/testdata/project-v3-config/api/v1/captain_webhook.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 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() +} + +// 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={v1beta1} + +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={v1beta1} + +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-config/api/v1/firstmate_types.go b/testdata/project-v3-config/api/v1/firstmate_types.go new file mode 100644 index 00000000000..b3509c629dc --- /dev/null +++ b/testdata/project-v3-config/api/v1/firstmate_types.go @@ -0,0 +1,64 @@ +/* +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 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-config/api/v1/firstmate_webhook.go b/testdata/project-v3-config/api/v1/firstmate_webhook.go new file mode 100644 index 00000000000..703a865c107 --- /dev/null +++ b/testdata/project-v3-config/api/v1/firstmate_webhook.go @@ -0,0 +1,33 @@ +/* +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 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() +} + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! diff --git a/testdata/project-v3-config/api/v1/groupversion_info.go b/testdata/project-v3-config/api/v1/groupversion_info.go new file mode 100644 index 00000000000..16821d46605 --- /dev/null +++ b/testdata/project-v3-config/api/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +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 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-config/api/v1/webhook_suite_test.go b/testdata/project-v3-config/api/v1/webhook_suite_test.go new file mode 100644 index 00000000000..541e7682ea0 --- /dev/null +++ b/testdata/project-v3-config/api/v1/webhook_suite_test.go @@ -0,0 +1,139 @@ +/* +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 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")}, + 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() { + err = mgr.Start(ctx) + if err != nil { + 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-config/api/v1/zz_generated.deepcopy.go b/testdata/project-v3-config/api/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..7015b52ea8e --- /dev/null +++ b/testdata/project-v3-config/api/v1/zz_generated.deepcopy.go @@ -0,0 +1,292 @@ +// +build !ignore_autogenerated + +/* +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. +*/ + +// 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-config/config/certmanager/certificate.yaml b/testdata/project-v3-config/config/certmanager/certificate.yaml new file mode 100644 index 00000000000..52d866183c7 --- /dev/null +++ b/testdata/project-v3-config/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-config/config/certmanager/kustomization.yaml b/testdata/project-v3-config/config/certmanager/kustomization.yaml new file mode 100644 index 00000000000..bebea5a595e --- /dev/null +++ b/testdata/project-v3-config/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- certificate.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/testdata/project-v3-config/config/certmanager/kustomizeconfig.yaml b/testdata/project-v3-config/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 00000000000..90d7c313ca1 --- /dev/null +++ b/testdata/project-v3-config/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-config/config/crd/bases/crew.testproject.org_admirals.yaml b/testdata/project-v3-config/config/crd/bases/crew.testproject.org_admirals.yaml new file mode 100644 index 00000000000..4611bd1e654 --- /dev/null +++ b/testdata/project-v3-config/config/crd/bases/crew.testproject.org_admirals.yaml @@ -0,0 +1,57 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + 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-config/config/crd/bases/crew.testproject.org_captains.yaml b/testdata/project-v3-config/config/crd/bases/crew.testproject.org_captains.yaml new file mode 100644 index 00000000000..012b4d166d8 --- /dev/null +++ b/testdata/project-v3-config/config/crd/bases/crew.testproject.org_captains.yaml @@ -0,0 +1,57 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + 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-config/config/crd/bases/crew.testproject.org_firstmates.yaml b/testdata/project-v3-config/config/crd/bases/crew.testproject.org_firstmates.yaml new file mode 100644 index 00000000000..40161cbd203 --- /dev/null +++ b/testdata/project-v3-config/config/crd/bases/crew.testproject.org_firstmates.yaml @@ -0,0 +1,57 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + 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-config/config/crd/kustomization.yaml b/testdata/project-v3-config/config/crd/kustomization.yaml new file mode 100644 index 00000000000..df6972356cf --- /dev/null +++ b/testdata/project-v3-config/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 webhook, 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-config/config/crd/kustomizeconfig.yaml b/testdata/project-v3-config/config/crd/kustomizeconfig.yaml new file mode 100644 index 00000000000..ec5c150a9df --- /dev/null +++ b/testdata/project-v3-config/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-config/config/crd/patches/cainjection_in_admirals.yaml b/testdata/project-v3-config/config/crd/patches/cainjection_in_admirals.yaml new file mode 100644 index 00000000000..ba7fea6e88d --- /dev/null +++ b/testdata/project-v3-config/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-config/config/crd/patches/cainjection_in_captains.yaml b/testdata/project-v3-config/config/crd/patches/cainjection_in_captains.yaml new file mode 100644 index 00000000000..9c9d61b0c97 --- /dev/null +++ b/testdata/project-v3-config/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-config/config/crd/patches/cainjection_in_firstmates.yaml b/testdata/project-v3-config/config/crd/patches/cainjection_in_firstmates.yaml new file mode 100644 index 00000000000..6849f00fb85 --- /dev/null +++ b/testdata/project-v3-config/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-config/config/crd/patches/webhook_in_admirals.yaml b/testdata/project-v3-config/config/crd/patches/webhook_in_admirals.yaml new file mode 100644 index 00000000000..e7cef4898e3 --- /dev/null +++ b/testdata/project-v3-config/config/crd/patches/webhook_in_admirals.yaml @@ -0,0 +1,14 @@ +# 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 diff --git a/testdata/project-v3-config/config/crd/patches/webhook_in_captains.yaml b/testdata/project-v3-config/config/crd/patches/webhook_in_captains.yaml new file mode 100644 index 00000000000..39ef2528c5a --- /dev/null +++ b/testdata/project-v3-config/config/crd/patches/webhook_in_captains.yaml @@ -0,0 +1,14 @@ +# 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 diff --git a/testdata/project-v3-config/config/crd/patches/webhook_in_firstmates.yaml b/testdata/project-v3-config/config/crd/patches/webhook_in_firstmates.yaml new file mode 100644 index 00000000000..a644d053242 --- /dev/null +++ b/testdata/project-v3-config/config/crd/patches/webhook_in_firstmates.yaml @@ -0,0 +1,14 @@ +# 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 diff --git a/testdata/project-v3-config/config/default/kustomization.yaml b/testdata/project-v3-config/config/default/kustomization.yaml new file mode 100644 index 00000000000..53d22a3b176 --- /dev/null +++ b/testdata/project-v3-config/config/default/kustomization.yaml @@ -0,0 +1,74 @@ +# Adds namespace to all resources. +namespace: project-v3-config-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-config- + +# 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 + +# the following config is for teaching kustomize how to do var substitution +vars: +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +# fieldref: +# fieldpath: metadata.namespace +#- name: CERTIFICATE_NAME +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +#- name: SERVICE_NAMESPACE # namespace of the service +# objref: +# kind: Service +# version: v1 +# name: webhook-service +# fieldref: +# fieldpath: metadata.namespace +#- name: SERVICE_NAME +# objref: +# kind: Service +# version: v1 +# name: webhook-service diff --git a/testdata/project-v3-config/config/default/manager_auth_proxy_patch.yaml b/testdata/project-v3-config/config/default/manager_auth_proxy_patch.yaml new file mode 100644 index 00000000000..37c578ab7ae --- /dev/null +++ b/testdata/project-v3-config/config/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,21 @@ +# 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.5.0 + args: + - "--secure-listen-address=0.0.0.0:8443" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=10" + ports: + - containerPort: 8443 + name: https diff --git a/testdata/project-v3-config/config/default/manager_config_patch.yaml b/testdata/project-v3-config/config/default/manager_config_patch.yaml new file mode 100644 index 00000000000..6c400155cfb --- /dev/null +++ b/testdata/project-v3-config/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-config/config/default/manager_webhook_patch.yaml b/testdata/project-v3-config/config/default/manager_webhook_patch.yaml new file mode 100644 index 00000000000..738de350b71 --- /dev/null +++ b/testdata/project-v3-config/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-config/config/default/webhookcainjection_patch.yaml b/testdata/project-v3-config/config/default/webhookcainjection_patch.yaml new file mode 100644 index 00000000000..02ab515d428 --- /dev/null +++ b/testdata/project-v3-config/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-config/config/manager/controller_manager_config.yaml b/testdata/project-v3-config/config/manager/controller_manager_config.yaml new file mode 100644 index 00000000000..a184ebe4998 --- /dev/null +++ b/testdata/project-v3-config/config/manager/controller_manager_config.yaml @@ -0,0 +1,9 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: 6858fb70.testproject.org diff --git a/testdata/project-v3-config/config/manager/kustomization.yaml b/testdata/project-v3-config/config/manager/kustomization.yaml new file mode 100644 index 00000000000..2bcd3eeaa94 --- /dev/null +++ b/testdata/project-v3-config/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-config/config/manager/manager.yaml b/testdata/project-v3-config/config/manager/manager.yaml new file mode 100644 index 00000000000..9f691b3f55b --- /dev/null +++ b/testdata/project-v3-config/config/manager/manager.yaml @@ -0,0 +1,41 @@ +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: + labels: + control-plane: controller-manager + spec: + securityContext: + runAsUser: 65532 + containers: + - command: + - /manager + image: controller:latest + name: manager + securityContext: + allowPrivilegeEscalation: false + resources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi + terminationGracePeriodSeconds: 10 diff --git a/testdata/project-v3-config/config/prometheus/kustomization.yaml b/testdata/project-v3-config/config/prometheus/kustomization.yaml new file mode 100644 index 00000000000..ed137168a1d --- /dev/null +++ b/testdata/project-v3-config/config/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/testdata/project-v3-config/config/prometheus/monitor.yaml b/testdata/project-v3-config/config/prometheus/monitor.yaml new file mode 100644 index 00000000000..9b8047b760f --- /dev/null +++ b/testdata/project-v3-config/config/prometheus/monitor.yaml @@ -0,0 +1,16 @@ + +# 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 + selector: + matchLabels: + control-plane: controller-manager diff --git a/testdata/project-v3-config/config/rbac/admiral_editor_role.yaml b/testdata/project-v3-config/config/rbac/admiral_editor_role.yaml new file mode 100644 index 00000000000..7f2cc5cd99f --- /dev/null +++ b/testdata/project-v3-config/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-config/config/rbac/admiral_viewer_role.yaml b/testdata/project-v3-config/config/rbac/admiral_viewer_role.yaml new file mode 100644 index 00000000000..ddbb0c2a85b --- /dev/null +++ b/testdata/project-v3-config/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-config/config/rbac/auth_proxy_client_clusterrole.yaml b/testdata/project-v3-config/config/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 00000000000..bd4af137a9f --- /dev/null +++ b/testdata/project-v3-config/config/rbac/auth_proxy_client_clusterrole.yaml @@ -0,0 +1,7 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: ["/metrics"] + verbs: ["get"] diff --git a/testdata/project-v3-config/config/rbac/auth_proxy_role.yaml b/testdata/project-v3-config/config/rbac/auth_proxy_role.yaml new file mode 100644 index 00000000000..618f5e4177c --- /dev/null +++ b/testdata/project-v3-config/config/rbac/auth_proxy_role.yaml @@ -0,0 +1,13 @@ +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-config/config/rbac/auth_proxy_role_binding.yaml b/testdata/project-v3-config/config/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 00000000000..48ed1e4b85c --- /dev/null +++ b/testdata/project-v3-config/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: default + namespace: system diff --git a/testdata/project-v3-config/config/rbac/auth_proxy_service.yaml b/testdata/project-v3-config/config/rbac/auth_proxy_service.yaml new file mode 100644 index 00000000000..6cf656be149 --- /dev/null +++ b/testdata/project-v3-config/config/rbac/auth_proxy_service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + name: controller-manager-metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + targetPort: https + selector: + control-plane: controller-manager diff --git a/testdata/project-v3-config/config/rbac/captain_editor_role.yaml b/testdata/project-v3-config/config/rbac/captain_editor_role.yaml new file mode 100644 index 00000000000..4b53ae38ffa --- /dev/null +++ b/testdata/project-v3-config/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-config/config/rbac/captain_viewer_role.yaml b/testdata/project-v3-config/config/rbac/captain_viewer_role.yaml new file mode 100644 index 00000000000..f19e10439d2 --- /dev/null +++ b/testdata/project-v3-config/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-config/config/rbac/firstmate_editor_role.yaml b/testdata/project-v3-config/config/rbac/firstmate_editor_role.yaml new file mode 100644 index 00000000000..22a08be29dd --- /dev/null +++ b/testdata/project-v3-config/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-config/config/rbac/firstmate_viewer_role.yaml b/testdata/project-v3-config/config/rbac/firstmate_viewer_role.yaml new file mode 100644 index 00000000000..9fd6ba933c7 --- /dev/null +++ b/testdata/project-v3-config/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-config/config/rbac/kustomization.yaml b/testdata/project-v3-config/config/rbac/kustomization.yaml new file mode 100644 index 00000000000..66c28338fe0 --- /dev/null +++ b/testdata/project-v3-config/config/rbac/kustomization.yaml @@ -0,0 +1,12 @@ +resources: +- 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-config/config/rbac/leader_election_role.yaml b/testdata/project-v3-config/config/rbac/leader_election_role.yaml new file mode 100644 index 00000000000..6334cc51c83 --- /dev/null +++ b/testdata/project-v3-config/config/rbac/leader_election_role.yaml @@ -0,0 +1,27 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: leader-election-role +rules: +- apiGroups: + - "" + - coordination.k8s.io + resources: + - configmaps + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/testdata/project-v3-config/config/rbac/leader_election_role_binding.yaml b/testdata/project-v3-config/config/rbac/leader_election_role_binding.yaml new file mode 100644 index 00000000000..eed16906f4d --- /dev/null +++ b/testdata/project-v3-config/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: default + namespace: system diff --git a/testdata/project-v3-config/config/rbac/role.yaml b/testdata/project-v3-config/config/rbac/role.yaml new file mode 100644 index 00000000000..1d105256811 --- /dev/null +++ b/testdata/project-v3-config/config/rbac/role.yaml @@ -0,0 +1,112 @@ + +--- +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-config/config/rbac/role_binding.yaml b/testdata/project-v3-config/config/rbac/role_binding.yaml new file mode 100644 index 00000000000..8f2658702c8 --- /dev/null +++ b/testdata/project-v3-config/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: default + namespace: system diff --git a/testdata/project-v3-config/config/samples/crew_v1_admiral.yaml b/testdata/project-v3-config/config/samples/crew_v1_admiral.yaml new file mode 100644 index 00000000000..0fd9ae039ef --- /dev/null +++ b/testdata/project-v3-config/config/samples/crew_v1_admiral.yaml @@ -0,0 +1,7 @@ +apiVersion: crew.testproject.org/v1 +kind: Admiral +metadata: + name: admiral-sample +spec: + # Add fields here + foo: bar diff --git a/testdata/project-v3-config/config/samples/crew_v1_captain.yaml b/testdata/project-v3-config/config/samples/crew_v1_captain.yaml new file mode 100644 index 00000000000..2b1254f53f9 --- /dev/null +++ b/testdata/project-v3-config/config/samples/crew_v1_captain.yaml @@ -0,0 +1,7 @@ +apiVersion: crew.testproject.org/v1 +kind: Captain +metadata: + name: captain-sample +spec: + # Add fields here + foo: bar diff --git a/testdata/project-v3-config/config/samples/crew_v1_firstmate.yaml b/testdata/project-v3-config/config/samples/crew_v1_firstmate.yaml new file mode 100644 index 00000000000..36e6be0b6fe --- /dev/null +++ b/testdata/project-v3-config/config/samples/crew_v1_firstmate.yaml @@ -0,0 +1,7 @@ +apiVersion: crew.testproject.org/v1 +kind: FirstMate +metadata: + name: firstmate-sample +spec: + # Add fields here + foo: bar diff --git a/testdata/project-v3-config/config/webhook/kustomization.yaml b/testdata/project-v3-config/config/webhook/kustomization.yaml new file mode 100644 index 00000000000..9cf26134e4d --- /dev/null +++ b/testdata/project-v3-config/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/testdata/project-v3-config/config/webhook/kustomizeconfig.yaml b/testdata/project-v3-config/config/webhook/kustomizeconfig.yaml new file mode 100644 index 00000000000..25e21e3c963 --- /dev/null +++ b/testdata/project-v3-config/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-config/config/webhook/manifests.yaml b/testdata/project-v3-config/config/webhook/manifests.yaml new file mode 100644 index 00000000000..ecb1136b5d4 --- /dev/null +++ b/testdata/project-v3-config/config/webhook/manifests.yaml @@ -0,0 +1,76 @@ + +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1beta1 + 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: + - v1beta1 + 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: + - v1beta1 + 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-config/config/webhook/service.yaml b/testdata/project-v3-config/config/webhook/service.yaml new file mode 100644 index 00000000000..31e0f829591 --- /dev/null +++ b/testdata/project-v3-config/config/webhook/service.yaml @@ -0,0 +1,12 @@ + +apiVersion: v1 +kind: Service +metadata: + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + targetPort: 9443 + selector: + control-plane: controller-manager diff --git a/testdata/project-v3-config/controllers/admiral_controller.go b/testdata/project-v3-config/controllers/admiral_controller.go new file mode 100644 index 00000000000..1d894baf856 --- /dev/null +++ b/testdata/project-v3-config/controllers/admiral_controller.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 controllers + +import ( + "context" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v3-config/api/v1" +) + +// AdmiralReconciler reconciles a Admiral object +type AdmiralReconciler struct { + client.Client + Log logr.Logger + 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.7.0-alpha.6/pkg/reconcile +func (r *AdmiralReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = r.Log.WithValues("admiral", req.NamespacedName) + + // 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-config/controllers/captain_controller.go b/testdata/project-v3-config/controllers/captain_controller.go new file mode 100644 index 00000000000..6ff1e6ba5b4 --- /dev/null +++ b/testdata/project-v3-config/controllers/captain_controller.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 controllers + +import ( + "context" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v3-config/api/v1" +) + +// CaptainReconciler reconciles a Captain object +type CaptainReconciler struct { + client.Client + Log logr.Logger + 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.7.0-alpha.6/pkg/reconcile +func (r *CaptainReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = r.Log.WithValues("captain", req.NamespacedName) + + // 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-config/controllers/firstmate_controller.go b/testdata/project-v3-config/controllers/firstmate_controller.go new file mode 100644 index 00000000000..3d70848c244 --- /dev/null +++ b/testdata/project-v3-config/controllers/firstmate_controller.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 controllers + +import ( + "context" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v3-config/api/v1" +) + +// FirstMateReconciler reconciles a FirstMate object +type FirstMateReconciler struct { + client.Client + Log logr.Logger + 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.7.0-alpha.6/pkg/reconcile +func (r *FirstMateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = r.Log.WithValues("firstmate", req.NamespacedName) + + // 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-config/controllers/laker_controller.go b/testdata/project-v3-config/controllers/laker_controller.go new file mode 100644 index 00000000000..e41f85dd043 --- /dev/null +++ b/testdata/project-v3-config/controllers/laker_controller.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 controllers + +import ( + "context" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// LakerReconciler reconciles a Laker object +type LakerReconciler struct { + client.Client + Log logr.Logger + 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.7.0-alpha.6/pkg/reconcile +func (r *LakerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = r.Log.WithValues("laker", req.NamespacedName) + + // 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-config/controllers/suite_test.go b/testdata/project-v3-config/controllers/suite_test.go new file mode 100644 index 00000000000..c2fb4129bb5 --- /dev/null +++ b/testdata/project-v3-config/controllers/suite_test.go @@ -0,0 +1,85 @@ +/* +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 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-config/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")}, + } + + cfg, err := testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = crewv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + err = crewv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + 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-config/go.mod b/testdata/project-v3-config/go.mod new file mode 100644 index 00000000000..138106a1bdf --- /dev/null +++ b/testdata/project-v3-config/go.mod @@ -0,0 +1,13 @@ +module sigs.k8s.io/kubebuilder/testdata/project-v3-config + +go 1.15 + +require ( + github.com/go-logr/logr v0.2.1 + github.com/onsi/ginkgo v1.14.1 + github.com/onsi/gomega v1.10.2 + k8s.io/api v0.19.2 + k8s.io/apimachinery v0.19.2 + k8s.io/client-go v0.19.2 + sigs.k8s.io/controller-runtime v0.7.0-alpha.6 +) diff --git a/testdata/project-v3-config/hack/boilerplate.go.txt b/testdata/project-v3-config/hack/boilerplate.go.txt new file mode 100644 index 00000000000..b75c7954b88 --- /dev/null +++ b/testdata/project-v3-config/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +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. +*/ \ No newline at end of file diff --git a/testdata/project-v3-config/main.go b/testdata/project-v3-config/main.go new file mode 100644 index 00000000000..2d78f6c1121 --- /dev/null +++ b/testdata/project-v3-config/main.go @@ -0,0 +1,131 @@ +/* +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 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/log/zap" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v3-config/api/v1" + "sigs.k8s.io/kubebuilder/testdata/project-v3-config/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 configFile string + flag.StringVar(&configFile, "config", "", + "The controller will load its initial configuration from this file. "+ + "Omit this flag to use the default configuration values. "+ + "Command-line flags override configuration from this file.") + opts := zap.Options{ + Development: true, + } + opts.BindFlags(flag.CommandLine) + flag.Parse() + + ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + + var err error + options := ctrl.Options{Scheme: scheme} + if configFile != "" { + options, err = options.AndFrom(ctrl.ConfigFile().AtPath(configFile)) + if err != nil { + setupLog.Error(err, "unable to load the config file") + os.Exit(1) + } + } + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + if err = (&controllers.CaptainReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("Captain"), + 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(), + Log: ctrl.Log.WithName("controllers").WithName("FirstMate"), + 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(), + Log: ctrl.Log.WithName("controllers").WithName("Admiral"), + 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(), + Log: ctrl.Log.WithName("controllers").WithName("Laker"), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Laker") + os.Exit(1) + } + // +kubebuilder:scaffold:builder + + setupLog.Info("starting manager") + if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} diff --git a/testdata/project-v3-multigroup/config/default/kustomization.yaml b/testdata/project-v3-multigroup/config/default/kustomization.yaml index 9511b097e70..5391c2c6431 100644 --- a/testdata/project-v3-multigroup/config/default/kustomization.yaml +++ b/testdata/project-v3-multigroup/config/default/kustomization.yaml @@ -25,11 +25,15 @@ bases: #- ../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. +# 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 diff --git a/testdata/project-v3-multigroup/config/default/manager_auth_proxy_patch.yaml b/testdata/project-v3-multigroup/config/default/manager_auth_proxy_patch.yaml index 77e743d1c1c..a945ed173a7 100644 --- a/testdata/project-v3-multigroup/config/default/manager_auth_proxy_patch.yaml +++ b/testdata/project-v3-multigroup/config/default/manager_auth_proxy_patch.yaml @@ -1,4 +1,4 @@ -# This patch inject a sidecar container which is a HTTP proxy for the +# 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 diff --git a/testdata/project-v3-multigroup/config/default/manager_config_patch.yaml b/testdata/project-v3-multigroup/config/default/manager_config_patch.yaml new file mode 100644 index 00000000000..6c400155cfb --- /dev/null +++ b/testdata/project-v3-multigroup/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-multigroup/config/manager/controller_manager_config.yaml b/testdata/project-v3-multigroup/config/manager/controller_manager_config.yaml new file mode 100644 index 00000000000..a9567425fdf --- /dev/null +++ b/testdata/project-v3-multigroup/config/manager/controller_manager_config.yaml @@ -0,0 +1,9 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: 14be1926.testproject.org diff --git a/testdata/project-v3-multigroup/config/manager/kustomization.yaml b/testdata/project-v3-multigroup/config/manager/kustomization.yaml index 5c5f0b84cba..2bcd3eeaa94 100644 --- a/testdata/project-v3-multigroup/config/manager/kustomization.yaml +++ b/testdata/project-v3-multigroup/config/manager/kustomization.yaml @@ -1,2 +1,10 @@ resources: - manager.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: +- name: manager-config + files: + - controller_manager_config.yaml diff --git a/testdata/project-v3-multigroup/main.go b/testdata/project-v3-multigroup/main.go index bb5f5ef3abb..bdd1985f78d 100644 --- a/testdata/project-v3-multigroup/main.go +++ b/testdata/project-v3-multigroup/main.go @@ -73,7 +73,6 @@ func main() { flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") - opts := zap.Options{ Development: true, } diff --git a/testdata/project-v3/config/default/kustomization.yaml b/testdata/project-v3/config/default/kustomization.yaml index 478bb802596..3680acb0fdd 100644 --- a/testdata/project-v3/config/default/kustomization.yaml +++ b/testdata/project-v3/config/default/kustomization.yaml @@ -25,11 +25,15 @@ bases: #- ../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. +# 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 diff --git a/testdata/project-v3/config/default/manager_auth_proxy_patch.yaml b/testdata/project-v3/config/default/manager_auth_proxy_patch.yaml index 77e743d1c1c..a945ed173a7 100644 --- a/testdata/project-v3/config/default/manager_auth_proxy_patch.yaml +++ b/testdata/project-v3/config/default/manager_auth_proxy_patch.yaml @@ -1,4 +1,4 @@ -# This patch inject a sidecar container which is a HTTP proxy for the +# 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 diff --git a/testdata/project-v3/config/default/manager_config_patch.yaml b/testdata/project-v3/config/default/manager_config_patch.yaml new file mode 100644 index 00000000000..6c400155cfb --- /dev/null +++ b/testdata/project-v3/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/config/manager/controller_manager_config.yaml b/testdata/project-v3/config/manager/controller_manager_config.yaml new file mode 100644 index 00000000000..7ea15c6957d --- /dev/null +++ b/testdata/project-v3/config/manager/controller_manager_config.yaml @@ -0,0 +1,9 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: dd1da13f.testproject.org diff --git a/testdata/project-v3/config/manager/kustomization.yaml b/testdata/project-v3/config/manager/kustomization.yaml index 5c5f0b84cba..2bcd3eeaa94 100644 --- a/testdata/project-v3/config/manager/kustomization.yaml +++ b/testdata/project-v3/config/manager/kustomization.yaml @@ -1,2 +1,10 @@ resources: - manager.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: +- name: manager-config + files: + - controller_manager_config.yaml diff --git a/testdata/project-v3/main.go b/testdata/project-v3/main.go index 4488ab146e8..c5af531bc28 100644 --- a/testdata/project-v3/main.go +++ b/testdata/project-v3/main.go @@ -54,7 +54,6 @@ func main() { flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") - opts := zap.Options{ Development: true, }