diff --git a/cmd/main.go b/cmd/main.go index 64a25502cd7..f0e35e16663 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -30,6 +30,7 @@ import ( deployimagev1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/deploy-image/v1alpha1" golangv4 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/v4" grafanav1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha" + helmv1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha" ) func init() { @@ -61,6 +62,7 @@ func main() { &kustomizecommonv2.Plugin{}, &deployimagev1alpha1.Plugin{}, &grafanav1alpha1.Plugin{}, + &helmv1alpha1.Plugin{}, ), cli.WithPlugins(externalPlugins...), cli.WithDefaultPlugins(cfgv3.Version, gov4Bundle), diff --git a/pkg/plugins/optional/helm/v1alpha/edit.go b/pkg/plugins/optional/helm/v1alpha/edit.go new file mode 100644 index 00000000000..ac17fac8567 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/edit.go @@ -0,0 +1,57 @@ +/* +Copyright 2024 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 v1alpha + +import ( + "fmt" + "github.com/spf13/pflag" + "sigs.k8s.io/kubebuilder/v4/pkg/config" + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" + "sigs.k8s.io/kubebuilder/v4/pkg/plugin" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds" +) + +var _ plugin.EditSubcommand = &editSubcommand{} + +type editSubcommand struct { + config config.Config + force bool +} + +func (p *editSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) { + subcmdMeta.Description = `Initialize a helm chart to distribute the project under dist/ +` + subcmdMeta.Examples = fmt.Sprintf(` # Initialize a helm chart to distribute the project under dist/ + %[1]s edit --plugins helm/v1alpha + +`, cliMeta.CommandName) +} + +func (p *editSubcommand) BindFlags(fs *pflag.FlagSet) { + fs.BoolVar(&p.force, "force", true, "if true, run re-generate the files") +} + +func (p *editSubcommand) InjectConfig(c config.Config) error { + p.config = c + return nil +} + +func (p *editSubcommand) Scaffold(fs machinery.Filesystem) error { + scaffolder := scaffolds.NewInitScaffolder() + scaffolder.InjectFS(fs) + return scaffolder.Scaffold() +} diff --git a/pkg/plugins/optional/helm/v1alpha/init.go b/pkg/plugins/optional/helm/v1alpha/init.go new file mode 100644 index 00000000000..2b6c21e06e0 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/init.go @@ -0,0 +1,53 @@ +/* +Copyright 2024 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 v1alpha + +import ( + "fmt" + + "sigs.k8s.io/kubebuilder/v4/pkg/config" + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" + "sigs.k8s.io/kubebuilder/v4/pkg/plugin" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha/scaffolds" +) + +var _ plugin.InitSubcommand = &initSubcommand{} + +type initSubcommand struct { + config config.Config +} + +func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) { + subcmdMeta.Description = `Initialize a helm chart to distribute the project under dist/ +` + subcmdMeta.Examples = fmt.Sprintf(` # Initialize a helm chart to distribute the project under dist/ + %[1]s init --plugins helm/v1alpha + +`, cliMeta.CommandName) +} + +func (p *initSubcommand) InjectConfig(c config.Config) error { + p.config = c + return nil +} + +func (p *initSubcommand) Scaffold(fs machinery.Filesystem) error { + + scaffolder := scaffolds.NewInitScaffolder() + scaffolder.InjectFS(fs) + return scaffolder.Scaffold() +} diff --git a/pkg/plugins/optional/helm/v1alpha/plugin.go b/pkg/plugins/optional/helm/v1alpha/plugin.go new file mode 100644 index 00000000000..e43dd41316a --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/plugin.go @@ -0,0 +1,64 @@ +/* +Copyright 2024 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 v1alpha + +import ( + "sigs.k8s.io/kubebuilder/v4/pkg/config" + cfgv3 "sigs.k8s.io/kubebuilder/v4/pkg/config/v3" + "sigs.k8s.io/kubebuilder/v4/pkg/model/stage" + "sigs.k8s.io/kubebuilder/v4/pkg/plugin" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins" +) + +const pluginName = "helm." + plugins.DefaultNameQualifier + +var ( + pluginVersion = plugin.Version{Number: 1, Stage: stage.Alpha} + supportedProjectVersions = []config.Version{cfgv3.Version} + pluginKey = plugin.KeyFor(Plugin{}) +) + +// Plugin implements the plugin.Full interface +type Plugin struct { + initSubcommand + editSubcommand +} + +var ( + _ plugin.Init = Plugin{} +) + +// Name returns the name of the plugin +func (Plugin) Name() string { return pluginName } + +// Version returns the version of the grafana plugin +func (Plugin) Version() plugin.Version { return pluginVersion } + +// SupportedProjectVersions returns an array with all project versions supported by the plugin +func (Plugin) SupportedProjectVersions() []config.Version { return supportedProjectVersions } + +// GetInitSubcommand will return the subcommand which is responsible for initializing and scaffolding grafana manifests +func (p Plugin) GetInitSubcommand() plugin.InitSubcommand { return &p.initSubcommand } + +// GetEditSubcommand will return the subcommand which is responsible for adding grafana manifests +func (p Plugin) GetEditSubcommand() plugin.EditSubcommand { return &p.editSubcommand } + +type pluginConfig struct{} + +func (p Plugin) DeprecationWarning() string { + return "" +} diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go new file mode 100644 index 00000000000..8ad6d58480c --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go @@ -0,0 +1,145 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package scaffolds + +import ( + "fmt" + log "github.com/sirupsen/logrus" + "io/ioutil" + "os" + "path/filepath" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates" + "strings" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins" +) + +var _ plugins.Scaffolder = &initScaffolder{} + +type initScaffolder struct { + fs machinery.Filesystem +} + +// NewInitScaffolder returns a new Scaffolder for project initialization operations +func NewInitScaffolder() plugins.Scaffolder { + return &initScaffolder{} +} + +// InjectFS implements cmdutil.Scaffolder +func (s *initScaffolder) InjectFS(fs machinery.Filesystem) { + s.fs = fs +} + +// Scaffold implements cmdutil.Scaffolder +func (s *initScaffolder) Scaffold() error { + log.Println("Generating Helm Chart to distribute project") + + scaffold := machinery.NewScaffold(s.fs) + + err := scaffold.Execute( + &templates.HelmChart{}, + &templates.HelmValues{}, + &templates.HelmIgnore{}, + ) + if err != nil { + return err + } + + // Copy all relevant files from config/ to chart/templates/ + err = copyConfigFiles() + if err != nil { + return err + } + return nil +} + +// Helper function to copy files from config/ to dist/chart/templates/ +func copyConfigFiles() error { + // Define the source directories and destination directories under dist/chart/templates + configDirs := []struct { + SrcDir string + DestDir string + SubDir string + }{ + {"config/rbac", "dist/chart/templates/rbac", "rbac"}, + {"config/manager", "dist/chart/templates/manager", "controllerManager"}, + {"config/webhook", "dist/chart/templates/webhook", "webhook"}, + {"config/crd/bases", "dist/chart/templates/crds", "crd"}, + {"config/prometheus", "dist/chart/templates/prometheus", "prometheus"}, + {"config/certmanager", "dist/chart/templates/certmanager", "certmanager"}, + {"config/network-policy", "dist/chart/templates/network-policy", "networkPolicy"}, + } + + // Copy all YAML files in each directory + for _, dir := range configDirs { + files, err := filepath.Glob(filepath.Join(dir.SrcDir, "*.yaml")) + if err != nil { + return err + } + + for _, srcFile := range files { + destFile := filepath.Join(dir.DestDir, filepath.Base(srcFile)) + err := copyFileWithHelmLogic(srcFile, destFile, dir.SubDir) + if err != nil { + return err + } + } + } + + return nil +} + +// copyFileWithHelmLogic reads the source file, wraps it with Helm logic, and writes it to the destination +func copyFileWithHelmLogic(srcFile, destFile, subDir string) error { + // Ensure the source file exists + if _, err := os.Stat(srcFile); os.IsNotExist(err) { + log.Printf("Source file does not exist: %s", srcFile) + return err + } + + // Read the source file + content, err := ioutil.ReadFile(srcFile) + if err != nil { + log.Printf("Error reading source file: %s", srcFile) + return err + } + + // Skip irrelevant files like kustomization.yaml + if strings.HasSuffix(srcFile, "kustomization.yaml") || strings.HasSuffix(srcFile, "kustomizeconfig.yaml") { + log.Printf("Skipping irrelevant file: %s", srcFile) + return nil + } + + // Wrap the content with Helm conditional logic based on the subdirectory (e.g., "rbac", "manager") + wrappedContent := fmt.Sprintf("{{- if .Values.%s.create }}\n%s\n{{- end }}\n", subDir, string(content)) + + // Ensure the destination directory exists + if err := os.MkdirAll(filepath.Dir(destFile), os.ModePerm); err != nil { + return err + } + + // Write the wrapped content to the destination file + err = ioutil.WriteFile(destFile, []byte(wrappedContent), os.ModePerm) + if err != nil { + log.Printf("Error writing destination file: %s", destFile) + return err + } + + log.Printf("Successfully copied %s to %s", srcFile, destFile) + return nil +} diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart.go new file mode 100644 index 00000000000..134f870e34f --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart.go @@ -0,0 +1,63 @@ +/* +Copyright 2024 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 templates + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &HelmChart{} + +// Chart scaffolds a file that defines the Helm chart structure +type HelmChart struct { + machinery.TemplateMixin + machinery.ProjectNameMixin + + Force bool +} + +// SetTemplateDefaults implements file.Template +func (f *HelmChart) SetTemplateDefaults() error { + // Define the path where the Helm Chart.yaml will be created + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "Chart.yaml") + } + + // Use the chart template defined below + f.TemplateBody = helmChartTemplate + + // Define file handling action based on Force flag + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + // If file exists (ex. because a Helm chart was already created), skip creation. + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// Define the content for the Chart.yaml file +const helmChartTemplate = `apiVersion: v2 +name: {{ .ProjectName }} +description: A Helm chart to distribute the project {{ .ProjectName }} +type: application +version: 0.1.0 +appVersion: "0.1.0" +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/helmignore.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/helmignore.go new file mode 100644 index 00000000000..8ea99a38992 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/helmignore.go @@ -0,0 +1,104 @@ +/* +Copyright 2024 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 templates + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &HelmIgnore{} + +// HelmIgnore scaffolds a file that defines the .helmignore for Helm packaging +type HelmIgnore struct { + machinery.TemplateMixin + + Force bool +} + +// SetTemplateDefaults implements file.Template +func (f *HelmIgnore) SetTemplateDefaults() error { + // Define the path where the .helmignore will be created + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", ".helmignore") + } + + // Use the .helmignore template defined below + f.TemplateBody = helmIgnoreTemplate + + // Define file handling action based on Force flag + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + // If file exists, skip creation. + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// Define the content for the .helmignore file +const helmIgnoreTemplate = `# Patterns to ignore when building Helm packages. +# Supports shell glob matching, relative path matching, and negation. + +# Operating system files +.DS_Store + +# Version control directories +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ + +# Backup and temporary files +*.swp +*.swo +*.tmp +*.bak +*.orig +*~ + +# IDE and editor-related files +.idea/ +.vscode/ +*.tmproj +.project + +# Go-related files +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin/* +Dockerfile.cross +*.test +*.out + +# Go workspace file +go.work + +# Ignore Kubernetes generated files (except vendored files) +!vendor/**/zz_generated.* + +# Helm chart artifacts in the dist/chart directory +dist/chart/*.tgz +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go new file mode 100644 index 00000000000..8ff7f0e39f5 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go @@ -0,0 +1,90 @@ +/* +Copyright 2024 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 templates + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &HelmValues{} + +// Values scaffolds a file that defines the values.yaml structure for the Helm chart +type HelmValues struct { + machinery.TemplateMixin + machinery.ResourceMixin + + Force bool +} + +// SetTemplateDefaults implements file.Template +func (f *HelmValues) SetTemplateDefaults() error { + // Define the path where the values.yaml will be created + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "values.yaml") + } + + // Use the values.yaml template defined below + f.TemplateBody = helmValuesTemplate + + // Define file handling action based on Force flag + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + // If file exists, skip creation. + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// Define the content for the values.yaml file +const helmValuesTemplate = `# Default values for the Kubebuilder Helm chart + +# RBAC settings +# Set to false to skip creating RBAC resources (roles, bindings, service accounts) +rbac: + create: true + +# Controller Manager settings +# Set to false to skip creating the controller manager deployment +controllerManager: + create: true + +# Webhook service settings +webhook: + create: true + +# CRDs settings +# Set to false to skip creating CustomResourceDefinitions (CRDs) +crd: + create: true + +# Prometheus monitoring settings +# Set to false to skip creating Prometheus monitoring resources +prometheus: + create: true + +# CertManager settings for certificates +certmanager: + create: false + +# Network policies +networkPolicy: + create: false +` diff --git a/test/e2e/utils/test_context.go b/test/e2e/utils/test_context.go index 922e235aa29..fddd1782a67 100644 --- a/test/e2e/utils/test_context.go +++ b/test/e2e/utils/test_context.go @@ -331,3 +331,43 @@ func (t *TestContext) AllowProjectBeMultiGroup() error { } return nil } + +// InstallHelm installs Helm in the e2e server. +func (t *TestContext) InstallHelm() error { + // You can fetch the latest Helm installation script from its official website + helmInstallScript := "https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3" + + // Use curl to fetch the Helm installation script and install Helm + cmd := exec.Command("bash", "-c", fmt.Sprintf("curl -fsSL %s | bash", helmInstallScript)) + + // Run the command to install Helm + if output, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("failed to install Helm: %s", string(output)) + } + + // Optionally verify that Helm was installed correctly by running `helm version` + verifyCmd := exec.Command("helm", "version") + if output, err := verifyCmd.CombinedOutput(); err != nil { + return fmt.Errorf("failed to verify Helm installation: %s", string(output)) + } + + return nil +} + +// UninstallHelmRelease removes the specified Helm release from the cluster. +func (t *TestContext) UninstallHelmRelease(releaseName, namespace string) error { + // Uninstall the Helm release + cmd := exec.Command("helm", "uninstall", releaseName, "--namespace", namespace) + + // Run the command to uninstall the Helm release + if output, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("failed to uninstall Helm release %s: %s", releaseName, string(output)) + } + + // Optionally wait for the namespace to be cleaned up + if _, err := t.Kubectl.Wait(false, "namespace", namespace, "--for=delete", "--timeout=2m"); err != nil { + return fmt.Errorf("failed to wait for namespace deletion: %s", err) + } + + return nil +} diff --git a/test/e2e/v4/plugin_cluster_test.go b/test/e2e/v4/plugin_cluster_test.go index 8c47403369b..21292ced3d3 100644 --- a/test/e2e/v4/plugin_cluster_test.go +++ b/test/e2e/v4/plugin_cluster_test.go @@ -69,39 +69,51 @@ var _ = Describe("kubebuilder", func() { It("should generate a runnable project", func() { kbc.IsRestricted = false GenerateV4(kbc) - Run(kbc, true, false, true, false) + Run(kbc, true, false, false, true, false) }) It("should generate a runnable project with the Installer", func() { kbc.IsRestricted = false GenerateV4(kbc) - Run(kbc, false, true, true, false) + Run(kbc, false, true, false, true, false) + }) + It("should generate a runnable project with the HelmChart", func() { + kbc.IsRestricted = false + GenerateV4(kbc) + + // Install Helm before running the tests + Expect(kbc.InstallHelm()).To(Succeed()) + + Run(kbc, false, false, true, true, false) + + // After test execution, uninstall the Helm release + Expect(kbc.UninstallHelmRelease("my-helm-release", "default")).To(Succeed()) }) It("should generate a runnable project without metrics exposed", func() { kbc.IsRestricted = false GenerateV4WithoutMetrics(kbc) - Run(kbc, true, false, false, false) + Run(kbc, true, false, false, false, false) }) It("should generate a runnable project with metrics protected by network policies", func() { kbc.IsRestricted = false GenerateV4WithNetworkPoliciesWithoutWebhooks(kbc) - Run(kbc, false, false, true, true) + Run(kbc, false, false, false, true, true) }) It("should generate a runnable project with webhooks and metrics protected by network policies", func() { kbc.IsRestricted = false GenerateV4WithNetworkPolicies(kbc) - Run(kbc, true, false, true, true) + Run(kbc, true, false, false, true, true) }) It("should generate a runnable project with the manager running "+ "as restricted and without webhooks", func() { kbc.IsRestricted = true GenerateV4WithoutWebhooks(kbc) - Run(kbc, false, false, true, false) + Run(kbc, false, false, false, true, false) }) }) }) // Run runs a set of e2e tests for a scaffolded project defined by a TestContext. -func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, hasMetrics bool, hasNetworkPolicies bool) { +func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, isToUseHelmChart, hasMetrics bool, hasNetworkPolicies bool) { var controllerPodName string var err error var output []byte @@ -132,14 +144,14 @@ func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, hasMetrics bool, err = kbc.LoadImageToKindCluster() ExpectWithOffset(1, err).NotTo(HaveOccurred()) - if !isToUseInstaller { + if !isToUseInstaller && !isToUseHelmChart { By("deploying the controller-manager") cmd := exec.Command("make", "deploy", "IMG="+kbc.ImageName) output, err = kbc.Run(cmd) ExpectWithOffset(1, err).NotTo(HaveOccurred()) } - if isToUseInstaller { + if isToUseInstaller && !isToUseHelmChart { By("building the installer") err = kbc.Make("build-installer", "IMG="+kbc.ImageName) ExpectWithOffset(1, err).NotTo(HaveOccurred()) @@ -149,6 +161,17 @@ func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, hasMetrics bool, ExpectWithOffset(1, err).NotTo(HaveOccurred()) } + if isToUseHelmChart && !isToUseInstaller { + By("building the helm-chart") + cmd := exec.Command("kubebuilder", "edit", "plugins=helm.kubebuilder.io/v1-alpha") + output, err = kbc.Run(cmd) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("install with Helm") + cmd = exec.Command("helm", "install", "./dist/chart") + output, err = kbc.Run(cmd) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + } if kbc.IsRestricted { By("validating that manager Pod/container(s) are restricted") ExpectWithOffset(1, output).NotTo(ContainSubstring("Warning: would violate PodSecurity")) diff --git a/test/testdata/generate.sh b/test/testdata/generate.sh index f9d5d2f3d8d..71acc38a963 100755 --- a/test/testdata/generate.sh +++ b/test/testdata/generate.sh @@ -95,6 +95,12 @@ function scaffold_test_project { make all make build-installer + + if [[ $project =~ multigroup ]] || [[ $project =~ with-plugins ]] ; then + header_text 'Editing project with Helm plugin ...' + $kb edit --plugins=helm.kubebuilder.io/v1-alpha + fi + # To avoid conflicts rm -f go.sum go mod tidy diff --git a/testdata/project-v4-multigroup/.devcontainer/devcontainer.json b/testdata/project-v4-multigroup/.devcontainer/devcontainer.json deleted file mode 100644 index e2cdc09c96c..00000000000 --- a/testdata/project-v4-multigroup/.devcontainer/devcontainer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "Kubebuilder DevContainer", - "image": "golang:1.22", - "features": { - "ghcr.io/devcontainers/features/docker-in-docker:2": {}, - "ghcr.io/devcontainers/features/git:1": {} - }, - - "runArgs": ["--network=host"], - - "customizations": { - "vscode": { - "settings": { - "terminal.integrated.shell.linux": "/bin/bash" - }, - "extensions": [ - "ms-kubernetes-tools.vscode-kubernetes-tools", - "ms-azuretools.vscode-docker" - ] - } - }, - - "onCreateCommand": "bash .devcontainer/post-install.sh" -} - diff --git a/testdata/project-v4-multigroup/.devcontainer/post-install.sh b/testdata/project-v4-multigroup/.devcontainer/post-install.sh deleted file mode 100644 index 265c43ee8d3..00000000000 --- a/testdata/project-v4-multigroup/.devcontainer/post-install.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -set -x - -curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64 -chmod +x ./kind -mv ./kind /usr/local/bin/kind - -curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/linux/amd64 -chmod +x kubebuilder -mv kubebuilder /usr/local/bin/ - -KUBECTL_VERSION=$(curl -L -s https://dl.k8s.io/release/stable.txt) -curl -LO "https://dl.k8s.io/release/$KUBECTL_VERSION/bin/linux/amd64/kubectl" -chmod +x kubectl -mv kubectl /usr/local/bin/kubectl - -docker network create -d=bridge --subnet=172.19.0.0/24 kind - -kind version -kubebuilder version -docker --version -go version -kubectl version --client diff --git a/testdata/project-v4-multigroup/.dockerignore b/testdata/project-v4-multigroup/.dockerignore deleted file mode 100644 index a3aab7af70c..00000000000 --- a/testdata/project-v4-multigroup/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file -# Ignore build and test binaries. -bin/ diff --git a/testdata/project-v4-multigroup/.github/workflows/lint.yml b/testdata/project-v4-multigroup/.github/workflows/lint.yml deleted file mode 100644 index b6967b35f4f..00000000000 --- a/testdata/project-v4-multigroup/.github/workflows/lint.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Lint - -on: - push: - pull_request: - -jobs: - lint: - name: Run on Ubuntu - runs-on: ubuntu-latest - steps: - - name: Clone the code - uses: actions/checkout@v4 - - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: '~1.22' - - - name: Run linter - uses: golangci/golangci-lint-action@v6 - with: - version: v1.59 diff --git a/testdata/project-v4-multigroup/.github/workflows/test-e2e.yml b/testdata/project-v4-multigroup/.github/workflows/test-e2e.yml deleted file mode 100644 index 8780644002a..00000000000 --- a/testdata/project-v4-multigroup/.github/workflows/test-e2e.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: E2E Tests - -on: - push: - pull_request: - -jobs: - test-e2e: - name: Run on Ubuntu - runs-on: ubuntu-latest - steps: - - name: Clone the code - uses: actions/checkout@v4 - - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: '~1.22' - - - name: Install the latest version of kind - run: | - curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64 - chmod +x ./kind - sudo mv ./kind /usr/local/bin/kind - - - name: Verify kind installation - run: kind version - - - name: Create kind cluster - run: kind create cluster - - - name: Running Test e2e - run: | - go mod tidy - make test-e2e diff --git a/testdata/project-v4-multigroup/.github/workflows/test.yml b/testdata/project-v4-multigroup/.github/workflows/test.yml deleted file mode 100644 index 7baf6579399..00000000000 --- a/testdata/project-v4-multigroup/.github/workflows/test.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Tests - -on: - push: - pull_request: - -jobs: - test: - name: Run on Ubuntu - runs-on: ubuntu-latest - steps: - - name: Clone the code - uses: actions/checkout@v4 - - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: '~1.22' - - - name: Running Tests - run: | - go mod tidy - make test diff --git a/testdata/project-v4-multigroup/.gitignore b/testdata/project-v4-multigroup/.gitignore deleted file mode 100644 index ada68ff086c..00000000000 --- a/testdata/project-v4-multigroup/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib -bin/* -Dockerfile.cross - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Go workspace file -go.work - -# Kubernetes Generated files - skip generated files, except for vendored files -!vendor/**/zz_generated.* - -# editor and IDE paraphernalia -.idea -.vscode -*.swp -*.swo -*~ diff --git a/testdata/project-v4-multigroup/.golangci.yml b/testdata/project-v4-multigroup/.golangci.yml deleted file mode 100644 index aac8a13f928..00000000000 --- a/testdata/project-v4-multigroup/.golangci.yml +++ /dev/null @@ -1,47 +0,0 @@ -run: - timeout: 5m - allow-parallel-runners: true - -issues: - # don't skip warning about doc comments - # don't exclude the default set of lint - exclude-use-default: false - # restore some of the defaults - # (fill in the rest as needed) - exclude-rules: - - path: "api/*" - linters: - - lll - - path: "internal/*" - linters: - - dupl - - lll -linters: - disable-all: true - enable: - - dupl - - errcheck - - exportloopref - - ginkgolinter - - goconst - - gocyclo - - gofmt - - goimports - - gosimple - - govet - - ineffassign - - lll - - misspell - - nakedret - - prealloc - - revive - - staticcheck - - typecheck - - unconvert - - unparam - - unused - -linters-settings: - revive: - rules: - - name: comment-spacings diff --git a/testdata/project-v4-multigroup/Dockerfile b/testdata/project-v4-multigroup/Dockerfile deleted file mode 100644 index 4ba18b68cc4..00000000000 --- a/testdata/project-v4-multigroup/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -# Build the manager binary -FROM golang:1.22 AS builder -ARG TARGETOS -ARG TARGETARCH - -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 cmd/main.go cmd/main.go -COPY api/ api/ -COPY internal/ internal/ - -# Build -# the GOARCH has not a default value to allow the binary be built according to the host where the command -# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO -# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, -# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. -RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/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-v4-multigroup/Makefile b/testdata/project-v4-multigroup/Makefile deleted file mode 100644 index 259a96b54b4..00000000000 --- a/testdata/project-v4-multigroup/Makefile +++ /dev/null @@ -1,212 +0,0 @@ -# Image URL to use all building/pushing image targets -IMG ?= controller:latest -# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.31.0 - -# 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 - -# CONTAINER_TOOL defines the container tool to be used for building images. -# Be aware that the target commands are only tested with Docker which is -# scaffolded by default. However, you might want to replace it to use other -# tools. (i.e. podman) -CONTAINER_TOOL ?= docker - -# Setting SHELL to bash allows bash commands to be executed by recipes. -# Options are set to exit when a recipe line exits non-zero or a piped command fails. -SHELL = /usr/bin/env bash -o pipefail -.SHELLFLAGS = -ec - -.PHONY: all -all: build - -##@ General - -# The help target prints out all targets with their descriptions organized -# beneath their categories. The categories are represented by '##@' and the -# target descriptions by '##'. The awk command is responsible for reading the -# entire set of makefiles included in this invocation, looking for lines of the -# file as xyz: ## something, and then pretty-format the target and help. Then, -# if there's a line with ##@ something, that gets pretty-printed as a category. -# More info on the usage of ANSI control characters for terminal formatting: -# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters -# More info on the awk command: -# http://linuxcommand.org/lc3_adv_awk.php - -.PHONY: help -help: ## Display this help. - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) - -##@ Development - -.PHONY: manifests -manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. - $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases - -.PHONY: generate -generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." - -.PHONY: fmt -fmt: ## Run go fmt against code. - go fmt ./... - -.PHONY: vet -vet: ## Run go vet against code. - go vet ./... - -.PHONY: test -test: manifests generate fmt vet envtest ## Run tests. - KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out - -# TODO(user): To use a different vendor for e2e tests, modify the setup under 'tests/e2e'. -# The default setup assumes Kind is pre-installed and builds/loads the Manager Docker image locally. -# Prometheus and CertManager are installed by default; skip with: -# - PROMETHEUS_INSTALL_SKIP=true -# - CERT_MANAGER_INSTALL_SKIP=true -.PHONY: test-e2e -test-e2e: manifests generate fmt vet ## Run the e2e tests. Expected an isolated environment using Kind. - @command -v kind >/dev/null 2>&1 || { \ - echo "Kind is not installed. Please install Kind manually."; \ - exit 1; \ - } - @kind get clusters | grep -q 'kind' || { \ - echo "No Kind cluster is running. Please start a Kind cluster before running the e2e tests."; \ - exit 1; \ - } - go test ./test/e2e/ -v -ginkgo.v - -.PHONY: lint -lint: golangci-lint ## Run golangci-lint linter - $(GOLANGCI_LINT) run - -.PHONY: lint-fix -lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes - $(GOLANGCI_LINT) run --fix - -##@ Build - -.PHONY: build -build: manifests generate fmt vet ## Build manager binary. - go build -o bin/manager cmd/main.go - -.PHONY: run -run: manifests generate fmt vet ## Run a controller from your host. - go run ./cmd/main.go - -# If you wish to build the manager image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. -# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -.PHONY: docker-build -docker-build: ## Build docker image with the manager. - $(CONTAINER_TOOL) build -t ${IMG} . - -.PHONY: docker-push -docker-push: ## Push docker image with the manager. - $(CONTAINER_TOOL) push ${IMG} - -# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple -# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: -# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ -# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) -# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. -PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le -.PHONY: docker-buildx -docker-buildx: ## Build and push docker image for the manager for cross-platform support - # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile - sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - - $(CONTAINER_TOOL) buildx create --name project-v4-multigroup-builder - $(CONTAINER_TOOL) buildx use project-v4-multigroup-builder - - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . - - $(CONTAINER_TOOL) buildx rm project-v4-multigroup-builder - rm Dockerfile.cross - -.PHONY: build-installer -build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment. - mkdir -p dist - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default > dist/install.yaml - -##@ Deployment - -ifndef ignore-not-found - ignore-not-found = false -endif - -.PHONY: install -install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. - $(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f - - -.PHONY: uninstall -uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - - -.PHONY: deploy -deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default | $(KUBECTL) apply -f - - -.PHONY: undeploy -undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - - -##@ Dependencies - -## Location to install dependencies to -LOCALBIN ?= $(shell pwd)/bin -$(LOCALBIN): - mkdir -p $(LOCALBIN) - -## Tool Binaries -KUBECTL ?= kubectl -KUSTOMIZE ?= $(LOCALBIN)/kustomize -CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen -ENVTEST ?= $(LOCALBIN)/setup-envtest -GOLANGCI_LINT = $(LOCALBIN)/golangci-lint - -## Tool Versions -KUSTOMIZE_VERSION ?= v5.4.3 -CONTROLLER_TOOLS_VERSION ?= v0.16.4 -ENVTEST_VERSION ?= release-0.19 -GOLANGCI_LINT_VERSION ?= v1.59.1 - -.PHONY: kustomize -kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. -$(KUSTOMIZE): $(LOCALBIN) - $(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_VERSION)) - -.PHONY: controller-gen -controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. -$(CONTROLLER_GEN): $(LOCALBIN) - $(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen,$(CONTROLLER_TOOLS_VERSION)) - -.PHONY: envtest -envtest: $(ENVTEST) ## Download setup-envtest locally if necessary. -$(ENVTEST): $(LOCALBIN) - $(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,$(ENVTEST_VERSION)) - -.PHONY: golangci-lint -golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. -$(GOLANGCI_LINT): $(LOCALBIN) - $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION)) - -# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist -# $1 - target path with name of binary -# $2 - package url which can be installed -# $3 - specific version of package -define go-install-tool -@[ -f "$(1)-$(3)" ] || { \ -set -e; \ -package=$(2)@$(3) ;\ -echo "Downloading $${package}" ;\ -rm -f $(1) || true ;\ -GOBIN=$(LOCALBIN) go install $${package} ;\ -mv $(1) $(1)-$(3) ;\ -} ;\ -ln -sf $(1)-$(3) $(1) -endef diff --git a/testdata/project-v4-multigroup/PROJECT b/testdata/project-v4-multigroup/PROJECT deleted file mode 100644 index ab8ce10ec1e..00000000000 --- a/testdata/project-v4-multigroup/PROJECT +++ /dev/null @@ -1,174 +0,0 @@ -# Code generated by tool. DO NOT EDIT. -# This file is used to track the info used to scaffold your project -# and allow the plugins properly work. -# More info: https://book.kubebuilder.io/reference/project-config.html -domain: testproject.org -layout: -- go.kubebuilder.io/v4 -multigroup: true -plugins: - deploy-image.go.kubebuilder.io/v1-alpha: - resources: - - domain: testproject.org - group: example.com - kind: Memcached - options: - containerCommand: memcached,--memory-limit=64,-o,modern,-v - containerPort: "11211" - image: memcached:memcached:1.6.26-alpine3.19 - runAsUser: "1001" - version: v1alpha1 - - domain: testproject.org - group: example.com - kind: Busybox - options: - image: busybox:1.36.1 - version: v1alpha1 - grafana.kubebuilder.io/v1-alpha: {} -projectName: project-v4-multigroup -repo: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup -resources: -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: crew - kind: Captain - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/crew/v1 - version: v1 - webhooks: - defaulting: true - validation: true - webhookVersion: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: ship - kind: Frigate - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1beta1 - version: v1beta1 - webhooks: - conversion: true - webhookVersion: v1 -- api: - crdVersion: v1 - controller: true - domain: testproject.org - group: ship - kind: Destroyer - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1 - version: v1 - webhooks: - defaulting: true - webhookVersion: v1 -- api: - crdVersion: v1 - controller: true - domain: testproject.org - group: ship - kind: Cruiser - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v2alpha1 - version: v2alpha1 - webhooks: - validation: true - webhookVersion: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: sea-creatures - kind: Kraken - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: sea-creatures - kind: Leviathan - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta2 - version: v1beta2 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: foo.policy - kind: HealthCheckPolicy - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo.policy/v1 - version: v1 -- controller: true - core: true - group: apps - kind: Deployment - path: k8s.io/api/apps/v1 - version: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: foo - kind: Bar - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo/v1 - version: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: fiz - kind: Bar - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/fiz/v1 - version: v1 -- controller: true - domain: io - external: true - group: cert-manager - kind: Certificate - path: github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1 - version: v1 -- domain: io - external: true - group: cert-manager - kind: Issuer - path: github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1 - version: v1 - webhooks: - defaulting: true - webhookVersion: v1 -- core: true - group: core - kind: Pod - path: k8s.io/api/core/v1 - version: v1 - webhooks: - validation: true - webhookVersion: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: example.com - kind: Memcached - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1 - version: v1alpha1 - webhooks: - validation: true - webhookVersion: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: example.com - kind: Busybox - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1 - version: v1alpha1 -version: "3" diff --git a/testdata/project-v4-multigroup/README.md b/testdata/project-v4-multigroup/README.md deleted file mode 100644 index be36750a352..00000000000 --- a/testdata/project-v4-multigroup/README.md +++ /dev/null @@ -1,114 +0,0 @@ -# project-v4-multigroup -// TODO(user): Add simple overview of use/purpose - -## Description -// TODO(user): An in-depth paragraph about your project and overview of use - -## Getting Started - -### Prerequisites -- go version v1.22.0+ -- docker version 17.03+. -- kubectl version v1.11.3+. -- Access to a Kubernetes v1.11.3+ cluster. - -### To Deploy on the cluster -**Build and push your image to the location specified by `IMG`:** - -```sh -make docker-build docker-push IMG=/project-v4-multigroup:tag -``` - -**NOTE:** This image ought to be published in the personal registry you specified. -And it is required to have access to pull the image from the working environment. -Make sure you have the proper permission to the registry if the above commands don’t work. - -**Install the CRDs into the cluster:** - -```sh -make install -``` - -**Deploy the Manager to the cluster with the image specified by `IMG`:** - -```sh -make deploy IMG=/project-v4-multigroup:tag -``` - -> **NOTE**: If you encounter RBAC errors, you may need to grant yourself cluster-admin -privileges or be logged in as admin. - -**Create instances of your solution** -You can apply the samples (examples) from the config/sample: - -```sh -kubectl apply -k config/samples/ -``` - ->**NOTE**: Ensure that the samples has default values to test it out. - -### To Uninstall -**Delete the instances (CRs) from the cluster:** - -```sh -kubectl delete -k config/samples/ -``` - -**Delete the APIs(CRDs) from the cluster:** - -```sh -make uninstall -``` - -**UnDeploy the controller from the cluster:** - -```sh -make undeploy -``` - -## Project Distribution - -Following are the steps to build the installer and distribute this project to users. - -1. Build the installer for the image built and published in the registry: - -```sh -make build-installer IMG=/project-v4-multigroup:tag -``` - -NOTE: The makefile target mentioned above generates an 'install.yaml' -file in the dist directory. This file contains all the resources built -with Kustomize, which are necessary to install this project without -its dependencies. - -2. Using the installer - -Users can just run kubectl apply -f to install the project, i.e.: - -```sh -kubectl apply -f https://raw.githubusercontent.com//project-v4-multigroup//dist/install.yaml -``` - -## Contributing -// TODO(user): Add detailed information on how you would like others to contribute to this project - -**NOTE:** Run `make help` for more information on all potential `make` targets - -More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html) - -## License - -Copyright 2024 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. - diff --git a/testdata/project-v4-multigroup/api/crew/v1/captain_types.go b/testdata/project-v4-multigroup/api/crew/v1/captain_types.go deleted file mode 100644 index 1b45736ca18..00000000000 --- a/testdata/project-v4-multigroup/api/crew/v1/captain_types.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2024 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-v4-multigroup/api/crew/v1/groupversion_info.go b/testdata/project-v4-multigroup/api/crew/v1/groupversion_info.go deleted file mode 100644 index 9c6c30fccf9..00000000000 --- a/testdata/project-v4-multigroup/api/crew/v1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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-v4-multigroup/api/crew/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/crew/v1/zz_generated.deepcopy.go deleted file mode 100644 index 26925504f6f..00000000000 --- a/testdata/project-v4-multigroup/api/crew/v1/zz_generated.deepcopy.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// 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 -} diff --git a/testdata/project-v4-multigroup/api/example.com/v1alpha1/busybox_types.go b/testdata/project-v4-multigroup/api/example.com/v1alpha1/busybox_types.go deleted file mode 100644 index cd1fd6da5d6..00000000000 --- a/testdata/project-v4-multigroup/api/example.com/v1alpha1/busybox_types.go +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 - -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. - -// BusyboxSpec defines the desired state of Busybox -type BusyboxSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // Size defines the number of Busybox instances - // The following markers will use OpenAPI v3 schema to validate the value - // More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - // +kubebuilder:validation:Minimum=1 - // +kubebuilder:validation:Maximum=3 - // +kubebuilder:validation:ExclusiveMaximum=false - Size int32 `json:"size,omitempty"` -} - -// BusyboxStatus defines the observed state of Busybox -type BusyboxStatus struct { - // Represents the observations of a Busybox's current state. - // Busybox.status.conditions.type are: "Available", "Progressing", and "Degraded" - // Busybox.status.conditions.status are one of True, False, Unknown. - // Busybox.status.conditions.reason the value should be a CamelCase string and producers of specific - // condition types may define expected values and meanings for this field, and whether the values - // are considered a guaranteed API. - // Busybox.status.conditions.Message is a human readable message indicating details about the transition. - // For further information see: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties - - Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status - -// Busybox is the Schema for the busyboxes API -type Busybox struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec BusyboxSpec `json:"spec,omitempty"` - Status BusyboxStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// BusyboxList contains a list of Busybox -type BusyboxList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Busybox `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Busybox{}, &BusyboxList{}) -} diff --git a/testdata/project-v4-multigroup/api/example.com/v1alpha1/groupversion_info.go b/testdata/project-v4-multigroup/api/example.com/v1alpha1/groupversion_info.go deleted file mode 100644 index 110a9b573a1..00000000000 --- a/testdata/project-v4-multigroup/api/example.com/v1alpha1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 contains API Schema definitions for the example.com v1alpha1 API group. -// +kubebuilder:object:generate=true -// +groupName=example.com.testproject.org -package v1alpha1 - -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: "example.com.testproject.org", Version: "v1alpha1"} - - // 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-v4-multigroup/api/example.com/v1alpha1/memcached_types.go b/testdata/project-v4-multigroup/api/example.com/v1alpha1/memcached_types.go deleted file mode 100644 index 7c4116e82a5..00000000000 --- a/testdata/project-v4-multigroup/api/example.com/v1alpha1/memcached_types.go +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 - -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. - -// MemcachedSpec defines the desired state of Memcached -type MemcachedSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // Size defines the number of Memcached instances - // The following markers will use OpenAPI v3 schema to validate the value - // More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - // +kubebuilder:validation:Minimum=1 - // +kubebuilder:validation:Maximum=3 - // +kubebuilder:validation:ExclusiveMaximum=false - Size int32 `json:"size,omitempty"` - - // Port defines the port that will be used to init the container with the image - ContainerPort int32 `json:"containerPort,omitempty"` -} - -// MemcachedStatus defines the observed state of Memcached -type MemcachedStatus struct { - // Represents the observations of a Memcached's current state. - // Memcached.status.conditions.type are: "Available", "Progressing", and "Degraded" - // Memcached.status.conditions.status are one of True, False, Unknown. - // Memcached.status.conditions.reason the value should be a CamelCase string and producers of specific - // condition types may define expected values and meanings for this field, and whether the values - // are considered a guaranteed API. - // Memcached.status.conditions.Message is a human readable message indicating details about the transition. - // For further information see: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties - - Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status - -// Memcached is the Schema for the memcacheds API -type Memcached struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec MemcachedSpec `json:"spec,omitempty"` - Status MemcachedStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// MemcachedList contains a list of Memcached -type MemcachedList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Memcached `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Memcached{}, &MemcachedList{}) -} diff --git a/testdata/project-v4-multigroup/api/example.com/v1alpha1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/example.com/v1alpha1/zz_generated.deepcopy.go deleted file mode 100644 index 6254bdb0507..00000000000 --- a/testdata/project-v4-multigroup/api/example.com/v1alpha1/zz_generated.deepcopy.go +++ /dev/null @@ -1,218 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Busybox) DeepCopyInto(out *Busybox) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Busybox. -func (in *Busybox) DeepCopy() *Busybox { - if in == nil { - return nil - } - out := new(Busybox) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Busybox) 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 *BusyboxList) DeepCopyInto(out *BusyboxList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Busybox, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusyboxList. -func (in *BusyboxList) DeepCopy() *BusyboxList { - if in == nil { - return nil - } - out := new(BusyboxList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BusyboxList) 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 *BusyboxSpec) DeepCopyInto(out *BusyboxSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusyboxSpec. -func (in *BusyboxSpec) DeepCopy() *BusyboxSpec { - if in == nil { - return nil - } - out := new(BusyboxSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BusyboxStatus) DeepCopyInto(out *BusyboxStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusyboxStatus. -func (in *BusyboxStatus) DeepCopy() *BusyboxStatus { - if in == nil { - return nil - } - out := new(BusyboxStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Memcached) DeepCopyInto(out *Memcached) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Memcached. -func (in *Memcached) DeepCopy() *Memcached { - if in == nil { - return nil - } - out := new(Memcached) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Memcached) 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 *MemcachedList) DeepCopyInto(out *MemcachedList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Memcached, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemcachedList. -func (in *MemcachedList) DeepCopy() *MemcachedList { - if in == nil { - return nil - } - out := new(MemcachedList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *MemcachedList) 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 *MemcachedSpec) DeepCopyInto(out *MemcachedSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemcachedSpec. -func (in *MemcachedSpec) DeepCopy() *MemcachedSpec { - if in == nil { - return nil - } - out := new(MemcachedSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MemcachedStatus) DeepCopyInto(out *MemcachedStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemcachedStatus. -func (in *MemcachedStatus) DeepCopy() *MemcachedStatus { - if in == nil { - return nil - } - out := new(MemcachedStatus) - in.DeepCopyInto(out) - return out -} diff --git a/testdata/project-v4-multigroup/api/fiz/v1/bar_types.go b/testdata/project-v4-multigroup/api/fiz/v1/bar_types.go deleted file mode 100644 index c3d4884be9e..00000000000 --- a/testdata/project-v4-multigroup/api/fiz/v1/bar_types.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2024 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. - -// BarSpec defines the desired state of Bar. -type BarSpec 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 Bar. Edit bar_types.go to remove/update - Foo string `json:"foo,omitempty"` -} - -// BarStatus defines the observed state of Bar. -type BarStatus 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 - -// Bar is the Schema for the bars API. -type Bar struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec BarSpec `json:"spec,omitempty"` - Status BarStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// BarList contains a list of Bar. -type BarList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Bar `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Bar{}, &BarList{}) -} diff --git a/testdata/project-v4-multigroup/api/fiz/v1/groupversion_info.go b/testdata/project-v4-multigroup/api/fiz/v1/groupversion_info.go deleted file mode 100644 index acb3305b576..00000000000 --- a/testdata/project-v4-multigroup/api/fiz/v1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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 fiz v1 API group. -// +kubebuilder:object:generate=true -// +groupName=fiz.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: "fiz.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-v4-multigroup/api/fiz/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/fiz/v1/zz_generated.deepcopy.go deleted file mode 100644 index b82929d3f21..00000000000 --- a/testdata/project-v4-multigroup/api/fiz/v1/zz_generated.deepcopy.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Bar) DeepCopyInto(out *Bar) { - *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 Bar. -func (in *Bar) DeepCopy() *Bar { - if in == nil { - return nil - } - out := new(Bar) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Bar) 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 *BarList) DeepCopyInto(out *BarList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Bar, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarList. -func (in *BarList) DeepCopy() *BarList { - if in == nil { - return nil - } - out := new(BarList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BarList) 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 *BarSpec) DeepCopyInto(out *BarSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarSpec. -func (in *BarSpec) DeepCopy() *BarSpec { - if in == nil { - return nil - } - out := new(BarSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BarStatus) DeepCopyInto(out *BarStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarStatus. -func (in *BarStatus) DeepCopy() *BarStatus { - if in == nil { - return nil - } - out := new(BarStatus) - in.DeepCopyInto(out) - return out -} diff --git a/testdata/project-v4-multigroup/api/foo.policy/v1/groupversion_info.go b/testdata/project-v4-multigroup/api/foo.policy/v1/groupversion_info.go deleted file mode 100644 index 03b284b34bf..00000000000 --- a/testdata/project-v4-multigroup/api/foo.policy/v1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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 foo.policy v1 API group. -// +kubebuilder:object:generate=true -// +groupName=foo.policy.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: "foo.policy.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-v4-multigroup/api/foo.policy/v1/healthcheckpolicy_types.go b/testdata/project-v4-multigroup/api/foo.policy/v1/healthcheckpolicy_types.go deleted file mode 100644 index 49b587d1499..00000000000 --- a/testdata/project-v4-multigroup/api/foo.policy/v1/healthcheckpolicy_types.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2024 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. - -// HealthCheckPolicySpec defines the desired state of HealthCheckPolicy. -type HealthCheckPolicySpec 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 HealthCheckPolicy. Edit healthcheckpolicy_types.go to remove/update - Foo string `json:"foo,omitempty"` -} - -// HealthCheckPolicyStatus defines the observed state of HealthCheckPolicy. -type HealthCheckPolicyStatus 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 - -// HealthCheckPolicy is the Schema for the healthcheckpolicies API. -type HealthCheckPolicy struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec HealthCheckPolicySpec `json:"spec,omitempty"` - Status HealthCheckPolicyStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// HealthCheckPolicyList contains a list of HealthCheckPolicy. -type HealthCheckPolicyList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []HealthCheckPolicy `json:"items"` -} - -func init() { - SchemeBuilder.Register(&HealthCheckPolicy{}, &HealthCheckPolicyList{}) -} diff --git a/testdata/project-v4-multigroup/api/foo.policy/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/foo.policy/v1/zz_generated.deepcopy.go deleted file mode 100644 index d0cfbe15c38..00000000000 --- a/testdata/project-v4-multigroup/api/foo.policy/v1/zz_generated.deepcopy.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HealthCheckPolicy) DeepCopyInto(out *HealthCheckPolicy) { - *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 HealthCheckPolicy. -func (in *HealthCheckPolicy) DeepCopy() *HealthCheckPolicy { - if in == nil { - return nil - } - out := new(HealthCheckPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HealthCheckPolicy) 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 *HealthCheckPolicyList) DeepCopyInto(out *HealthCheckPolicyList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]HealthCheckPolicy, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheckPolicyList. -func (in *HealthCheckPolicyList) DeepCopy() *HealthCheckPolicyList { - if in == nil { - return nil - } - out := new(HealthCheckPolicyList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HealthCheckPolicyList) 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 *HealthCheckPolicySpec) DeepCopyInto(out *HealthCheckPolicySpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheckPolicySpec. -func (in *HealthCheckPolicySpec) DeepCopy() *HealthCheckPolicySpec { - if in == nil { - return nil - } - out := new(HealthCheckPolicySpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HealthCheckPolicyStatus) DeepCopyInto(out *HealthCheckPolicyStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheckPolicyStatus. -func (in *HealthCheckPolicyStatus) DeepCopy() *HealthCheckPolicyStatus { - if in == nil { - return nil - } - out := new(HealthCheckPolicyStatus) - in.DeepCopyInto(out) - return out -} diff --git a/testdata/project-v4-multigroup/api/foo/v1/bar_types.go b/testdata/project-v4-multigroup/api/foo/v1/bar_types.go deleted file mode 100644 index c3d4884be9e..00000000000 --- a/testdata/project-v4-multigroup/api/foo/v1/bar_types.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2024 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. - -// BarSpec defines the desired state of Bar. -type BarSpec 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 Bar. Edit bar_types.go to remove/update - Foo string `json:"foo,omitempty"` -} - -// BarStatus defines the observed state of Bar. -type BarStatus 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 - -// Bar is the Schema for the bars API. -type Bar struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec BarSpec `json:"spec,omitempty"` - Status BarStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// BarList contains a list of Bar. -type BarList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Bar `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Bar{}, &BarList{}) -} diff --git a/testdata/project-v4-multigroup/api/foo/v1/groupversion_info.go b/testdata/project-v4-multigroup/api/foo/v1/groupversion_info.go deleted file mode 100644 index f90e36f69ec..00000000000 --- a/testdata/project-v4-multigroup/api/foo/v1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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 foo v1 API group. -// +kubebuilder:object:generate=true -// +groupName=foo.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: "foo.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-v4-multigroup/api/foo/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/foo/v1/zz_generated.deepcopy.go deleted file mode 100644 index b82929d3f21..00000000000 --- a/testdata/project-v4-multigroup/api/foo/v1/zz_generated.deepcopy.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Bar) DeepCopyInto(out *Bar) { - *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 Bar. -func (in *Bar) DeepCopy() *Bar { - if in == nil { - return nil - } - out := new(Bar) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Bar) 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 *BarList) DeepCopyInto(out *BarList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Bar, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarList. -func (in *BarList) DeepCopy() *BarList { - if in == nil { - return nil - } - out := new(BarList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BarList) 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 *BarSpec) DeepCopyInto(out *BarSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarSpec. -func (in *BarSpec) DeepCopy() *BarSpec { - if in == nil { - return nil - } - out := new(BarSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BarStatus) DeepCopyInto(out *BarStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarStatus. -func (in *BarStatus) DeepCopy() *BarStatus { - if in == nil { - return nil - } - out := new(BarStatus) - in.DeepCopyInto(out) - return out -} diff --git a/testdata/project-v4-multigroup/api/sea-creatures/v1beta1/groupversion_info.go b/testdata/project-v4-multigroup/api/sea-creatures/v1beta1/groupversion_info.go deleted file mode 100644 index 89449b7966a..00000000000 --- a/testdata/project-v4-multigroup/api/sea-creatures/v1beta1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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 v1beta1 contains API Schema definitions for the sea-creatures v1beta1 API group. -// +kubebuilder:object:generate=true -// +groupName=sea-creatures.testproject.org -package v1beta1 - -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: "sea-creatures.testproject.org", Version: "v1beta1"} - - // 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-v4-multigroup/api/sea-creatures/v1beta1/kraken_types.go b/testdata/project-v4-multigroup/api/sea-creatures/v1beta1/kraken_types.go deleted file mode 100644 index 3682748a3c3..00000000000 --- a/testdata/project-v4-multigroup/api/sea-creatures/v1beta1/kraken_types.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2024 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 v1beta1 - -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. - -// KrakenSpec defines the desired state of Kraken. -type KrakenSpec 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 Kraken. Edit kraken_types.go to remove/update - Foo string `json:"foo,omitempty"` -} - -// KrakenStatus defines the observed state of Kraken. -type KrakenStatus 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 - -// Kraken is the Schema for the krakens API. -type Kraken struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec KrakenSpec `json:"spec,omitempty"` - Status KrakenStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// KrakenList contains a list of Kraken. -type KrakenList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Kraken `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Kraken{}, &KrakenList{}) -} diff --git a/testdata/project-v4-multigroup/api/sea-creatures/v1beta1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/sea-creatures/v1beta1/zz_generated.deepcopy.go deleted file mode 100644 index 25f64b3d2b5..00000000000 --- a/testdata/project-v4-multigroup/api/sea-creatures/v1beta1/zz_generated.deepcopy.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 v1beta1 - -import ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Kraken) DeepCopyInto(out *Kraken) { - *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 Kraken. -func (in *Kraken) DeepCopy() *Kraken { - if in == nil { - return nil - } - out := new(Kraken) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Kraken) 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 *KrakenList) DeepCopyInto(out *KrakenList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Kraken, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KrakenList. -func (in *KrakenList) DeepCopy() *KrakenList { - if in == nil { - return nil - } - out := new(KrakenList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *KrakenList) 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 *KrakenSpec) DeepCopyInto(out *KrakenSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KrakenSpec. -func (in *KrakenSpec) DeepCopy() *KrakenSpec { - if in == nil { - return nil - } - out := new(KrakenSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KrakenStatus) DeepCopyInto(out *KrakenStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KrakenStatus. -func (in *KrakenStatus) DeepCopy() *KrakenStatus { - if in == nil { - return nil - } - out := new(KrakenStatus) - in.DeepCopyInto(out) - return out -} diff --git a/testdata/project-v4-multigroup/api/sea-creatures/v1beta2/groupversion_info.go b/testdata/project-v4-multigroup/api/sea-creatures/v1beta2/groupversion_info.go deleted file mode 100644 index eaee6464829..00000000000 --- a/testdata/project-v4-multigroup/api/sea-creatures/v1beta2/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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 v1beta2 contains API Schema definitions for the sea-creatures v1beta2 API group. -// +kubebuilder:object:generate=true -// +groupName=sea-creatures.testproject.org -package v1beta2 - -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: "sea-creatures.testproject.org", Version: "v1beta2"} - - // 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-v4-multigroup/api/sea-creatures/v1beta2/leviathan_types.go b/testdata/project-v4-multigroup/api/sea-creatures/v1beta2/leviathan_types.go deleted file mode 100644 index 4726c79b1b1..00000000000 --- a/testdata/project-v4-multigroup/api/sea-creatures/v1beta2/leviathan_types.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2024 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 v1beta2 - -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. - -// LeviathanSpec defines the desired state of Leviathan. -type LeviathanSpec 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 Leviathan. Edit leviathan_types.go to remove/update - Foo string `json:"foo,omitempty"` -} - -// LeviathanStatus defines the observed state of Leviathan. -type LeviathanStatus 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 - -// Leviathan is the Schema for the leviathans API. -type Leviathan struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec LeviathanSpec `json:"spec,omitempty"` - Status LeviathanStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// LeviathanList contains a list of Leviathan. -type LeviathanList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Leviathan `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Leviathan{}, &LeviathanList{}) -} diff --git a/testdata/project-v4-multigroup/api/sea-creatures/v1beta2/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/sea-creatures/v1beta2/zz_generated.deepcopy.go deleted file mode 100644 index e9934a77f85..00000000000 --- a/testdata/project-v4-multigroup/api/sea-creatures/v1beta2/zz_generated.deepcopy.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 v1beta2 - -import ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Leviathan) DeepCopyInto(out *Leviathan) { - *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 Leviathan. -func (in *Leviathan) DeepCopy() *Leviathan { - if in == nil { - return nil - } - out := new(Leviathan) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Leviathan) 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 *LeviathanList) DeepCopyInto(out *LeviathanList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Leviathan, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeviathanList. -func (in *LeviathanList) DeepCopy() *LeviathanList { - if in == nil { - return nil - } - out := new(LeviathanList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *LeviathanList) 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 *LeviathanSpec) DeepCopyInto(out *LeviathanSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeviathanSpec. -func (in *LeviathanSpec) DeepCopy() *LeviathanSpec { - if in == nil { - return nil - } - out := new(LeviathanSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LeviathanStatus) DeepCopyInto(out *LeviathanStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeviathanStatus. -func (in *LeviathanStatus) DeepCopy() *LeviathanStatus { - if in == nil { - return nil - } - out := new(LeviathanStatus) - in.DeepCopyInto(out) - return out -} diff --git a/testdata/project-v4-multigroup/api/ship/v1/destroyer_types.go b/testdata/project-v4-multigroup/api/ship/v1/destroyer_types.go deleted file mode 100644 index 11c5768f0ac..00000000000 --- a/testdata/project-v4-multigroup/api/ship/v1/destroyer_types.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2024 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. - -// DestroyerSpec defines the desired state of Destroyer. -type DestroyerSpec 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 Destroyer. Edit destroyer_types.go to remove/update - Foo string `json:"foo,omitempty"` -} - -// DestroyerStatus defines the observed state of Destroyer. -type DestroyerStatus 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 - -// Destroyer is the Schema for the destroyers API. -type Destroyer struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec DestroyerSpec `json:"spec,omitempty"` - Status DestroyerStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// DestroyerList contains a list of Destroyer. -type DestroyerList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Destroyer `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Destroyer{}, &DestroyerList{}) -} diff --git a/testdata/project-v4-multigroup/api/ship/v1/groupversion_info.go b/testdata/project-v4-multigroup/api/ship/v1/groupversion_info.go deleted file mode 100644 index 7ede1ddfa92..00000000000 --- a/testdata/project-v4-multigroup/api/ship/v1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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 ship v1 API group. -// +kubebuilder:object:generate=true -// +groupName=ship.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: "ship.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-v4-multigroup/api/ship/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/ship/v1/zz_generated.deepcopy.go deleted file mode 100644 index 8931c51a317..00000000000 --- a/testdata/project-v4-multigroup/api/ship/v1/zz_generated.deepcopy.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Destroyer) DeepCopyInto(out *Destroyer) { - *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 Destroyer. -func (in *Destroyer) DeepCopy() *Destroyer { - if in == nil { - return nil - } - out := new(Destroyer) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Destroyer) 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 *DestroyerList) DeepCopyInto(out *DestroyerList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Destroyer, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestroyerList. -func (in *DestroyerList) DeepCopy() *DestroyerList { - if in == nil { - return nil - } - out := new(DestroyerList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DestroyerList) 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 *DestroyerSpec) DeepCopyInto(out *DestroyerSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestroyerSpec. -func (in *DestroyerSpec) DeepCopy() *DestroyerSpec { - if in == nil { - return nil - } - out := new(DestroyerSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DestroyerStatus) DeepCopyInto(out *DestroyerStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestroyerStatus. -func (in *DestroyerStatus) DeepCopy() *DestroyerStatus { - if in == nil { - return nil - } - out := new(DestroyerStatus) - in.DeepCopyInto(out) - return out -} diff --git a/testdata/project-v4-multigroup/api/ship/v1beta1/frigate_types.go b/testdata/project-v4-multigroup/api/ship/v1beta1/frigate_types.go deleted file mode 100644 index 7cfb6b61593..00000000000 --- a/testdata/project-v4-multigroup/api/ship/v1beta1/frigate_types.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2024 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 v1beta1 - -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. - -// FrigateSpec defines the desired state of Frigate. -type FrigateSpec 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 Frigate. Edit frigate_types.go to remove/update - Foo string `json:"foo,omitempty"` -} - -// FrigateStatus defines the observed state of Frigate. -type FrigateStatus 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 - -// Frigate is the Schema for the frigates API. -type Frigate struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec FrigateSpec `json:"spec,omitempty"` - Status FrigateStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// FrigateList contains a list of Frigate. -type FrigateList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Frigate `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Frigate{}, &FrigateList{}) -} diff --git a/testdata/project-v4-multigroup/api/ship/v1beta1/groupversion_info.go b/testdata/project-v4-multigroup/api/ship/v1beta1/groupversion_info.go deleted file mode 100644 index f226e342def..00000000000 --- a/testdata/project-v4-multigroup/api/ship/v1beta1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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 v1beta1 contains API Schema definitions for the ship v1beta1 API group. -// +kubebuilder:object:generate=true -// +groupName=ship.testproject.org -package v1beta1 - -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: "ship.testproject.org", Version: "v1beta1"} - - // 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-v4-multigroup/api/ship/v1beta1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/ship/v1beta1/zz_generated.deepcopy.go deleted file mode 100644 index bfcdcf442ae..00000000000 --- a/testdata/project-v4-multigroup/api/ship/v1beta1/zz_generated.deepcopy.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 v1beta1 - -import ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Frigate) DeepCopyInto(out *Frigate) { - *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 Frigate. -func (in *Frigate) DeepCopy() *Frigate { - if in == nil { - return nil - } - out := new(Frigate) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Frigate) 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 *FrigateList) DeepCopyInto(out *FrigateList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Frigate, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FrigateList. -func (in *FrigateList) DeepCopy() *FrigateList { - if in == nil { - return nil - } - out := new(FrigateList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *FrigateList) 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 *FrigateSpec) DeepCopyInto(out *FrigateSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FrigateSpec. -func (in *FrigateSpec) DeepCopy() *FrigateSpec { - if in == nil { - return nil - } - out := new(FrigateSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FrigateStatus) DeepCopyInto(out *FrigateStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FrigateStatus. -func (in *FrigateStatus) DeepCopy() *FrigateStatus { - if in == nil { - return nil - } - out := new(FrigateStatus) - in.DeepCopyInto(out) - return out -} diff --git a/testdata/project-v4-multigroup/api/ship/v2alpha1/cruiser_types.go b/testdata/project-v4-multigroup/api/ship/v2alpha1/cruiser_types.go deleted file mode 100644 index 938e1343c1b..00000000000 --- a/testdata/project-v4-multigroup/api/ship/v2alpha1/cruiser_types.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2024 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 v2alpha1 - -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. - -// CruiserSpec defines the desired state of Cruiser. -type CruiserSpec 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 Cruiser. Edit cruiser_types.go to remove/update - Foo string `json:"foo,omitempty"` -} - -// CruiserStatus defines the observed state of Cruiser. -type CruiserStatus 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 - -// Cruiser is the Schema for the cruisers API. -type Cruiser struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec CruiserSpec `json:"spec,omitempty"` - Status CruiserStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// CruiserList contains a list of Cruiser. -type CruiserList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Cruiser `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Cruiser{}, &CruiserList{}) -} diff --git a/testdata/project-v4-multigroup/api/ship/v2alpha1/groupversion_info.go b/testdata/project-v4-multigroup/api/ship/v2alpha1/groupversion_info.go deleted file mode 100644 index 29c5dd6871a..00000000000 --- a/testdata/project-v4-multigroup/api/ship/v2alpha1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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 v2alpha1 contains API Schema definitions for the ship v2alpha1 API group. -// +kubebuilder:object:generate=true -// +groupName=ship.testproject.org -package v2alpha1 - -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: "ship.testproject.org", Version: "v2alpha1"} - - // 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-v4-multigroup/api/ship/v2alpha1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/ship/v2alpha1/zz_generated.deepcopy.go deleted file mode 100644 index 01af43ca4fe..00000000000 --- a/testdata/project-v4-multigroup/api/ship/v2alpha1/zz_generated.deepcopy.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 v2alpha1 - -import ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Cruiser) DeepCopyInto(out *Cruiser) { - *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 Cruiser. -func (in *Cruiser) DeepCopy() *Cruiser { - if in == nil { - return nil - } - out := new(Cruiser) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Cruiser) 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 *CruiserList) DeepCopyInto(out *CruiserList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Cruiser, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CruiserList. -func (in *CruiserList) DeepCopy() *CruiserList { - if in == nil { - return nil - } - out := new(CruiserList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *CruiserList) 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 *CruiserSpec) DeepCopyInto(out *CruiserSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CruiserSpec. -func (in *CruiserSpec) DeepCopy() *CruiserSpec { - if in == nil { - return nil - } - out := new(CruiserSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CruiserStatus) DeepCopyInto(out *CruiserStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CruiserStatus. -func (in *CruiserStatus) DeepCopy() *CruiserStatus { - if in == nil { - return nil - } - out := new(CruiserStatus) - in.DeepCopyInto(out) - return out -} diff --git a/testdata/project-v4-multigroup/cmd/main.go b/testdata/project-v4-multigroup/cmd/main.go deleted file mode 100644 index 80ee1732165..00000000000 --- a/testdata/project-v4-multigroup/cmd/main.go +++ /dev/null @@ -1,341 +0,0 @@ -/* -Copyright 2024 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 ( - "crypto/tls" - "flag" - "os" - - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - // to ensure that exec-entrypoint and run can make use of them. - _ "k8s.io/client-go/plugin/pkg/client/auth" - - "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/metrics/filters" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" - - certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/crew/v1" - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" - fizv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/fiz/v1" - foopolicyv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo.policy/v1" - foov1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo/v1" - seacreaturesv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta1" - seacreaturesv1beta2 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta2" - shipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1" - shipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1beta1" - shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v2alpha1" - appscontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/apps" - certmanagercontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/cert-manager" - crewcontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/crew" - examplecomcontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/example.com" - fizcontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/fiz" - foocontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/foo" - foopolicycontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/foo.policy" - seacreaturescontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/sea-creatures" - shipcontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/ship" - webhookcertmanagerv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/webhook/cert-manager/v1" - webhookcorev1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/webhook/core/v1" - webhookcrewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/webhook/crew/v1" - webhookexamplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/webhook/example.com/v1alpha1" - webhookshipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/webhook/ship/v1" - webhookshipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/webhook/ship/v1beta1" - webhookshipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/webhook/ship/v2alpha1" - // +kubebuilder:scaffold:imports -) - -var ( - scheme = runtime.NewScheme() - setupLog = ctrl.Log.WithName("setup") -) - -func init() { - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - - utilruntime.Must(crewv1.AddToScheme(scheme)) - utilruntime.Must(shipv1beta1.AddToScheme(scheme)) - utilruntime.Must(shipv1.AddToScheme(scheme)) - utilruntime.Must(shipv2alpha1.AddToScheme(scheme)) - utilruntime.Must(seacreaturesv1beta1.AddToScheme(scheme)) - utilruntime.Must(seacreaturesv1beta2.AddToScheme(scheme)) - utilruntime.Must(foopolicyv1.AddToScheme(scheme)) - utilruntime.Must(foov1.AddToScheme(scheme)) - utilruntime.Must(fizv1.AddToScheme(scheme)) - utilruntime.Must(certmanagerv1.AddToScheme(scheme)) - utilruntime.Must(examplecomv1alpha1.AddToScheme(scheme)) - // +kubebuilder:scaffold:scheme -} - -func main() { - var metricsAddr string - var enableLeaderElection bool - var probeAddr string - var secureMetrics bool - var enableHTTP2 bool - var tlsOpts []func(*tls.Config) - flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+ - "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.") - flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") - flag.BoolVar(&enableLeaderElection, "leader-elect", false, - "Enable leader election for controller manager. "+ - "Enabling this will ensure there is only one active controller manager.") - flag.BoolVar(&secureMetrics, "metrics-secure", true, - "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.") - flag.BoolVar(&enableHTTP2, "enable-http2", false, - "If set, HTTP/2 will be enabled for the metrics and webhook servers") - opts := zap.Options{ - Development: true, - } - opts.BindFlags(flag.CommandLine) - flag.Parse() - - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - - // if the enable-http2 flag is false (the default), http/2 should be disabled - // due to its vulnerabilities. More specifically, disabling http/2 will - // prevent from being vulnerable to the HTTP/2 Stream Cancellation and - // Rapid Reset CVEs. For more information see: - // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3 - // - https://github.com/advisories/GHSA-4374-p667-p6c8 - disableHTTP2 := func(c *tls.Config) { - setupLog.Info("disabling http/2") - c.NextProtos = []string{"http/1.1"} - } - - if !enableHTTP2 { - tlsOpts = append(tlsOpts, disableHTTP2) - } - - webhookServer := webhook.NewServer(webhook.Options{ - TLSOpts: tlsOpts, - }) - - // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server. - // More info: - // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/metrics/server - // - https://book.kubebuilder.io/reference/metrics.html - metricsServerOptions := metricsserver.Options{ - BindAddress: metricsAddr, - SecureServing: secureMetrics, - // TODO(user): TLSOpts is used to allow configuring the TLS config used for the server. If certificates are - // not provided, self-signed certificates will be generated by default. This option is not recommended for - // production environments as self-signed certificates do not offer the same level of trust and security - // as certificates issued by a trusted Certificate Authority (CA). The primary risk is potentially allowing - // unauthorized access to sensitive metrics data. Consider replacing with CertDir, CertName, and KeyName - // to provide certificates, ensuring the server communicates using trusted and secure certificates. - TLSOpts: tlsOpts, - } - - if secureMetrics { - // FilterProvider is used to protect the metrics endpoint with authn/authz. - // These configurations ensure that only authorized users and service accounts - // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info: - // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/metrics/filters#WithAuthenticationAndAuthorization - metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization - } - - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: scheme, - Metrics: metricsServerOptions, - WebhookServer: webhookServer, - HealthProbeBindAddress: probeAddr, - LeaderElection: enableLeaderElection, - LeaderElectionID: "3e9f67a9.testproject.org", - // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily - // when the Manager ends. This requires the binary to immediately end when the - // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly - // speeds up voluntary leader transitions as the new leader don't have to wait - // LeaseDuration time first. - // - // In the default scaffold provided, the program ends immediately after - // the manager stops, so would be fine to enable this option. However, - // if you are doing or is intended to do any operation such as perform cleanups - // after the manager stops then its usage might be unsafe. - // LeaderElectionReleaseOnCancel: true, - }) - if err != nil { - setupLog.Error(err, "unable to start manager") - os.Exit(1) - } - - if err = (&crewcontroller.CaptainReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Captain") - os.Exit(1) - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookcrewv1.SetupCaptainWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Captain") - os.Exit(1) - } - } - if err = (&shipcontroller.FrigateReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Frigate") - os.Exit(1) - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookshipv1beta1.SetupFrigateWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Frigate") - os.Exit(1) - } - } - if err = (&shipcontroller.DestroyerReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Destroyer") - os.Exit(1) - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookshipv1.SetupDestroyerWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Destroyer") - os.Exit(1) - } - } - if err = (&shipcontroller.CruiserReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Cruiser") - os.Exit(1) - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookshipv2alpha1.SetupCruiserWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Cruiser") - os.Exit(1) - } - } - if err = (&seacreaturescontroller.KrakenReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Kraken") - os.Exit(1) - } - if err = (&seacreaturescontroller.LeviathanReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Leviathan") - os.Exit(1) - } - if err = (&foopolicycontroller.HealthCheckPolicyReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "HealthCheckPolicy") - os.Exit(1) - } - if err = (&appscontroller.DeploymentReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Deployment") - os.Exit(1) - } - if err = (&foocontroller.BarReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Bar") - os.Exit(1) - } - if err = (&fizcontroller.BarReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Bar") - os.Exit(1) - } - if err = (&certmanagercontroller.CertificateReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Certificate") - os.Exit(1) - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookcertmanagerv1.SetupIssuerWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Issuer") - os.Exit(1) - } - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookcorev1.SetupPodWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Pod") - os.Exit(1) - } - } - if err = (&examplecomcontroller.MemcachedReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Recorder: mgr.GetEventRecorderFor("memcached-controller"), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Memcached") - os.Exit(1) - } - if err = (&examplecomcontroller.BusyboxReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Recorder: mgr.GetEventRecorderFor("busybox-controller"), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Busybox") - os.Exit(1) - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookexamplecomv1alpha1.SetupMemcachedWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Memcached") - os.Exit(1) - } - } - // +kubebuilder:scaffold:builder - - if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up health check") - os.Exit(1) - } - if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up ready check") - os.Exit(1) - } - - setupLog.Info("starting manager") - if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { - setupLog.Error(err, "problem running manager") - os.Exit(1) - } -} diff --git a/testdata/project-v4-multigroup/config/certmanager/certificate.yaml b/testdata/project-v4-multigroup/config/certmanager/certificate.yaml deleted file mode 100644 index d6bd556f1b4..00000000000 --- a/testdata/project-v4-multigroup/config/certmanager/certificate.yaml +++ /dev/null @@ -1,35 +0,0 @@ -# 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: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: selfsigned-issuer - namespace: system -spec: - selfSigned: {} ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - labels: - app.kubernetes.io/name: certificate - app.kubernetes.io/instance: serving-cert - app.kubernetes.io/component: certificate - app.kubernetes.io/created-by: project-v4-multigroup - app.kubernetes.io/part-of: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - 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-v4-multigroup/config/certmanager/kustomization.yaml b/testdata/project-v4-multigroup/config/certmanager/kustomization.yaml deleted file mode 100644 index bebea5a595e..00000000000 --- a/testdata/project-v4-multigroup/config/certmanager/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -resources: -- certificate.yaml - -configurations: -- kustomizeconfig.yaml diff --git a/testdata/project-v4-multigroup/config/certmanager/kustomizeconfig.yaml b/testdata/project-v4-multigroup/config/certmanager/kustomizeconfig.yaml deleted file mode 100644 index cf6f89e8892..00000000000 --- a/testdata/project-v4-multigroup/config/certmanager/kustomizeconfig.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# This configuration is for teaching kustomize how to update name ref substitution -nameReference: -- kind: Issuer - group: cert-manager.io - fieldSpecs: - - kind: Certificate - group: cert-manager.io - path: spec/issuerRef/name diff --git a/testdata/project-v4-multigroup/config/crd/bases/crew.testproject.org_captains.yaml b/testdata/project-v4-multigroup/config/crd/bases/crew.testproject.org_captains.yaml deleted file mode 100644 index b9a8b5d4da8..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/crew.testproject.org_captains.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - 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: {} diff --git a/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_busyboxes.yaml b/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_busyboxes.yaml deleted file mode 100644 index 9f02a3d2fa0..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_busyboxes.yaml +++ /dev/null @@ -1,116 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: busyboxes.example.com.testproject.org -spec: - group: example.com.testproject.org - names: - kind: Busybox - listKind: BusyboxList - plural: busyboxes - singular: busybox - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Busybox is the Schema for the busyboxes 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: BusyboxSpec defines the desired state of Busybox - properties: - size: - description: |- - Size defines the number of Busybox instances - The following markers will use OpenAPI v3 schema to validate the value - More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - format: int32 - maximum: 3 - minimum: 1 - type: integer - type: object - status: - description: BusyboxStatus defines the observed state of Busybox - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_memcacheds.yaml b/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_memcacheds.yaml deleted file mode 100644 index db5bd44e21d..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_memcacheds.yaml +++ /dev/null @@ -1,121 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: memcacheds.example.com.testproject.org -spec: - group: example.com.testproject.org - names: - kind: Memcached - listKind: MemcachedList - plural: memcacheds - singular: memcached - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Memcached is the Schema for the memcacheds 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: MemcachedSpec defines the desired state of Memcached - properties: - containerPort: - description: Port defines the port that will be used to init the container - with the image - format: int32 - type: integer - size: - description: |- - Size defines the number of Memcached instances - The following markers will use OpenAPI v3 schema to validate the value - More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - format: int32 - maximum: 3 - minimum: 1 - type: integer - type: object - status: - description: MemcachedStatus defines the observed state of Memcached - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/bases/fiz.testproject.org_bars.yaml b/testdata/project-v4-multigroup/config/crd/bases/fiz.testproject.org_bars.yaml deleted file mode 100644 index e874970aa45..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/fiz.testproject.org_bars.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: bars.fiz.testproject.org -spec: - group: fiz.testproject.org - names: - kind: Bar - listKind: BarList - plural: bars - singular: bar - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Bar is the Schema for the bars 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: BarSpec defines the desired state of Bar. - properties: - foo: - description: Foo is an example field of Bar. Edit bar_types.go to - remove/update - type: string - type: object - status: - description: BarStatus defines the observed state of Bar. - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/bases/foo.policy.testproject.org_healthcheckpolicies.yaml b/testdata/project-v4-multigroup/config/crd/bases/foo.policy.testproject.org_healthcheckpolicies.yaml deleted file mode 100644 index 11db7a2502d..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/foo.policy.testproject.org_healthcheckpolicies.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: healthcheckpolicies.foo.policy.testproject.org -spec: - group: foo.policy.testproject.org - names: - kind: HealthCheckPolicy - listKind: HealthCheckPolicyList - plural: healthcheckpolicies - singular: healthcheckpolicy - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: HealthCheckPolicy is the Schema for the healthcheckpolicies 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: HealthCheckPolicySpec defines the desired state of HealthCheckPolicy. - properties: - foo: - description: Foo is an example field of HealthCheckPolicy. Edit healthcheckpolicy_types.go - to remove/update - type: string - type: object - status: - description: HealthCheckPolicyStatus defines the observed state of HealthCheckPolicy. - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/bases/foo.testproject.org_bars.yaml b/testdata/project-v4-multigroup/config/crd/bases/foo.testproject.org_bars.yaml deleted file mode 100644 index 59a50ef2dee..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/foo.testproject.org_bars.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: bars.foo.testproject.org -spec: - group: foo.testproject.org - names: - kind: Bar - listKind: BarList - plural: bars - singular: bar - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Bar is the Schema for the bars 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: BarSpec defines the desired state of Bar. - properties: - foo: - description: Foo is an example field of Bar. Edit bar_types.go to - remove/update - type: string - type: object - status: - description: BarStatus defines the observed state of Bar. - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_krakens.yaml b/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_krakens.yaml deleted file mode 100644 index f4aef68ea7d..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_krakens.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: krakens.sea-creatures.testproject.org -spec: - group: sea-creatures.testproject.org - names: - kind: Kraken - listKind: KrakenList - plural: krakens - singular: kraken - scope: Namespaced - versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: Kraken is the Schema for the krakens 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: KrakenSpec defines the desired state of Kraken. - properties: - foo: - description: Foo is an example field of Kraken. Edit kraken_types.go - to remove/update - type: string - type: object - status: - description: KrakenStatus defines the observed state of Kraken. - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_leviathans.yaml b/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_leviathans.yaml deleted file mode 100644 index 9c09eae6ffa..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_leviathans.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: leviathans.sea-creatures.testproject.org -spec: - group: sea-creatures.testproject.org - names: - kind: Leviathan - listKind: LeviathanList - plural: leviathans - singular: leviathan - scope: Namespaced - versions: - - name: v1beta2 - schema: - openAPIV3Schema: - description: Leviathan is the Schema for the leviathans 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: LeviathanSpec defines the desired state of Leviathan. - properties: - foo: - description: Foo is an example field of Leviathan. Edit leviathan_types.go - to remove/update - type: string - type: object - status: - description: LeviathanStatus defines the observed state of Leviathan. - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_cruisers.yaml b/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_cruisers.yaml deleted file mode 100644 index 0ddbb235280..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_cruisers.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: cruisers.ship.testproject.org -spec: - group: ship.testproject.org - names: - kind: Cruiser - listKind: CruiserList - plural: cruisers - singular: cruiser - scope: Cluster - versions: - - name: v2alpha1 - schema: - openAPIV3Schema: - description: Cruiser is the Schema for the cruisers 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: CruiserSpec defines the desired state of Cruiser. - properties: - foo: - description: Foo is an example field of Cruiser. Edit cruiser_types.go - to remove/update - type: string - type: object - status: - description: CruiserStatus defines the observed state of Cruiser. - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_destroyers.yaml b/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_destroyers.yaml deleted file mode 100644 index 9ae5a0d368a..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_destroyers.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: destroyers.ship.testproject.org -spec: - group: ship.testproject.org - names: - kind: Destroyer - listKind: DestroyerList - plural: destroyers - singular: destroyer - scope: Cluster - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Destroyer is the Schema for the destroyers 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: DestroyerSpec defines the desired state of Destroyer. - properties: - foo: - description: Foo is an example field of Destroyer. Edit destroyer_types.go - to remove/update - type: string - type: object - status: - description: DestroyerStatus defines the observed state of Destroyer. - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_frigates.yaml b/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_frigates.yaml deleted file mode 100644 index 74489e2ec77..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_frigates.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: frigates.ship.testproject.org -spec: - group: ship.testproject.org - names: - kind: Frigate - listKind: FrigateList - plural: frigates - singular: frigate - scope: Namespaced - versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: Frigate is the Schema for the frigates 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: FrigateSpec defines the desired state of Frigate. - properties: - foo: - description: Foo is an example field of Frigate. Edit frigate_types.go - to remove/update - type: string - type: object - status: - description: FrigateStatus defines the observed state of Frigate. - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/kustomization.yaml b/testdata/project-v4-multigroup/config/crd/kustomization.yaml deleted file mode 100644 index 6b362727dd7..00000000000 --- a/testdata/project-v4-multigroup/config/crd/kustomization.yaml +++ /dev/null @@ -1,47 +0,0 @@ -# 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/ship.testproject.org_frigates.yaml -- bases/ship.testproject.org_destroyers.yaml -- bases/ship.testproject.org_cruisers.yaml -- bases/sea-creatures.testproject.org_krakens.yaml -- bases/sea-creatures.testproject.org_leviathans.yaml -- bases/foo.policy.testproject.org_healthcheckpolicies.yaml -- bases/foo.testproject.org_bars.yaml -- bases/fiz.testproject.org_bars.yaml -- bases/example.com.testproject.org_memcacheds.yaml -- bases/example.com.testproject.org_busyboxes.yaml -# +kubebuilder:scaffold:crdkustomizeresource - -patches: -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. -# patches here are for enabling the conversion webhook for each CRD -- path: patches/webhook_in_crew_captains.yaml -- path: patches/webhook_in_ship_frigates.yaml -- path: patches/webhook_in_ship_destroyers.yaml -- path: patches/webhook_in_ship_cruisers.yaml -- path: patches/webhook_in_example.com_memcacheds.yaml -# +kubebuilder:scaffold:crdkustomizewebhookpatch - -# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. -# patches here are for enabling the CA injection for each CRD -#- path: patches/cainjection_in_crew_captains.yaml -#- path: patches/cainjection_in_ship_frigates.yaml -#- path: patches/cainjection_in_ship_destroyers.yaml -#- path: patches/cainjection_in_ship_cruisers.yaml -#- path: patches/cainjection_in_sea-creatures_krakens.yaml -#- path: patches/cainjection_in_sea-creatures_leviathans.yaml -#- path: patches/cainjection_in_foo.policy_healthcheckpolicies.yaml -#- path: patches/cainjection_in_foo_bars.yaml -#- path: patches/cainjection_in_fiz_bars.yaml -#- path: patches/cainjection_in_example.com_memcacheds.yaml -#- path: patches/cainjection_in_example.com_busyboxes.yaml -# +kubebuilder:scaffold:crdkustomizecainjectionpatch - -# [WEBHOOK] To enable webhook, uncomment the following section -# the following config is for teaching kustomize how to do kustomization for CRDs. - -configurations: -- kustomizeconfig.yaml diff --git a/testdata/project-v4-multigroup/config/crd/kustomizeconfig.yaml b/testdata/project-v4-multigroup/config/crd/kustomizeconfig.yaml deleted file mode 100644 index ec5c150a9df..00000000000 --- a/testdata/project-v4-multigroup/config/crd/kustomizeconfig.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# 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-v4-multigroup/config/crd/patches/cainjection_in_cert-manager_issuers.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_cert-manager_issuers.yaml deleted file mode 100644 index c23d48081df..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_cert-manager_issuers.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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: issuers.cert-manager.io diff --git a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_core_pods.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_core_pods.yaml deleted file mode 100644 index b1ab830f8f6..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_core_pods.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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: pods.core diff --git a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_crew_captains.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_crew_captains.yaml deleted file mode 100644 index fba0c3ed6fd..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_crew_captains.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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-v4-multigroup/config/crd/patches/cainjection_in_example.com_memcacheds.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_example.com_memcacheds.yaml deleted file mode 100644 index 5b9e839364d..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_example.com_memcacheds.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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: memcacheds.example.com.testproject.org diff --git a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_cruisers.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_cruisers.yaml deleted file mode 100644 index 0d31cb0b8af..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_cruisers.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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: cruisers.ship.testproject.org diff --git a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_destroyers.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_destroyers.yaml deleted file mode 100644 index 865395574ff..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_destroyers.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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: destroyers.ship.testproject.org diff --git a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_frigates.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_frigates.yaml deleted file mode 100644 index d4acb9d24c1..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_frigates.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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: frigates.ship.testproject.org diff --git a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_cert-manager_issuers.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_cert-manager_issuers.yaml deleted file mode 100644 index 29988f44a9b..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_cert-manager_issuers.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: issuers.cert-manager.io -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_core_pods.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_core_pods.yaml deleted file mode 100644 index 8fa5d252208..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_core_pods.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: pods.core -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_crew_captains.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_crew_captains.yaml deleted file mode 100644 index f73ae2e8abc..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_crew_captains.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: captains.crew.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_example.com_memcacheds.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_example.com_memcacheds.yaml deleted file mode 100644 index 4a56b0f4c69..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_example.com_memcacheds.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: memcacheds.example.com.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_cruisers.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_cruisers.yaml deleted file mode 100644 index 99b6b6741b6..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_cruisers.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: cruisers.ship.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_destroyers.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_destroyers.yaml deleted file mode 100644 index 0e0095cb3a6..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_destroyers.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: destroyers.ship.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_frigates.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_frigates.yaml deleted file mode 100644 index cdc5078ae71..00000000000 --- a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_frigates.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: frigates.ship.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4-multigroup/config/default/kustomization.yaml b/testdata/project-v4-multigroup/config/default/kustomization.yaml deleted file mode 100644 index 556ccec1c19..00000000000 --- a/testdata/project-v4-multigroup/config/default/kustomization.yaml +++ /dev/null @@ -1,177 +0,0 @@ -# Adds namespace to all resources. -namespace: project-v4-multigroup-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-v4-multigroup- - -# Labels to add to all resources and selectors. -#labels: -#- includeSelectors: true -# pairs: -# someName: someValue - -resources: -- ../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 -# [METRICS] Expose the controller manager metrics service. -- metrics_service.yaml -# [NETWORK POLICY] Protect the /metrics endpoint and Webhook Server with NetworkPolicy. -# Only Pod(s) running a namespace labeled with 'metrics: enabled' will be able to gather the metrics. -# Only CR(s) which requires webhooks and are applied on namespaces labeled with 'webhooks: enabled' will -# be able to communicate with the Webhook Server. -#- ../network-policy - -# Uncomment the patches line if you enable Metrics, and/or are using webhooks and cert-manager -patches: -# [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. -# More info: https://book.kubebuilder.io/reference/metrics -- path: manager_metrics_patch.yaml - target: - kind: Deployment - -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -- path: manager_webhook_patch.yaml - -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -# Uncomment the following replacements to add the cert-manager CA injection annotations -#replacements: -# - source: # Uncomment the following block if you have a ValidatingWebhook (--programmatic-validation) -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.namespace # Namespace of the certificate CR -# targets: -# - select: -# kind: ValidatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.name -# targets: -# - select: -# kind: ValidatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# -# - source: # Uncomment the following block if you have a DefaultingWebhook (--defaulting ) -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.namespace # Namespace of the certificate CR -# targets: -# - select: -# kind: MutatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.name -# targets: -# - select: -# kind: MutatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# -# - source: # Uncomment the following block if you have a ConversionWebhook (--conversion) -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.namespace # Namespace of the certificate CR -# targets: -# - select: -# kind: CustomResourceDefinition -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.name -# targets: -# - select: -# kind: CustomResourceDefinition -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# -# - source: # Uncomment the following block if you enable cert-manager -# kind: Service -# version: v1 -# name: webhook-service -# fieldPath: .metadata.name # Name of the service -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# fieldPaths: -# - .spec.dnsNames.0 -# - .spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 0 -# create: true -# - source: -# kind: Service -# version: v1 -# name: webhook-service -# fieldPath: .metadata.namespace # Namespace of the service -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# fieldPaths: -# - .spec.dnsNames.0 -# - .spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 1 -# create: true diff --git a/testdata/project-v4-multigroup/config/default/manager_metrics_patch.yaml b/testdata/project-v4-multigroup/config/default/manager_metrics_patch.yaml deleted file mode 100644 index 2aaef6536f4..00000000000 --- a/testdata/project-v4-multigroup/config/default/manager_metrics_patch.yaml +++ /dev/null @@ -1,4 +0,0 @@ -# This patch adds the args to allow exposing the metrics endpoint using HTTPS -- op: add - path: /spec/template/spec/containers/0/args/0 - value: --metrics-bind-address=:8443 diff --git a/testdata/project-v4-multigroup/config/default/manager_webhook_patch.yaml b/testdata/project-v4-multigroup/config/default/manager_webhook_patch.yaml deleted file mode 100644 index 9fd690c819f..00000000000 --- a/testdata/project-v4-multigroup/config/default/manager_webhook_patch.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize -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-v4-multigroup/config/default/metrics_service.yaml b/testdata/project-v4-multigroup/config/default/metrics_service.yaml deleted file mode 100644 index afd67bb43af..00000000000 --- a/testdata/project-v4-multigroup/config/default/metrics_service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: controller-manager-metrics-service - namespace: system -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: 8443 - selector: - control-plane: controller-manager diff --git a/testdata/project-v4-multigroup/config/manager/kustomization.yaml b/testdata/project-v4-multigroup/config/manager/kustomization.yaml deleted file mode 100644 index ad13e96b3fc..00000000000 --- a/testdata/project-v4-multigroup/config/manager/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -resources: -- manager.yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -images: -- name: controller - newName: controller - newTag: latest diff --git a/testdata/project-v4-multigroup/config/manager/manager.yaml b/testdata/project-v4-multigroup/config/manager/manager.yaml deleted file mode 100644 index dc23b608705..00000000000 --- a/testdata/project-v4-multigroup/config/manager/manager.yaml +++ /dev/null @@ -1,100 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: system ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system - labels: - control-plane: controller-manager - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize -spec: - selector: - matchLabels: - control-plane: controller-manager - replicas: 1 - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - control-plane: controller-manager - spec: - # TODO(user): Uncomment the following code to configure the nodeAffinity expression - # according to the platforms which are supported by your solution. - # It is considered best practice to support multiple architectures. You can - # build your manager image using the makefile target docker-buildx. - # affinity: - # nodeAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # nodeSelectorTerms: - # - matchExpressions: - # - key: kubernetes.io/arch - # operator: In - # values: - # - amd64 - # - arm64 - # - ppc64le - # - s390x - # - key: kubernetes.io/os - # operator: In - # values: - # - linux - securityContext: - runAsNonRoot: true - # TODO(user): For common cases that do not require escalating privileges - # it is recommended to ensure that all your Pods/Containers are restrictive. - # More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - # Please uncomment the following code if your project does NOT have to work on old Kubernetes - # versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ). - # seccompProfile: - # type: RuntimeDefault - containers: - - command: - - /manager - args: - - --leader-elect - - --health-probe-bind-address=:8081 - image: controller:latest - name: manager - env: - - name: BUSYBOX_IMAGE - value: busybox:1.36.1 - - name: MEMCACHED_IMAGE - value: memcached:memcached:1.6.26-alpine3.19 - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - # TODO(user): Configure the resources accordingly based on the project requirements. - # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - serviceAccountName: controller-manager - terminationGracePeriodSeconds: 10 diff --git a/testdata/project-v4-multigroup/config/network-policy/allow-metrics-traffic.yaml b/testdata/project-v4-multigroup/config/network-policy/allow-metrics-traffic.yaml deleted file mode 100644 index 3f144fb140e..00000000000 --- a/testdata/project-v4-multigroup/config/network-policy/allow-metrics-traffic.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# This NetworkPolicy allows ingress traffic -# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those -# namespaces are able to gathering data from the metrics endpoint. -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: allow-metrics-traffic - namespace: system -spec: - podSelector: - matchLabels: - control-plane: controller-manager - policyTypes: - - Ingress - ingress: - # This allows ingress traffic from any namespace with the label metrics: enabled - - from: - - namespaceSelector: - matchLabels: - metrics: enabled # Only from namespaces with this label - ports: - - port: 8443 - protocol: TCP diff --git a/testdata/project-v4-multigroup/config/network-policy/allow-webhook-traffic.yaml b/testdata/project-v4-multigroup/config/network-policy/allow-webhook-traffic.yaml deleted file mode 100644 index ec32d71710c..00000000000 --- a/testdata/project-v4-multigroup/config/network-policy/allow-webhook-traffic.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# This NetworkPolicy allows ingress traffic to your webhook server running -# as part of the controller-manager from specific namespaces and pods. CR(s) which uses webhooks -# will only work when applied in namespaces labeled with 'webhook: enabled' -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: allow-webhook-traffic - namespace: system -spec: - podSelector: - matchLabels: - control-plane: controller-manager - policyTypes: - - Ingress - ingress: - # This allows ingress traffic from any namespace with the label webhook: enabled - - from: - - namespaceSelector: - matchLabels: - webhook: enabled # Only from namespaces with this label - ports: - - port: 443 - protocol: TCP diff --git a/testdata/project-v4-multigroup/config/network-policy/kustomization.yaml b/testdata/project-v4-multigroup/config/network-policy/kustomization.yaml deleted file mode 100644 index 0872bee124c..00000000000 --- a/testdata/project-v4-multigroup/config/network-policy/kustomization.yaml +++ /dev/null @@ -1,3 +0,0 @@ -resources: -- allow-webhook-traffic.yaml -- allow-metrics-traffic.yaml diff --git a/testdata/project-v4-multigroup/config/prometheus/kustomization.yaml b/testdata/project-v4-multigroup/config/prometheus/kustomization.yaml deleted file mode 100644 index ed137168a1d..00000000000 --- a/testdata/project-v4-multigroup/config/prometheus/kustomization.yaml +++ /dev/null @@ -1,2 +0,0 @@ -resources: -- monitor.yaml diff --git a/testdata/project-v4-multigroup/config/prometheus/monitor.yaml b/testdata/project-v4-multigroup/config/prometheus/monitor.yaml deleted file mode 100644 index 89d2f351f5b..00000000000 --- a/testdata/project-v4-multigroup/config/prometheus/monitor.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# Prometheus Monitor Service (Metrics) -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: controller-manager-metrics-monitor - namespace: system -spec: - endpoints: - - path: /metrics - port: https # Ensure this is the name of the port that exposes HTTPS metrics - scheme: https - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - tlsConfig: - # TODO(user): The option insecureSkipVerify: true is not recommended for production since it disables - # certificate verification. This poses a significant security risk by making the system vulnerable to - # man-in-the-middle attacks, where an attacker could intercept and manipulate the communication between - # Prometheus and the monitored services. This could lead to unauthorized access to sensitive metrics data, - # compromising the integrity and confidentiality of the information. - # Please use the following options for secure configurations: - # caFile: /etc/metrics-certs/ca.crt - # certFile: /etc/metrics-certs/tls.crt - # keyFile: /etc/metrics-certs/tls.key - insecureSkipVerify: true - selector: - matchLabels: - control-plane: controller-manager diff --git a/testdata/project-v4-multigroup/config/rbac/crew_captain_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/crew_captain_editor_role.yaml deleted file mode 100644 index c6a33cbfbda..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/crew_captain_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit captains. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: crew-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-v4-multigroup/config/rbac/crew_captain_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/crew_captain_viewer_role.yaml deleted file mode 100644 index 7d723490e56..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/crew_captain_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view captains. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: crew-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-v4-multigroup/config/rbac/example.com_busybox_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/example.com_busybox_editor_role.yaml deleted file mode 100644 index bcaffc621e4..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/example.com_busybox_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit busyboxes. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: example.com-busybox-editor-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_busybox_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/example.com_busybox_viewer_role.yaml deleted file mode 100644 index c4121f22e51..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/example.com_busybox_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view busyboxes. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: example.com-busybox-viewer-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - verbs: - - get - - list - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_memcached_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/example.com_memcached_editor_role.yaml deleted file mode 100644 index e5e1036db95..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/example.com_memcached_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit memcacheds. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: example.com-memcached-editor-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_memcached_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/example.com_memcached_viewer_role.yaml deleted file mode 100644 index 0bd3312686d..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/example.com_memcached_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view memcacheds. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: example.com-memcached-viewer-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds - verbs: - - get - - list - - watch -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/fiz_bar_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/fiz_bar_editor_role.yaml deleted file mode 100644 index 6ce5d8f2ef9..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/fiz_bar_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit bars. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: fiz-bar-editor-role -rules: -- apiGroups: - - fiz.testproject.org - resources: - - bars - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - fiz.testproject.org - resources: - - bars/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/fiz_bar_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/fiz_bar_viewer_role.yaml deleted file mode 100644 index 744a0a955c0..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/fiz_bar_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view bars. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: fiz-bar-viewer-role -rules: -- apiGroups: - - fiz.testproject.org - resources: - - bars - verbs: - - get - - list - - watch -- apiGroups: - - fiz.testproject.org - resources: - - bars/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_editor_role.yaml deleted file mode 100644 index 66fa7944f70..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit healthcheckpolicies. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: foo.policy-healthcheckpolicy-editor-role -rules: -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml deleted file mode 100644 index dff3ea7abc0..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view healthcheckpolicies. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: foo.policy-healthcheckpolicy-viewer-role -rules: -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies - verbs: - - get - - list - - watch -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/foo_bar_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/foo_bar_editor_role.yaml deleted file mode 100644 index f05089941a4..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/foo_bar_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit bars. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: foo-bar-editor-role -rules: -- apiGroups: - - foo.testproject.org - resources: - - bars - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - foo.testproject.org - resources: - - bars/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/foo_bar_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/foo_bar_viewer_role.yaml deleted file mode 100644 index eabf9ee517b..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/foo_bar_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view bars. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: foo-bar-viewer-role -rules: -- apiGroups: - - foo.testproject.org - resources: - - bars - verbs: - - get - - list - - watch -- apiGroups: - - foo.testproject.org - resources: - - bars/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/kustomization.yaml b/testdata/project-v4-multigroup/config/rbac/kustomization.yaml deleted file mode 100644 index bbf5c747bb5..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/kustomization.yaml +++ /dev/null @@ -1,47 +0,0 @@ -resources: -# All RBAC will be applied under this service account in -# the deployment namespace. You may comment out this resource -# if your manager will use a service account that exists at -# runtime. Be sure to update RoleBinding and ClusterRoleBinding -# subjects if changing service account names. -- service_account.yaml -- role.yaml -- role_binding.yaml -- leader_election_role.yaml -- leader_election_role_binding.yaml -# The following RBAC configurations are used to protect -# the metrics endpoint with authn/authz. These configurations -# ensure that only authorized users and service accounts -# can access the metrics endpoint. Comment the following -# permissions if you want to disable this protection. -# More info: https://book.kubebuilder.io/reference/metrics.html -- metrics_auth_role.yaml -- metrics_auth_role_binding.yaml -- metrics_reader_role.yaml -# For each CRD, "Editor" and "Viewer" roles are scaffolded by -# default, aiding admins in cluster management. Those roles are -# not used by the Project itself. You can comment the following lines -# if you do not want those helpers be installed with your Project. -- example.com_busybox_editor_role.yaml -- example.com_busybox_viewer_role.yaml -- example.com_memcached_editor_role.yaml -- example.com_memcached_viewer_role.yaml -- fiz_bar_editor_role.yaml -- fiz_bar_viewer_role.yaml -- foo_bar_editor_role.yaml -- foo_bar_viewer_role.yaml -- foo.policy_healthcheckpolicy_editor_role.yaml -- foo.policy_healthcheckpolicy_viewer_role.yaml -- sea-creatures_leviathan_editor_role.yaml -- sea-creatures_leviathan_viewer_role.yaml -- sea-creatures_kraken_editor_role.yaml -- sea-creatures_kraken_viewer_role.yaml -- ship_cruiser_editor_role.yaml -- ship_cruiser_viewer_role.yaml -- ship_destroyer_editor_role.yaml -- ship_destroyer_viewer_role.yaml -- ship_frigate_editor_role.yaml -- ship_frigate_viewer_role.yaml -- crew_captain_editor_role.yaml -- crew_captain_viewer_role.yaml - diff --git a/testdata/project-v4-multigroup/config/rbac/leader_election_role.yaml b/testdata/project-v4-multigroup/config/rbac/leader_election_role.yaml deleted file mode 100644 index 14015b3499d..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/leader_election_role.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# permissions to do leader election. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: leader-election-role -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch diff --git a/testdata/project-v4-multigroup/config/rbac/leader_election_role_binding.yaml b/testdata/project-v4-multigroup/config/rbac/leader_election_role_binding.yaml deleted file mode 100644 index 7af36fa2d81..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/leader_election_role_binding.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: leader-election-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: leader-election-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/testdata/project-v4-multigroup/config/rbac/metrics_auth_role.yaml b/testdata/project-v4-multigroup/config/rbac/metrics_auth_role.yaml deleted file mode 100644 index 32d2e4ec6b0..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/metrics_auth_role.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: metrics-auth-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create diff --git a/testdata/project-v4-multigroup/config/rbac/metrics_auth_role_binding.yaml b/testdata/project-v4-multigroup/config/rbac/metrics_auth_role_binding.yaml deleted file mode 100644 index e775d67ff08..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/metrics_auth_role_binding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: metrics-auth-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: metrics-auth-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/testdata/project-v4-multigroup/config/rbac/metrics_reader_role.yaml b/testdata/project-v4-multigroup/config/rbac/metrics_reader_role.yaml deleted file mode 100644 index 51a75db47a5..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/metrics_reader_role.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: metrics-reader -rules: -- nonResourceURLs: - - "/metrics" - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/role.yaml b/testdata/project-v4-multigroup/config/rbac/role.yaml deleted file mode 100644 index f8e24f77f46..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/role.yaml +++ /dev/null @@ -1,244 +0,0 @@ ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: manager-role -rules: -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch -- apiGroups: - - "" - resources: - - pods - verbs: - - get - - list - - watch -- apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - apps - resources: - - deployments/finalizers - verbs: - - update -- apiGroups: - - apps - resources: - - deployments/status - verbs: - - get - - patch - - update -- apiGroups: - - cert-manager.io - resources: - - certificates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - cert-manager.io - resources: - - certificates/finalizers - verbs: - - update -- apiGroups: - - cert-manager.io - resources: - - certificates/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: - - example.com.testproject.org - resources: - - busyboxes - - memcacheds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/finalizers - - memcacheds/finalizers - verbs: - - update -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - - memcacheds/status - verbs: - - get - - patch - - update -- apiGroups: - - fiz.testproject.org - - foo.testproject.org - resources: - - bars - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - fiz.testproject.org - - foo.testproject.org - resources: - - bars/finalizers - verbs: - - update -- apiGroups: - - fiz.testproject.org - - foo.testproject.org - resources: - - bars/status - verbs: - - get - - patch - - update -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies/finalizers - verbs: - - update -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies/status - verbs: - - get - - patch - - update -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens - - leviathans - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens/finalizers - - leviathans/finalizers - verbs: - - update -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens/status - - leviathans/status - verbs: - - get - - patch - - update -- apiGroups: - - ship.testproject.org - resources: - - cruisers - - destroyers - - frigates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ship.testproject.org - resources: - - cruisers/finalizers - - destroyers/finalizers - - frigates/finalizers - verbs: - - update -- apiGroups: - - ship.testproject.org - resources: - - cruisers/status - - destroyers/status - - frigates/status - verbs: - - get - - patch - - update diff --git a/testdata/project-v4-multigroup/config/rbac/role_binding.yaml b/testdata/project-v4-multigroup/config/rbac/role_binding.yaml deleted file mode 100644 index ae53b6529da..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/role_binding.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: manager-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_editor_role.yaml deleted file mode 100644 index 1d372dccf66..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit krakens. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: sea-creatures-kraken-editor-role -rules: -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_viewer_role.yaml deleted file mode 100644 index a65c4916546..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view krakens. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: sea-creatures-kraken-viewer-role -rules: -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens - verbs: - - get - - list - - watch -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_editor_role.yaml deleted file mode 100644 index 77d2ff19c22..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit leviathans. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: sea-creatures-leviathan-editor-role -rules: -- apiGroups: - - sea-creatures.testproject.org - resources: - - leviathans - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - sea-creatures.testproject.org - resources: - - leviathans/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_viewer_role.yaml deleted file mode 100644 index e0344e4699b..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view leviathans. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: sea-creatures-leviathan-viewer-role -rules: -- apiGroups: - - sea-creatures.testproject.org - resources: - - leviathans - verbs: - - get - - list - - watch -- apiGroups: - - sea-creatures.testproject.org - resources: - - leviathans/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/service_account.yaml b/testdata/project-v4-multigroup/config/rbac/service_account.yaml deleted file mode 100644 index 25d4288f404..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/service_account.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: controller-manager - namespace: system diff --git a/testdata/project-v4-multigroup/config/rbac/ship_cruiser_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_cruiser_editor_role.yaml deleted file mode 100644 index 32a0bcaf91e..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/ship_cruiser_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit cruisers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: ship-cruiser-editor-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - cruisers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ship.testproject.org - resources: - - cruisers/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/ship_cruiser_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_cruiser_viewer_role.yaml deleted file mode 100644 index 287ffcc397a..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/ship_cruiser_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view cruisers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: ship-cruiser-viewer-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - cruisers - verbs: - - get - - list - - watch -- apiGroups: - - ship.testproject.org - resources: - - cruisers/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/ship_destroyer_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_destroyer_editor_role.yaml deleted file mode 100644 index 8b0aa1da540..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/ship_destroyer_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit destroyers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: ship-destroyer-editor-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - destroyers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ship.testproject.org - resources: - - destroyers/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/ship_destroyer_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_destroyer_viewer_role.yaml deleted file mode 100644 index 027ff57455a..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/ship_destroyer_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view destroyers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: ship-destroyer-viewer-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - destroyers - verbs: - - get - - list - - watch -- apiGroups: - - ship.testproject.org - resources: - - destroyers/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/ship_frigate_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_frigate_editor_role.yaml deleted file mode 100644 index d0b243c8886..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/ship_frigate_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit frigates. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: ship-frigate-editor-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - frigates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ship.testproject.org - resources: - - frigates/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/ship_frigate_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_frigate_viewer_role.yaml deleted file mode 100644 index f8d54802480..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/ship_frigate_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view frigates. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: ship-frigate-viewer-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - frigates - verbs: - - get - - list - - watch -- apiGroups: - - ship.testproject.org - resources: - - frigates/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/samples/crew_v1_captain.yaml b/testdata/project-v4-multigroup/config/samples/crew_v1_captain.yaml deleted file mode 100644 index 0eed664c7cb..00000000000 --- a/testdata/project-v4-multigroup/config/samples/crew_v1_captain.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: crew.testproject.org/v1 -kind: Captain -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: captain-sample -spec: - # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_busybox.yaml b/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_busybox.yaml deleted file mode 100644 index 506d43a6f30..00000000000 --- a/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_busybox.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: example.com.testproject.org/v1alpha1 -kind: Busybox -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: busybox-sample -spec: - # TODO(user): edit the following value to ensure the number - # of Pods/Instances your Operand must have on cluster - size: 1 diff --git a/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_memcached.yaml b/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_memcached.yaml deleted file mode 100644 index 13b8e3cecb5..00000000000 --- a/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_memcached.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: example.com.testproject.org/v1alpha1 -kind: Memcached -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: memcached-sample -spec: - # TODO(user): edit the following value to ensure the number - # of Pods/Instances your Operand must have on cluster - size: 1 - - # TODO(user): edit the following value to ensure the container has the right port to be initialized - containerPort: 11211 diff --git a/testdata/project-v4-multigroup/config/samples/fiz_v1_bar.yaml b/testdata/project-v4-multigroup/config/samples/fiz_v1_bar.yaml deleted file mode 100644 index ded18d76876..00000000000 --- a/testdata/project-v4-multigroup/config/samples/fiz_v1_bar.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: fiz.testproject.org/v1 -kind: Bar -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: bar-sample -spec: - # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/foo.policy_v1_healthcheckpolicy.yaml b/testdata/project-v4-multigroup/config/samples/foo.policy_v1_healthcheckpolicy.yaml deleted file mode 100644 index 945fe8b48ad..00000000000 --- a/testdata/project-v4-multigroup/config/samples/foo.policy_v1_healthcheckpolicy.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: foo.policy.testproject.org/v1 -kind: HealthCheckPolicy -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: healthcheckpolicy-sample -spec: - # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/foo_v1_bar.yaml b/testdata/project-v4-multigroup/config/samples/foo_v1_bar.yaml deleted file mode 100644 index 6de418e33d7..00000000000 --- a/testdata/project-v4-multigroup/config/samples/foo_v1_bar.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: foo.testproject.org/v1 -kind: Bar -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: bar-sample -spec: - # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/kustomization.yaml b/testdata/project-v4-multigroup/config/samples/kustomization.yaml deleted file mode 100644 index cffe4bc820a..00000000000 --- a/testdata/project-v4-multigroup/config/samples/kustomization.yaml +++ /dev/null @@ -1,14 +0,0 @@ -## Append samples of your project ## -resources: -- crew_v1_captain.yaml -- ship_v1beta1_frigate.yaml -- ship_v1_destroyer.yaml -- ship_v2alpha1_cruiser.yaml -- sea-creatures_v1beta1_kraken.yaml -- sea-creatures_v1beta2_leviathan.yaml -- foo.policy_v1_healthcheckpolicy.yaml -- foo_v1_bar.yaml -- fiz_v1_bar.yaml -- example.com_v1alpha1_memcached.yaml -- example.com_v1alpha1_busybox.yaml -# +kubebuilder:scaffold:manifestskustomizesamples diff --git a/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta1_kraken.yaml b/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta1_kraken.yaml deleted file mode 100644 index 0e0453d7c80..00000000000 --- a/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta1_kraken.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: sea-creatures.testproject.org/v1beta1 -kind: Kraken -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: kraken-sample -spec: - # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta2_leviathan.yaml b/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta2_leviathan.yaml deleted file mode 100644 index 5d2125ed9b7..00000000000 --- a/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta2_leviathan.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: sea-creatures.testproject.org/v1beta2 -kind: Leviathan -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: leviathan-sample -spec: - # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/ship_v1_destroyer.yaml b/testdata/project-v4-multigroup/config/samples/ship_v1_destroyer.yaml deleted file mode 100644 index 946dee59890..00000000000 --- a/testdata/project-v4-multigroup/config/samples/ship_v1_destroyer.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: ship.testproject.org/v1 -kind: Destroyer -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: destroyer-sample -spec: - # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/ship_v1beta1_frigate.yaml b/testdata/project-v4-multigroup/config/samples/ship_v1beta1_frigate.yaml deleted file mode 100644 index b758b075bcf..00000000000 --- a/testdata/project-v4-multigroup/config/samples/ship_v1beta1_frigate.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: ship.testproject.org/v1beta1 -kind: Frigate -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: frigate-sample -spec: - # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/ship_v2alpha1_cruiser.yaml b/testdata/project-v4-multigroup/config/samples/ship_v2alpha1_cruiser.yaml deleted file mode 100644 index 58d0c89226b..00000000000 --- a/testdata/project-v4-multigroup/config/samples/ship_v2alpha1_cruiser.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: ship.testproject.org/v2alpha1 -kind: Cruiser -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: cruiser-sample -spec: - # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/webhook/kustomization.yaml b/testdata/project-v4-multigroup/config/webhook/kustomization.yaml deleted file mode 100644 index 9cf26134e4d..00000000000 --- a/testdata/project-v4-multigroup/config/webhook/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -resources: -- manifests.yaml -- service.yaml - -configurations: -- kustomizeconfig.yaml diff --git a/testdata/project-v4-multigroup/config/webhook/kustomizeconfig.yaml b/testdata/project-v4-multigroup/config/webhook/kustomizeconfig.yaml deleted file mode 100644 index 206316e54ff..00000000000 --- a/testdata/project-v4-multigroup/config/webhook/kustomizeconfig.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# the following config is for teaching kustomize where to look at when substituting nameReference. -# 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 diff --git a/testdata/project-v4-multigroup/config/webhook/manifests.yaml b/testdata/project-v4-multigroup/config/webhook/manifests.yaml deleted file mode 100644 index 6a694a4a8e6..00000000000 --- a/testdata/project-v4-multigroup/config/webhook/manifests.yaml +++ /dev/null @@ -1,152 +0,0 @@ ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: mutating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-cert-manager-io-v1-issuer - failurePolicy: Fail - name: missuer-v1.kb.io - rules: - - apiGroups: - - cert-manager.io - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - issuers - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-crew-testproject-org-v1-captain - failurePolicy: Fail - name: mcaptain-v1.kb.io - rules: - - apiGroups: - - crew.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - captains - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-ship-testproject-org-v1-destroyer - failurePolicy: Fail - name: mdestroyer-v1.kb.io - rules: - - apiGroups: - - ship.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - destroyers - sideEffects: None ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: validating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /validate--v1-pod - failurePolicy: Fail - name: vpod-v1.kb.io - rules: - - apiGroups: - - "" - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - pods - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /validate-crew-testproject-org-v1-captain - failurePolicy: Fail - name: vcaptain-v1.kb.io - rules: - - apiGroups: - - crew.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - captains - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /validate-example-com-testproject-org-v1alpha1-memcached - failurePolicy: Fail - name: vmemcached-v1alpha1.kb.io - rules: - - apiGroups: - - example.com.testproject.org - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - memcacheds - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /validate-ship-testproject-org-v2alpha1-cruiser - failurePolicy: Fail - name: vcruiser-v2alpha1.kb.io - rules: - - apiGroups: - - ship.testproject.org - apiVersions: - - v2alpha1 - operations: - - CREATE - - UPDATE - resources: - - cruisers - sideEffects: None diff --git a/testdata/project-v4-multigroup/config/webhook/service.yaml b/testdata/project-v4-multigroup/config/webhook/service.yaml deleted file mode 100644 index 0ba1f669758..00000000000 --- a/testdata/project-v4-multigroup/config/webhook/service.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/name: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: webhook-service - namespace: system -spec: - ports: - - port: 443 - protocol: TCP - targetPort: 9443 - selector: - control-plane: controller-manager diff --git a/testdata/project-v4-multigroup/dist/install.yaml b/testdata/project-v4-multigroup/dist/install.yaml deleted file mode 100644 index 56d97112886..00000000000 --- a/testdata/project-v4-multigroup/dist/install.yaml +++ /dev/null @@ -1,1962 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - control-plane: controller-manager - name: project-v4-multigroup-system ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: bars.fiz.testproject.org -spec: - group: fiz.testproject.org - names: - kind: Bar - listKind: BarList - plural: bars - singular: bar - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Bar is the Schema for the bars 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: BarSpec defines the desired state of Bar. - properties: - foo: - description: Foo is an example field of Bar. Edit bar_types.go to - remove/update - type: string - type: object - status: - description: BarStatus defines the observed state of Bar. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: bars.foo.testproject.org -spec: - group: foo.testproject.org - names: - kind: Bar - listKind: BarList - plural: bars - singular: bar - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Bar is the Schema for the bars 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: BarSpec defines the desired state of Bar. - properties: - foo: - description: Foo is an example field of Bar. Edit bar_types.go to - remove/update - type: string - type: object - status: - description: BarStatus defines the observed state of Bar. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: busyboxes.example.com.testproject.org -spec: - group: example.com.testproject.org - names: - kind: Busybox - listKind: BusyboxList - plural: busyboxes - singular: busybox - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Busybox is the Schema for the busyboxes 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: BusyboxSpec defines the desired state of Busybox - properties: - size: - description: |- - Size defines the number of Busybox instances - The following markers will use OpenAPI v3 schema to validate the value - More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - format: int32 - maximum: 3 - minimum: 1 - type: integer - type: object - status: - description: BusyboxStatus defines the observed state of Busybox - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: captains.crew.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /convert - conversionReviewVersions: - - v1 - 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: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: cruisers.ship.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /convert - conversionReviewVersions: - - v1 - group: ship.testproject.org - names: - kind: Cruiser - listKind: CruiserList - plural: cruisers - singular: cruiser - scope: Cluster - versions: - - name: v2alpha1 - schema: - openAPIV3Schema: - description: Cruiser is the Schema for the cruisers 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: CruiserSpec defines the desired state of Cruiser. - properties: - foo: - description: Foo is an example field of Cruiser. Edit cruiser_types.go - to remove/update - type: string - type: object - status: - description: CruiserStatus defines the observed state of Cruiser. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: destroyers.ship.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /convert - conversionReviewVersions: - - v1 - group: ship.testproject.org - names: - kind: Destroyer - listKind: DestroyerList - plural: destroyers - singular: destroyer - scope: Cluster - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Destroyer is the Schema for the destroyers 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: DestroyerSpec defines the desired state of Destroyer. - properties: - foo: - description: Foo is an example field of Destroyer. Edit destroyer_types.go - to remove/update - type: string - type: object - status: - description: DestroyerStatus defines the observed state of Destroyer. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: frigates.ship.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /convert - conversionReviewVersions: - - v1 - group: ship.testproject.org - names: - kind: Frigate - listKind: FrigateList - plural: frigates - singular: frigate - scope: Namespaced - versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: Frigate is the Schema for the frigates 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: FrigateSpec defines the desired state of Frigate. - properties: - foo: - description: Foo is an example field of Frigate. Edit frigate_types.go - to remove/update - type: string - type: object - status: - description: FrigateStatus defines the observed state of Frigate. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: healthcheckpolicies.foo.policy.testproject.org -spec: - group: foo.policy.testproject.org - names: - kind: HealthCheckPolicy - listKind: HealthCheckPolicyList - plural: healthcheckpolicies - singular: healthcheckpolicy - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: HealthCheckPolicy is the Schema for the healthcheckpolicies 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: HealthCheckPolicySpec defines the desired state of HealthCheckPolicy. - properties: - foo: - description: Foo is an example field of HealthCheckPolicy. Edit healthcheckpolicy_types.go - to remove/update - type: string - type: object - status: - description: HealthCheckPolicyStatus defines the observed state of HealthCheckPolicy. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: krakens.sea-creatures.testproject.org -spec: - group: sea-creatures.testproject.org - names: - kind: Kraken - listKind: KrakenList - plural: krakens - singular: kraken - scope: Namespaced - versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: Kraken is the Schema for the krakens 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: KrakenSpec defines the desired state of Kraken. - properties: - foo: - description: Foo is an example field of Kraken. Edit kraken_types.go - to remove/update - type: string - type: object - status: - description: KrakenStatus defines the observed state of Kraken. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: leviathans.sea-creatures.testproject.org -spec: - group: sea-creatures.testproject.org - names: - kind: Leviathan - listKind: LeviathanList - plural: leviathans - singular: leviathan - scope: Namespaced - versions: - - name: v1beta2 - schema: - openAPIV3Schema: - description: Leviathan is the Schema for the leviathans 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: LeviathanSpec defines the desired state of Leviathan. - properties: - foo: - description: Foo is an example field of Leviathan. Edit leviathan_types.go - to remove/update - type: string - type: object - status: - description: LeviathanStatus defines the observed state of Leviathan. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: memcacheds.example.com.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /convert - conversionReviewVersions: - - v1 - group: example.com.testproject.org - names: - kind: Memcached - listKind: MemcachedList - plural: memcacheds - singular: memcached - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Memcached is the Schema for the memcacheds 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: MemcachedSpec defines the desired state of Memcached - properties: - containerPort: - description: Port defines the port that will be used to init the container - with the image - format: int32 - type: integer - size: - description: |- - Size defines the number of Memcached instances - The following markers will use OpenAPI v3 schema to validate the value - More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - format: int32 - maximum: 3 - minimum: 1 - type: integer - type: object - status: - description: MemcachedStatus defines the observed state of Memcached - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-controller-manager - namespace: project-v4-multigroup-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-leader-election-role - namespace: project-v4-multigroup-system -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-crew-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 ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-crew-captain-viewer-role -rules: -- apiGroups: - - crew.testproject.org - resources: - - captains - verbs: - - get - - list - - watch -- apiGroups: - - crew.testproject.org - resources: - - captains/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-example.com-busybox-editor-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-example.com-busybox-viewer-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - verbs: - - get - - list - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-example.com-memcached-editor-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-example.com-memcached-viewer-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds - verbs: - - get - - list - - watch -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-fiz-bar-editor-role -rules: -- apiGroups: - - fiz.testproject.org - resources: - - bars - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - fiz.testproject.org - resources: - - bars/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-fiz-bar-viewer-role -rules: -- apiGroups: - - fiz.testproject.org - resources: - - bars - verbs: - - get - - list - - watch -- apiGroups: - - fiz.testproject.org - resources: - - bars/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-foo-bar-editor-role -rules: -- apiGroups: - - foo.testproject.org - resources: - - bars - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - foo.testproject.org - resources: - - bars/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-foo-bar-viewer-role -rules: -- apiGroups: - - foo.testproject.org - resources: - - bars - verbs: - - get - - list - - watch -- apiGroups: - - foo.testproject.org - resources: - - bars/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-foo.policy-healthcheckpolicy-editor-role -rules: -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-foo.policy-healthcheckpolicy-viewer-role -rules: -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies - verbs: - - get - - list - - watch -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: project-v4-multigroup-manager-role -rules: -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch -- apiGroups: - - "" - resources: - - pods - verbs: - - get - - list - - watch -- apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - apps - resources: - - deployments/finalizers - verbs: - - update -- apiGroups: - - apps - resources: - - deployments/status - verbs: - - get - - patch - - update -- apiGroups: - - cert-manager.io - resources: - - certificates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - cert-manager.io - resources: - - certificates/finalizers - verbs: - - update -- apiGroups: - - cert-manager.io - resources: - - certificates/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: - - example.com.testproject.org - resources: - - busyboxes - - memcacheds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/finalizers - - memcacheds/finalizers - verbs: - - update -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - - memcacheds/status - verbs: - - get - - patch - - update -- apiGroups: - - fiz.testproject.org - - foo.testproject.org - resources: - - bars - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - fiz.testproject.org - - foo.testproject.org - resources: - - bars/finalizers - verbs: - - update -- apiGroups: - - fiz.testproject.org - - foo.testproject.org - resources: - - bars/status - verbs: - - get - - patch - - update -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies/finalizers - verbs: - - update -- apiGroups: - - foo.policy.testproject.org - resources: - - healthcheckpolicies/status - verbs: - - get - - patch - - update -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens - - leviathans - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens/finalizers - - leviathans/finalizers - verbs: - - update -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens/status - - leviathans/status - verbs: - - get - - patch - - update -- apiGroups: - - ship.testproject.org - resources: - - cruisers - - destroyers - - frigates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ship.testproject.org - resources: - - cruisers/finalizers - - destroyers/finalizers - - frigates/finalizers - verbs: - - update -- apiGroups: - - ship.testproject.org - resources: - - cruisers/status - - destroyers/status - - frigates/status - verbs: - - get - - patch - - update ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: project-v4-multigroup-metrics-auth-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: project-v4-multigroup-metrics-reader -rules: -- nonResourceURLs: - - /metrics - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-sea-creatures-kraken-editor-role -rules: -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-sea-creatures-kraken-viewer-role -rules: -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens - verbs: - - get - - list - - watch -- apiGroups: - - sea-creatures.testproject.org - resources: - - krakens/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-sea-creatures-leviathan-editor-role -rules: -- apiGroups: - - sea-creatures.testproject.org - resources: - - leviathans - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - sea-creatures.testproject.org - resources: - - leviathans/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-sea-creatures-leviathan-viewer-role -rules: -- apiGroups: - - sea-creatures.testproject.org - resources: - - leviathans - verbs: - - get - - list - - watch -- apiGroups: - - sea-creatures.testproject.org - resources: - - leviathans/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-ship-cruiser-editor-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - cruisers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ship.testproject.org - resources: - - cruisers/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-ship-cruiser-viewer-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - cruisers - verbs: - - get - - list - - watch -- apiGroups: - - ship.testproject.org - resources: - - cruisers/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-ship-destroyer-editor-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - destroyers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ship.testproject.org - resources: - - destroyers/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-ship-destroyer-viewer-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - destroyers - verbs: - - get - - list - - watch -- apiGroups: - - ship.testproject.org - resources: - - destroyers/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-ship-frigate-editor-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - frigates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ship.testproject.org - resources: - - frigates/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-ship-frigate-viewer-role -rules: -- apiGroups: - - ship.testproject.org - resources: - - frigates - verbs: - - get - - list - - watch -- apiGroups: - - ship.testproject.org - resources: - - frigates/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-leader-election-rolebinding - namespace: project-v4-multigroup-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: project-v4-multigroup-leader-election-role -subjects: -- kind: ServiceAccount - name: project-v4-multigroup-controller-manager - namespace: project-v4-multigroup-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-v4-multigroup-manager-role -subjects: -- kind: ServiceAccount - name: project-v4-multigroup-controller-manager - namespace: project-v4-multigroup-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: project-v4-multigroup-metrics-auth-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-v4-multigroup-metrics-auth-role -subjects: -- kind: ServiceAccount - name: project-v4-multigroup-controller-manager - namespace: project-v4-multigroup-system ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - control-plane: controller-manager - name: project-v4-multigroup-controller-manager-metrics-service - namespace: project-v4-multigroup-system -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: 8443 - selector: - control-plane: controller-manager ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system -spec: - ports: - - port: 443 - protocol: TCP - targetPort: 9443 - selector: - control-plane: controller-manager ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-multigroup - control-plane: controller-manager - name: project-v4-multigroup-controller-manager - namespace: project-v4-multigroup-system -spec: - replicas: 1 - selector: - matchLabels: - control-plane: controller-manager - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - control-plane: controller-manager - spec: - containers: - - args: - - --metrics-bind-address=:8443 - - --leader-elect - - --health-probe-bind-address=:8081 - command: - - /manager - env: - - name: BUSYBOX_IMAGE - value: busybox:1.36.1 - - name: MEMCACHED_IMAGE - value: memcached:memcached:1.6.26-alpine3.19 - image: controller:latest - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - name: manager - ports: - - containerPort: 9443 - name: webhook-server - protocol: TCP - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - volumeMounts: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cert - readOnly: true - securityContext: - runAsNonRoot: true - serviceAccountName: project-v4-multigroup-controller-manager - terminationGracePeriodSeconds: 10 - volumes: - - name: cert - secret: - defaultMode: 420 - secretName: webhook-server-cert ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: project-v4-multigroup-mutating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /mutate-cert-manager-io-v1-issuer - failurePolicy: Fail - name: missuer-v1.kb.io - rules: - - apiGroups: - - cert-manager.io - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - issuers - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /mutate-crew-testproject-org-v1-captain - failurePolicy: Fail - name: mcaptain-v1.kb.io - rules: - - apiGroups: - - crew.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - captains - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /mutate-ship-testproject-org-v1-destroyer - failurePolicy: Fail - name: mdestroyer-v1.kb.io - rules: - - apiGroups: - - ship.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - destroyers - sideEffects: None ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: project-v4-multigroup-validating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /validate--v1-pod - failurePolicy: Fail - name: vpod-v1.kb.io - rules: - - apiGroups: - - "" - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - pods - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /validate-crew-testproject-org-v1-captain - failurePolicy: Fail - name: vcaptain-v1.kb.io - rules: - - apiGroups: - - crew.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - captains - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /validate-example-com-testproject-org-v1alpha1-memcached - failurePolicy: Fail - name: vmemcached-v1alpha1.kb.io - rules: - - apiGroups: - - example.com.testproject.org - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - memcacheds - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-multigroup-webhook-service - namespace: project-v4-multigroup-system - path: /validate-ship-testproject-org-v2alpha1-cruiser - failurePolicy: Fail - name: vcruiser-v2alpha1.kb.io - rules: - - apiGroups: - - ship.testproject.org - apiVersions: - - v2alpha1 - operations: - - CREATE - - UPDATE - resources: - - cruisers - sideEffects: None diff --git a/testdata/project-v4-multigroup/go.mod b/testdata/project-v4-multigroup/go.mod deleted file mode 100644 index 69774941f19..00000000000 --- a/testdata/project-v4-multigroup/go.mod +++ /dev/null @@ -1,101 +0,0 @@ -module sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup - -go 1.22.0 - -require ( - github.com/cert-manager/cert-manager v1.16.1 - github.com/onsi/ginkgo/v2 v2.19.0 - github.com/onsi/gomega v1.33.1 - k8s.io/api v0.31.1 - k8s.io/apimachinery v0.31.1 - k8s.io/client-go v0.31.1 - sigs.k8s.io/controller-runtime v0.19.0 -) - -require ( - github.com/antlr4-go/antlr/v4 v4.13.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.12.1 // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/google/cel-go v0.20.1 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.20.4 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect - github.com/spf13/cobra v1.8.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/stoewer/go-strcase v1.3.0 // indirect - github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect - go.opentelemetry.io/otel v1.29.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.29.0 // indirect - go.opentelemetry.io/otel/sdk v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.29.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.24.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/grpc v1.66.2 // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.31.1 // indirect - k8s.io/apiserver v0.31.1 // indirect - k8s.io/component-base v0.31.1 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 // indirect - k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect - sigs.k8s.io/gateway-api v1.1.0 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect -) diff --git a/testdata/project-v4-multigroup/grafana/controller-resources-metrics.json b/testdata/project-v4-multigroup/grafana/controller-resources-metrics.json deleted file mode 100644 index 629e0d3c9b1..00000000000 --- a/testdata/project-v4-multigroup/grafana/controller-resources-metrics.json +++ /dev/null @@ -1,306 +0,0 @@ -{ - "__inputs": [ - { - "name": "DS_PROMETHEUS", - "label": "Prometheus", - "description": "", - "type": "datasource", - "pluginId": "prometheus", - "pluginName": "Prometheus" - } - ], - "__requires": [ - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "1.0.0" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "links": [], - "liveNow": false, - "panels": [ - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "percent" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 0 - }, - "id": 2, - "interval": "1m", - "links": [], - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.4.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "rate(process_cpu_seconds_total{job=\"$job\", namespace=\"$namespace\", pod=\"$pod\"}[5m]) * 100", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "Pod: {{pod}} | Container: {{container}}", - "refId": "A", - "step": 10 - } - ], - "title": "Controller CPU Usage", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 0 - }, - "id": 4, - "interval": "1m", - "links": [], - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.4.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "process_resident_memory_bytes{job=\"$job\", namespace=\"$namespace\", pod=\"$pod\"}", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "Pod: {{pod}} | Container: {{container}}", - "refId": "A", - "step": 10 - } - ], - "title": "Controller Memory Usage", - "type": "timeseries" - } - ], - "refresh": "", - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "job", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "current": { - "selected": false, - "text": "observability", - "value": "observability" - }, - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total, namespace)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "namespace", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total, namespace)", - "refId": "StandardVariableQuery" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "current": { - "selected": false, - "text": "All", - "value": "$__all" - }, - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "hide": 2, - "includeAll": true, - "label": "pod", - "multi": true, - "name": "pod", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Controller-Resources-Metrics", - "weekStart": "" -} diff --git a/testdata/project-v4-multigroup/grafana/controller-runtime-metrics.json b/testdata/project-v4-multigroup/grafana/controller-runtime-metrics.json deleted file mode 100644 index c8eea4cb434..00000000000 --- a/testdata/project-v4-multigroup/grafana/controller-runtime-metrics.json +++ /dev/null @@ -1,898 +0,0 @@ -{ - "__inputs": [ - { - "name": "DS_PROMETHEUS", - "label": "Prometheus", - "description": "", - "type": "datasource", - "pluginId": "prometheus", - "pluginName": "Prometheus" - } - ], - "__requires": [ - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "1.0.0" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "links": [], - "liveNow": false, - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 9, - "panels": [], - "title": "Reconciliation Metrics", - "type": "row" - }, - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "percentage", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "orange", - "value": 70 - }, - { - "color": "red", - "value": 85 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 3, - "x": 0, - "y": 1 - }, - "id": 24, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "controller_runtime_active_workers{job=\"$job\", namespace=\"$namespace\"}", - "interval": "", - "legendFormat": "{{controller}} {{instance}}", - "refId": "A" - } - ], - "title": "Number of workers in use", - "type": "gauge" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "Total number of reconciliations per controller", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "cpm" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 11, - "x": 3, - "y": 1 - }, - "id": 7, - "options": { - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "editorMode": "code", - "exemplar": true, - "expr": "sum(rate(controller_runtime_reconcile_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, pod)", - "interval": "", - "legendFormat": "{{instance}} {{pod}}", - "range": true, - "refId": "A" - } - ], - "title": "Total Reconciliation Count Per Controller", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "Total number of reconciliation errors per controller", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "cpm" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 10, - "x": 14, - "y": 1 - }, - "id": 6, - "options": { - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "editorMode": "code", - "exemplar": true, - "expr": "sum(rate(controller_runtime_reconcile_errors_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, pod)", - "interval": "", - "legendFormat": "{{instance}} {{pod}}", - "range": true, - "refId": "A" - } - ], - "title": "Reconciliation Error Count Per Controller", - "type": "timeseries" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 9 - }, - "id": 11, - "panels": [], - "title": "Work Queue Metrics", - "type": "row" - }, - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "percentage", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "orange", - "value": 70 - }, - { - "color": "red", - "value": 85 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 3, - "x": 0, - "y": 10 - }, - "id": 22, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "workqueue_depth{job=\"$job\", namespace=\"$namespace\"}", - "interval": "", - "legendFormat": "", - "refId": "A" - } - ], - "title": "WorkQueue Depth", - "type": "gauge" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "How long in seconds an item stays in workqueue before being requested", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "normal" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 11, - "x": 3, - "y": 10 - }, - "id": 13, - "options": { - "legend": { - "calcs": [ - "max", - "mean" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.50, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "interval": "", - "legendFormat": "P50 {{name}} {{instance}} ", - "refId": "A" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.90, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P90 {{name}} {{instance}} ", - "refId": "B" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P99 {{name}} {{instance}} ", - "refId": "C" - } - ], - "title": "Seconds For Items Stay In Queue (before being requested) (P50, P90, P99)", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "ops" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 10, - "x": 14, - "y": 10 - }, - "id": 15, - "options": { - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.4.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "sum(rate(workqueue_adds_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name)", - "interval": "", - "legendFormat": "{{name}} {{instance}}", - "refId": "A" - } - ], - "title": "Work Queue Add Rate", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "How many seconds of work has done that is in progress and hasn't been observed by work_duration.\nLarge values indicate stuck threads.\nOne can deduce the number of stuck threads by observing the rate at which this increases.", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "percentage", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "orange", - "value": 70 - }, - { - "color": "red", - "value": 85 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 9, - "w": 3, - "x": 0, - "y": 18 - }, - "id": 23, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "rate(workqueue_unfinished_work_seconds{job=\"$job\", namespace=\"$namespace\"}[5m])", - "interval": "", - "legendFormat": "", - "refId": "A" - } - ], - "title": "Unfinished Seconds", - "type": "gauge" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "How long in seconds processing an item from workqueue takes.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 9, - "w": 11, - "x": 3, - "y": 18 - }, - "id": 19, - "options": { - "legend": { - "calcs": [ - "max", - "mean" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.50, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "interval": "", - "legendFormat": "P50 {{name}} {{instance}} ", - "refId": "A" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.90, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P90 {{name}} {{instance}} ", - "refId": "B" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.99, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P99 {{name}} {{instance}} ", - "refId": "C" - } - ], - "title": "Seconds Processing Items From WorkQueue (P50, P90, P99)", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "Total number of retries handled by workqueue", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "ops" - }, - "overrides": [] - }, - "gridPos": { - "h": 9, - "w": 10, - "x": 14, - "y": 18 - }, - "id": 17, - "options": { - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "sum(rate(workqueue_retries_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name)", - "interval": "", - "legendFormat": "{{name}} {{instance}} ", - "refId": "A" - } - ], - "title": "Work Queue Retries Rate", - "type": "timeseries" - } - ], - "refresh": "", - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "job", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total, namespace)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "namespace", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total, namespace)", - "refId": "StandardVariableQuery" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "current": { - "selected": true, - "text": [ - "All" - ], - "value": [ - "$__all" - ] - }, - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "hide": 2, - "includeAll": true, - "label": "pod", - "multi": true, - "name": "pod", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Controller-Runtime-Metrics", - "weekStart": "" -} diff --git a/testdata/project-v4-multigroup/grafana/custom-metrics/config.yaml b/testdata/project-v4-multigroup/grafana/custom-metrics/config.yaml deleted file mode 100644 index 3ee1bebdf24..00000000000 --- a/testdata/project-v4-multigroup/grafana/custom-metrics/config.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -customMetrics: -# - metric: # Raw custom metric (required) -# type: # Metric type: counter/gauge/histogram (required) -# expr: # Prom_ql for the metric (optional) -# unit: # Unit of measurement, examples: s,none,bytes,percent,etc. (optional) -# -# -# Example: -# --- -# customMetrics: -# - metric: foo_bar -# unit: none -# type: histogram -# expr: histogram_quantile(0.90, sum by(instance, le) (rate(foo_bar{job=\"$job\", namespace=\"$namespace\"}[5m]))) diff --git a/testdata/project-v4-multigroup/hack/boilerplate.go.txt b/testdata/project-v4-multigroup/hack/boilerplate.go.txt deleted file mode 100644 index 0d32012672a..00000000000 --- a/testdata/project-v4-multigroup/hack/boilerplate.go.txt +++ /dev/null @@ -1,15 +0,0 @@ -/* -Copyright 2024 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-v4-multigroup/internal/controller/apps/deployment_controller.go b/testdata/project-v4-multigroup/internal/controller/apps/deployment_controller.go deleted file mode 100644 index c3c79078b17..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/apps/deployment_controller.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2024 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 apps - -import ( - "context" - - appsv1 "k8s.io/api/apps/v1" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" -) - -// DeploymentReconciler reconciles a Deployment object -type DeploymentReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=apps,resources=deployments/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 Deployment 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.19.0/pkg/reconcile -func (r *DeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *DeploymentReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&appsv1.Deployment{}). - Named("apps-deployment"). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/apps/deployment_controller_test.go b/testdata/project-v4-multigroup/internal/controller/apps/deployment_controller_test.go deleted file mode 100644 index 339a1532026..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/apps/deployment_controller_test.go +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright 2024 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 apps - -import ( - . "github.com/onsi/ginkgo/v2" -) - -var _ = Describe("Deployment Controller", func() { - Context("When reconciling a resource", func() { - - It("should successfully reconcile the resource", func() { - - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/apps/suite_test.go b/testdata/project-v4-multigroup/internal/controller/apps/suite_test.go deleted file mode 100644 index 8d7a448f9e8..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/apps/suite_test.go +++ /dev/null @@ -1,95 +0,0 @@ -/* -Copyright 2024 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 apps - -import ( - "context" - "fmt" - "path/filepath" - "runtime" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - appsv1 "k8s.io/api/apps/v1" - "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - // +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 -var ctx context.Context -var cancel context.CancelFunc - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = appsv1.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()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/cert-manager/certificate_controller.go b/testdata/project-v4-multigroup/internal/controller/cert-manager/certificate_controller.go deleted file mode 100644 index af5ec391ad3..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/cert-manager/certificate_controller.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2024 The Kubernetes authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package certmanager - -import ( - "context" - - certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" -) - -// CertificateReconciler reconciles a Certificate object -type CertificateReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates/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 Certificate 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.19.0/pkg/reconcile -func (r *CertificateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *CertificateReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&certmanagerv1.Certificate{}). - Named("cert-manager-certificate"). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/cert-manager/certificate_controller_test.go b/testdata/project-v4-multigroup/internal/controller/cert-manager/certificate_controller_test.go deleted file mode 100644 index 3959874773b..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/cert-manager/certificate_controller_test.go +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright 2024 The Kubernetes authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package certmanager - -import ( - . "github.com/onsi/ginkgo/v2" -) - -var _ = Describe("Certificate Controller", func() { - Context("When reconciling a resource", func() { - - It("should successfully reconcile the resource", func() { - - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/cert-manager/suite_test.go b/testdata/project-v4-multigroup/internal/controller/cert-manager/suite_test.go deleted file mode 100644 index 8a55c1d28e9..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/cert-manager/suite_test.go +++ /dev/null @@ -1,95 +0,0 @@ -/* -Copyright 2024 The Kubernetes authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package certmanager - -import ( - "context" - "fmt" - "path/filepath" - "runtime" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - // +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 -var ctx context.Context -var cancel context.CancelFunc - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = certmanagerv1.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()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/crew/captain_controller.go b/testdata/project-v4-multigroup/internal/controller/crew/captain_controller.go deleted file mode 100644 index d6878885a45..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/crew/captain_controller.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2024 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 crew - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/crew/v1" -) - -// CaptainReconciler reconciles a Captain object -type CaptainReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=crew.testproject.org,resources=captains,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=crew.testproject.org,resources=captains/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=crew.testproject.org,resources=captains/finalizers,verbs=update - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// TODO(user): Modify the Reconcile function to compare the state specified by -// the Captain object against the actual cluster state, and then -// perform operations to make the cluster state reflect the state specified by -// the user. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/reconcile -func (r *CaptainReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *CaptainReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&crewv1.Captain{}). - Named("crew-captain"). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/crew/captain_controller_test.go b/testdata/project-v4-multigroup/internal/controller/crew/captain_controller_test.go deleted file mode 100644 index c2495aee47c..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/crew/captain_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2024 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 crew - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/crew/v1" -) - -var _ = Describe("Captain Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - captain := &crewv1.Captain{} - - BeforeEach(func() { - By("creating the custom resource for the Kind Captain") - err := k8sClient.Get(ctx, typeNamespacedName, captain) - if err != nil && errors.IsNotFound(err) { - resource := &crewv1.Captain{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &crewv1.Captain{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance Captain") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &CaptainReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/crew/suite_test.go b/testdata/project-v4-multigroup/internal/controller/crew/suite_test.go deleted file mode 100644 index 840accd8f8a..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/crew/suite_test.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2024 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 crew - -import ( - "context" - "fmt" - "path/filepath" - "runtime" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/crew/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 -var ctx context.Context -var cancel context.CancelFunc - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = crewv1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:scheme - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller.go b/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller.go deleted file mode 100644 index 2995a0bb2fa..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller.go +++ /dev/null @@ -1,443 +0,0 @@ -/* -Copyright 2024 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 examplecom - -import ( - "context" - "fmt" - "os" - "strings" - "time" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/log" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" -) - -const busyboxFinalizer = "example.com.testproject.org/finalizer" - -// Definitions to manage status conditions -const ( - // typeAvailableBusybox represents the status of the Deployment reconciliation - typeAvailableBusybox = "Available" - // typeDegradedBusybox represents the status used when the custom resource is deleted and the finalizer operations are yet to occur. - typeDegradedBusybox = "Degraded" -) - -// BusyboxReconciler reconciles a Busybox object -type BusyboxReconciler struct { - client.Client - Scheme *runtime.Scheme - Recorder record.EventRecorder -} - -// The following markers are used to generate the rules permissions (RBAC) on config/rbac using controller-gen -// when the command is executed. -// To know more about markers see: https://book.kubebuilder.io/reference/markers.html - -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=busyboxes,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=busyboxes/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=busyboxes/finalizers,verbs=update -// +kubebuilder:rbac:groups=core,resources=events,verbs=create;patch -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// It is essential for the controller's reconciliation loop to be idempotent. By following the Operator -// pattern you will create Controllers which provide a reconcile function -// responsible for synchronizing resources until the desired state is reached on the cluster. -// Breaking this recommendation goes against the design principles of controller-runtime. -// and may lead to unforeseen consequences such as resources becoming stuck and requiring manual intervention. -// For further info: -// - About Operator Pattern: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/ -// - About Controllers: https://kubernetes.io/docs/concepts/architecture/controller/ -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/reconcile -func (r *BusyboxReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - log := log.FromContext(ctx) - - // Fetch the Busybox instance - // The purpose is check if the Custom Resource for the Kind Busybox - // is applied on the cluster if not we return nil to stop the reconciliation - busybox := &examplecomv1alpha1.Busybox{} - err := r.Get(ctx, req.NamespacedName, busybox) - if err != nil { - if apierrors.IsNotFound(err) { - // If the custom resource is not found then it usually means that it was deleted or not created - // In this way, we will stop the reconciliation - log.Info("busybox resource not found. Ignoring since object must be deleted") - return ctrl.Result{}, nil - } - // Error reading the object - requeue the request. - log.Error(err, "Failed to get busybox") - return ctrl.Result{}, err - } - - // Let's just set the status as Unknown when no status is available - if busybox.Status.Conditions == nil || len(busybox.Status.Conditions) == 0 { - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, Status: metav1.ConditionUnknown, Reason: "Reconciling", Message: "Starting reconciliation"}) - if err = r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - // Let's re-fetch the busybox Custom Resource after updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - // if we try to update it again in the following operations - if err := r.Get(ctx, req.NamespacedName, busybox); err != nil { - log.Error(err, "Failed to re-fetch busybox") - return ctrl.Result{}, err - } - } - - // Let's add a finalizer. Then, we can define some operations which should - // occur before the custom resource is deleted. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers - if !controllerutil.ContainsFinalizer(busybox, busyboxFinalizer) { - log.Info("Adding Finalizer for Busybox") - if ok := controllerutil.AddFinalizer(busybox, busyboxFinalizer); !ok { - log.Error(err, "Failed to add finalizer into the custom resource") - return ctrl.Result{Requeue: true}, nil - } - - if err = r.Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update custom resource to add finalizer") - return ctrl.Result{}, err - } - } - - // Check if the Busybox instance is marked to be deleted, which is - // indicated by the deletion timestamp being set. - isBusyboxMarkedToBeDeleted := busybox.GetDeletionTimestamp() != nil - if isBusyboxMarkedToBeDeleted { - if controllerutil.ContainsFinalizer(busybox, busyboxFinalizer) { - log.Info("Performing Finalizer Operations for Busybox before delete CR") - - // Let's add here a status "Downgrade" to reflect that this resource began its process to be terminated. - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeDegradedBusybox, - Status: metav1.ConditionUnknown, Reason: "Finalizing", - Message: fmt.Sprintf("Performing finalizer operations for the custom resource: %s ", busybox.Name)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - // Perform all operations required before removing the finalizer and allow - // the Kubernetes API to remove the custom resource. - r.doFinalizerOperationsForBusybox(busybox) - - // TODO(user): If you add operations to the doFinalizerOperationsForBusybox method - // then you need to ensure that all worked fine before deleting and updating the Downgrade status - // otherwise, you should requeue here. - - // Re-fetch the busybox Custom Resource before updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, busybox); err != nil { - log.Error(err, "Failed to re-fetch busybox") - return ctrl.Result{}, err - } - - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeDegradedBusybox, - Status: metav1.ConditionTrue, Reason: "Finalizing", - Message: fmt.Sprintf("Finalizer operations for custom resource %s name were successfully accomplished", busybox.Name)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - log.Info("Removing Finalizer for Busybox after successfully perform the operations") - if ok := controllerutil.RemoveFinalizer(busybox, busyboxFinalizer); !ok { - log.Error(err, "Failed to remove finalizer for Busybox") - return ctrl.Result{Requeue: true}, nil - } - - if err := r.Update(ctx, busybox); err != nil { - log.Error(err, "Failed to remove finalizer for Busybox") - return ctrl.Result{}, err - } - } - return ctrl.Result{}, nil - } - - // Check if the deployment already exists, if not create a new one - found := &appsv1.Deployment{} - err = r.Get(ctx, types.NamespacedName{Name: busybox.Name, Namespace: busybox.Namespace}, found) - if err != nil && apierrors.IsNotFound(err) { - // Define a new deployment - dep, err := r.deploymentForBusybox(busybox) - if err != nil { - log.Error(err, "Failed to define new Deployment resource for Busybox") - - // The following implementation will update the status - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, - Status: metav1.ConditionFalse, Reason: "Reconciling", - Message: fmt.Sprintf("Failed to create Deployment for the custom resource (%s): (%s)", busybox.Name, err)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - log.Info("Creating a new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - if err = r.Create(ctx, dep); err != nil { - log.Error(err, "Failed to create new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - return ctrl.Result{}, err - } - - // Deployment created successfully - // We will requeue the reconciliation so that we can ensure the state - // and move forward for the next operations - return ctrl.Result{RequeueAfter: time.Minute}, nil - } else if err != nil { - log.Error(err, "Failed to get Deployment") - // Let's return the error for the reconciliation be re-trigged again - return ctrl.Result{}, err - } - - // The CRD API defines that the Busybox type have a BusyboxSpec.Size field - // to set the quantity of Deployment instances to the desired state on the cluster. - // Therefore, the following code will ensure the Deployment size is the same as defined - // via the Size spec of the Custom Resource which we are reconciling. - size := busybox.Spec.Size - if *found.Spec.Replicas != size { - found.Spec.Replicas = &size - if err = r.Update(ctx, found); err != nil { - log.Error(err, "Failed to update Deployment", - "Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name) - - // Re-fetch the busybox Custom Resource before updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, busybox); err != nil { - log.Error(err, "Failed to re-fetch busybox") - return ctrl.Result{}, err - } - - // The following implementation will update the status - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, - Status: metav1.ConditionFalse, Reason: "Resizing", - Message: fmt.Sprintf("Failed to update the size for the custom resource (%s): (%s)", busybox.Name, err)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - // Now, that we update the size we want to requeue the reconciliation - // so that we can ensure that we have the latest state of the resource before - // update. Also, it will help ensure the desired state on the cluster - return ctrl.Result{Requeue: true}, nil - } - - // The following implementation will update the status - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, - Status: metav1.ConditionTrue, Reason: "Reconciling", - Message: fmt.Sprintf("Deployment for custom resource (%s) with %d replicas created successfully", busybox.Name, size)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, nil -} - -// finalizeBusybox will perform the required operations before delete the CR. -func (r *BusyboxReconciler) doFinalizerOperationsForBusybox(cr *examplecomv1alpha1.Busybox) { - // TODO(user): Add the cleanup steps that the operator - // needs to do before the CR can be deleted. Examples - // of finalizers include performing backups and deleting - // resources that are not owned by this CR, like a PVC. - - // Note: It is not recommended to use finalizers with the purpose of deleting resources which are - // created and managed in the reconciliation. These ones, such as the Deployment created on this reconcile, - // are defined as dependent of the custom resource. See that we use the method ctrl.SetControllerReference. - // to set the ownerRef which means that the Deployment will be deleted by the Kubernetes API. - // More info: https://kubernetes.io/docs/tasks/administer-cluster/use-cascading-deletion/ - - // The following implementation will raise an event - r.Recorder.Event(cr, "Warning", "Deleting", - fmt.Sprintf("Custom Resource %s is being deleted from the namespace %s", - cr.Name, - cr.Namespace)) -} - -// deploymentForBusybox returns a Busybox Deployment object -func (r *BusyboxReconciler) deploymentForBusybox( - busybox *examplecomv1alpha1.Busybox) (*appsv1.Deployment, error) { - ls := labelsForBusybox() - replicas := busybox.Spec.Size - - // Get the Operand image - image, err := imageForBusybox() - if err != nil { - return nil, err - } - - dep := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: busybox.Name, - Namespace: busybox.Namespace, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: ls, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: ls, - }, - Spec: corev1.PodSpec{ - // TODO(user): Uncomment the following code to configure the nodeAffinity expression - // according to the platforms which are supported by your solution. It is considered - // best practice to support multiple architectures. build your manager image using the - // makefile target docker-buildx. Also, you can use docker manifest inspect - // to check what are the platforms supported. - // More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity - // Affinity: &corev1.Affinity{ - // NodeAffinity: &corev1.NodeAffinity{ - // RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ - // NodeSelectorTerms: []corev1.NodeSelectorTerm{ - // { - // MatchExpressions: []corev1.NodeSelectorRequirement{ - // { - // Key: "kubernetes.io/arch", - // Operator: "In", - // Values: []string{"amd64", "arm64", "ppc64le", "s390x"}, - // }, - // { - // Key: "kubernetes.io/os", - // Operator: "In", - // Values: []string{"linux"}, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - SecurityContext: &corev1.PodSecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - // IMPORTANT: seccomProfile was introduced with Kubernetes 1.19 - // If you are looking for to produce solutions to be supported - // on lower versions you must remove this option. - SeccompProfile: &corev1.SeccompProfile{ - Type: corev1.SeccompProfileTypeRuntimeDefault, - }, - }, - Containers: []corev1.Container{{ - Image: image, - Name: "busybox", - ImagePullPolicy: corev1.PullIfNotPresent, - // Ensure restrictive context for the container - // More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - SecurityContext: &corev1.SecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - AllowPrivilegeEscalation: &[]bool{false}[0], - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - }, - }}, - }, - }, - }, - } - - // Set the ownerRef for the Deployment - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/ - if err := ctrl.SetControllerReference(busybox, dep, r.Scheme); err != nil { - return nil, err - } - return dep, nil -} - -// labelsForBusybox returns the labels for selecting the resources -// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/ -func labelsForBusybox() map[string]string { - var imageTag string - image, err := imageForBusybox() - if err == nil { - imageTag = strings.Split(image, ":")[1] - } - return map[string]string{"app.kubernetes.io/name": "project-v4-multigroup", - "app.kubernetes.io/version": imageTag, - "app.kubernetes.io/managed-by": "BusyboxController", - } -} - -// imageForBusybox gets the Operand image which is managed by this controller -// from the BUSYBOX_IMAGE environment variable defined in the config/manager/manager.yaml -func imageForBusybox() (string, error) { - var imageEnvVar = "BUSYBOX_IMAGE" - image, found := os.LookupEnv(imageEnvVar) - if !found { - return "", fmt.Errorf("Unable to find %s environment variable with the image", imageEnvVar) - } - return image, nil -} - -// SetupWithManager sets up the controller with the Manager. -// The whole idea is to be watching the resources that matter for the controller. -// When a resource that the controller is interested in changes, the Watch triggers -// the controller’s reconciliation loop, ensuring that the actual state of the resource -// matches the desired state as defined in the controller’s logic. -// -// Notice how we configured the Manager to monitor events such as the creation, update, -// or deletion of a Custom Resource (CR) of the Busybox kind, as well as any changes -// to the Deployment that the controller manages and owns. -func (r *BusyboxReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - // Watch the Busybox CR(s) and trigger reconciliation whenever it - // is created, updated, or deleted - For(&examplecomv1alpha1.Busybox{}). - Named("example.com-busybox"). - // Watch the Deployment managed by the BusyboxReconciler. If any changes occur to the Deployment - // owned and managed by this controller, it will trigger reconciliation, ensuring that the cluster - // state aligns with the desired state. See that the ownerRef was set when the Deployment was created. - Owns(&appsv1.Deployment{}). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller_test.go b/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller_test.go deleted file mode 100644 index 1013257a3bd..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller_test.go +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright 2024 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 examplecom - -import ( - "context" - "os" - "time" - - //nolint:golint - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" -) - -var _ = Describe("Busybox controller", func() { - Context("Busybox controller test", func() { - - const BusyboxName = "test-busybox" - - ctx := context.Background() - - namespace := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: BusyboxName, - Namespace: BusyboxName, - }, - } - - typeNamespacedName := types.NamespacedName{ - Name: BusyboxName, - Namespace: BusyboxName, - } - busybox := &examplecomv1alpha1.Busybox{} - - SetDefaultEventuallyTimeout(2 * time.Minute) - SetDefaultEventuallyPollingInterval(time.Second) - - BeforeEach(func() { - By("Creating the Namespace to perform the tests") - err := k8sClient.Create(ctx, namespace) - Expect(err).NotTo(HaveOccurred()) - - By("Setting the Image ENV VAR which stores the Operand image") - err = os.Setenv("BUSYBOX_IMAGE", "example.com/image:test") - Expect(err).NotTo(HaveOccurred()) - - By("creating the custom resource for the Kind Busybox") - err = k8sClient.Get(ctx, typeNamespacedName, busybox) - if err != nil && errors.IsNotFound(err) { - // Let's mock our custom resource at the same way that we would - // apply on the cluster the manifest under config/samples - busybox := &examplecomv1alpha1.Busybox{ - ObjectMeta: metav1.ObjectMeta{ - Name: BusyboxName, - Namespace: namespace.Name, - }, - Spec: examplecomv1alpha1.BusyboxSpec{ - Size: 1, - }, - } - - err = k8sClient.Create(ctx, busybox) - Expect(err).NotTo(HaveOccurred()) - } - }) - - AfterEach(func() { - By("removing the custom resource for the Kind Busybox") - found := &examplecomv1alpha1.Busybox{} - err := k8sClient.Get(ctx, typeNamespacedName, found) - Expect(err).NotTo(HaveOccurred()) - - Eventually(func(g Gomega) { - g.Expect(k8sClient.Delete(context.TODO(), found)).To(Succeed()) - }).Should(Succeed()) - - // TODO(user): Attention if you improve this code by adding other context test you MUST - // be aware of the current delete namespace limitations. - // More info: https://book.kubebuilder.io/reference/envtest.html#testing-considerations - By("Deleting the Namespace to perform the tests") - _ = k8sClient.Delete(ctx, namespace) - - By("Removing the Image ENV VAR which stores the Operand image") - _ = os.Unsetenv("BUSYBOX_IMAGE") - }) - - It("should successfully reconcile a custom resource for Busybox", func() { - By("Checking if the custom resource was successfully created") - Eventually(func(g Gomega) { - found := &examplecomv1alpha1.Busybox{} - Expect(k8sClient.Get(ctx, typeNamespacedName, found)).To(Succeed()) - }).Should(Succeed()) - - By("Reconciling the custom resource created") - busyboxReconciler := &BusyboxReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := busyboxReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - - By("Checking if Deployment was successfully created in the reconciliation") - Eventually(func(g Gomega) { - found := &appsv1.Deployment{} - g.Expect(k8sClient.Get(ctx, typeNamespacedName, found)).To(Succeed()) - }).Should(Succeed()) - - By("Reconciling the custom resource again") - _, err = busyboxReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - - By("Checking the latest Status Condition added to the Busybox instance") - Expect(k8sClient.Get(ctx, typeNamespacedName, busybox)).To(Succeed()) - conditions := []metav1.Condition{} - Expect(busybox.Status.Conditions).To(ContainElement( - HaveField("Type", Equal(typeAvailableBusybox)), &conditions)) - Expect(conditions).To(HaveLen(1), "Multiple conditions of type %s", typeAvailableBusybox) - Expect(conditions[0].Status).To(Equal(metav1.ConditionTrue), "condition %s", typeAvailableBusybox) - Expect(conditions[0].Reason).To(Equal("Reconciling"), "condition %s", typeAvailableBusybox) - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller.go b/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller.go deleted file mode 100644 index d3896d58c14..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller.go +++ /dev/null @@ -1,449 +0,0 @@ -/* -Copyright 2024 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 examplecom - -import ( - "context" - "fmt" - "os" - "strings" - "time" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/log" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" -) - -const memcachedFinalizer = "example.com.testproject.org/finalizer" - -// Definitions to manage status conditions -const ( - // typeAvailableMemcached represents the status of the Deployment reconciliation - typeAvailableMemcached = "Available" - // typeDegradedMemcached represents the status used when the custom resource is deleted and the finalizer operations are yet to occur. - typeDegradedMemcached = "Degraded" -) - -// MemcachedReconciler reconciles a Memcached object -type MemcachedReconciler struct { - client.Client - Scheme *runtime.Scheme - Recorder record.EventRecorder -} - -// The following markers are used to generate the rules permissions (RBAC) on config/rbac using controller-gen -// when the command is executed. -// To know more about markers see: https://book.kubebuilder.io/reference/markers.html - -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=memcacheds/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=memcacheds/finalizers,verbs=update -// +kubebuilder:rbac:groups=core,resources=events,verbs=create;patch -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// It is essential for the controller's reconciliation loop to be idempotent. By following the Operator -// pattern you will create Controllers which provide a reconcile function -// responsible for synchronizing resources until the desired state is reached on the cluster. -// Breaking this recommendation goes against the design principles of controller-runtime. -// and may lead to unforeseen consequences such as resources becoming stuck and requiring manual intervention. -// For further info: -// - About Operator Pattern: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/ -// - About Controllers: https://kubernetes.io/docs/concepts/architecture/controller/ -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/reconcile -func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - log := log.FromContext(ctx) - - // Fetch the Memcached instance - // The purpose is check if the Custom Resource for the Kind Memcached - // is applied on the cluster if not we return nil to stop the reconciliation - memcached := &examplecomv1alpha1.Memcached{} - err := r.Get(ctx, req.NamespacedName, memcached) - if err != nil { - if apierrors.IsNotFound(err) { - // If the custom resource is not found then it usually means that it was deleted or not created - // In this way, we will stop the reconciliation - log.Info("memcached resource not found. Ignoring since object must be deleted") - return ctrl.Result{}, nil - } - // Error reading the object - requeue the request. - log.Error(err, "Failed to get memcached") - return ctrl.Result{}, err - } - - // Let's just set the status as Unknown when no status is available - if memcached.Status.Conditions == nil || len(memcached.Status.Conditions) == 0 { - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, Status: metav1.ConditionUnknown, Reason: "Reconciling", Message: "Starting reconciliation"}) - if err = r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - // Let's re-fetch the memcached Custom Resource after updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - // if we try to update it again in the following operations - if err := r.Get(ctx, req.NamespacedName, memcached); err != nil { - log.Error(err, "Failed to re-fetch memcached") - return ctrl.Result{}, err - } - } - - // Let's add a finalizer. Then, we can define some operations which should - // occur before the custom resource is deleted. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers - if !controllerutil.ContainsFinalizer(memcached, memcachedFinalizer) { - log.Info("Adding Finalizer for Memcached") - if ok := controllerutil.AddFinalizer(memcached, memcachedFinalizer); !ok { - log.Error(err, "Failed to add finalizer into the custom resource") - return ctrl.Result{Requeue: true}, nil - } - - if err = r.Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update custom resource to add finalizer") - return ctrl.Result{}, err - } - } - - // Check if the Memcached instance is marked to be deleted, which is - // indicated by the deletion timestamp being set. - isMemcachedMarkedToBeDeleted := memcached.GetDeletionTimestamp() != nil - if isMemcachedMarkedToBeDeleted { - if controllerutil.ContainsFinalizer(memcached, memcachedFinalizer) { - log.Info("Performing Finalizer Operations for Memcached before delete CR") - - // Let's add here a status "Downgrade" to reflect that this resource began its process to be terminated. - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeDegradedMemcached, - Status: metav1.ConditionUnknown, Reason: "Finalizing", - Message: fmt.Sprintf("Performing finalizer operations for the custom resource: %s ", memcached.Name)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - // Perform all operations required before removing the finalizer and allow - // the Kubernetes API to remove the custom resource. - r.doFinalizerOperationsForMemcached(memcached) - - // TODO(user): If you add operations to the doFinalizerOperationsForMemcached method - // then you need to ensure that all worked fine before deleting and updating the Downgrade status - // otherwise, you should requeue here. - - // Re-fetch the memcached Custom Resource before updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, memcached); err != nil { - log.Error(err, "Failed to re-fetch memcached") - return ctrl.Result{}, err - } - - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeDegradedMemcached, - Status: metav1.ConditionTrue, Reason: "Finalizing", - Message: fmt.Sprintf("Finalizer operations for custom resource %s name were successfully accomplished", memcached.Name)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - log.Info("Removing Finalizer for Memcached after successfully perform the operations") - if ok := controllerutil.RemoveFinalizer(memcached, memcachedFinalizer); !ok { - log.Error(err, "Failed to remove finalizer for Memcached") - return ctrl.Result{Requeue: true}, nil - } - - if err := r.Update(ctx, memcached); err != nil { - log.Error(err, "Failed to remove finalizer for Memcached") - return ctrl.Result{}, err - } - } - return ctrl.Result{}, nil - } - - // Check if the deployment already exists, if not create a new one - found := &appsv1.Deployment{} - err = r.Get(ctx, types.NamespacedName{Name: memcached.Name, Namespace: memcached.Namespace}, found) - if err != nil && apierrors.IsNotFound(err) { - // Define a new deployment - dep, err := r.deploymentForMemcached(memcached) - if err != nil { - log.Error(err, "Failed to define new Deployment resource for Memcached") - - // The following implementation will update the status - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, - Status: metav1.ConditionFalse, Reason: "Reconciling", - Message: fmt.Sprintf("Failed to create Deployment for the custom resource (%s): (%s)", memcached.Name, err)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - log.Info("Creating a new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - if err = r.Create(ctx, dep); err != nil { - log.Error(err, "Failed to create new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - return ctrl.Result{}, err - } - - // Deployment created successfully - // We will requeue the reconciliation so that we can ensure the state - // and move forward for the next operations - return ctrl.Result{RequeueAfter: time.Minute}, nil - } else if err != nil { - log.Error(err, "Failed to get Deployment") - // Let's return the error for the reconciliation be re-trigged again - return ctrl.Result{}, err - } - - // The CRD API defines that the Memcached type have a MemcachedSpec.Size field - // to set the quantity of Deployment instances to the desired state on the cluster. - // Therefore, the following code will ensure the Deployment size is the same as defined - // via the Size spec of the Custom Resource which we are reconciling. - size := memcached.Spec.Size - if *found.Spec.Replicas != size { - found.Spec.Replicas = &size - if err = r.Update(ctx, found); err != nil { - log.Error(err, "Failed to update Deployment", - "Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name) - - // Re-fetch the memcached Custom Resource before updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, memcached); err != nil { - log.Error(err, "Failed to re-fetch memcached") - return ctrl.Result{}, err - } - - // The following implementation will update the status - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, - Status: metav1.ConditionFalse, Reason: "Resizing", - Message: fmt.Sprintf("Failed to update the size for the custom resource (%s): (%s)", memcached.Name, err)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - // Now, that we update the size we want to requeue the reconciliation - // so that we can ensure that we have the latest state of the resource before - // update. Also, it will help ensure the desired state on the cluster - return ctrl.Result{Requeue: true}, nil - } - - // The following implementation will update the status - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, - Status: metav1.ConditionTrue, Reason: "Reconciling", - Message: fmt.Sprintf("Deployment for custom resource (%s) with %d replicas created successfully", memcached.Name, size)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, nil -} - -// finalizeMemcached will perform the required operations before delete the CR. -func (r *MemcachedReconciler) doFinalizerOperationsForMemcached(cr *examplecomv1alpha1.Memcached) { - // TODO(user): Add the cleanup steps that the operator - // needs to do before the CR can be deleted. Examples - // of finalizers include performing backups and deleting - // resources that are not owned by this CR, like a PVC. - - // Note: It is not recommended to use finalizers with the purpose of deleting resources which are - // created and managed in the reconciliation. These ones, such as the Deployment created on this reconcile, - // are defined as dependent of the custom resource. See that we use the method ctrl.SetControllerReference. - // to set the ownerRef which means that the Deployment will be deleted by the Kubernetes API. - // More info: https://kubernetes.io/docs/tasks/administer-cluster/use-cascading-deletion/ - - // The following implementation will raise an event - r.Recorder.Event(cr, "Warning", "Deleting", - fmt.Sprintf("Custom Resource %s is being deleted from the namespace %s", - cr.Name, - cr.Namespace)) -} - -// deploymentForMemcached returns a Memcached Deployment object -func (r *MemcachedReconciler) deploymentForMemcached( - memcached *examplecomv1alpha1.Memcached) (*appsv1.Deployment, error) { - ls := labelsForMemcached() - replicas := memcached.Spec.Size - - // Get the Operand image - image, err := imageForMemcached() - if err != nil { - return nil, err - } - - dep := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: memcached.Name, - Namespace: memcached.Namespace, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: ls, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: ls, - }, - Spec: corev1.PodSpec{ - // TODO(user): Uncomment the following code to configure the nodeAffinity expression - // according to the platforms which are supported by your solution. It is considered - // best practice to support multiple architectures. build your manager image using the - // makefile target docker-buildx. Also, you can use docker manifest inspect - // to check what are the platforms supported. - // More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity - // Affinity: &corev1.Affinity{ - // NodeAffinity: &corev1.NodeAffinity{ - // RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ - // NodeSelectorTerms: []corev1.NodeSelectorTerm{ - // { - // MatchExpressions: []corev1.NodeSelectorRequirement{ - // { - // Key: "kubernetes.io/arch", - // Operator: "In", - // Values: []string{"amd64", "arm64", "ppc64le", "s390x"}, - // }, - // { - // Key: "kubernetes.io/os", - // Operator: "In", - // Values: []string{"linux"}, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - SecurityContext: &corev1.PodSecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - // IMPORTANT: seccomProfile was introduced with Kubernetes 1.19 - // If you are looking for to produce solutions to be supported - // on lower versions you must remove this option. - SeccompProfile: &corev1.SeccompProfile{ - Type: corev1.SeccompProfileTypeRuntimeDefault, - }, - }, - Containers: []corev1.Container{{ - Image: image, - Name: "memcached", - ImagePullPolicy: corev1.PullIfNotPresent, - // Ensure restrictive context for the container - // More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - SecurityContext: &corev1.SecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - RunAsUser: &[]int64{1001}[0], - AllowPrivilegeEscalation: &[]bool{false}[0], - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - }, - Ports: []corev1.ContainerPort{{ - ContainerPort: memcached.Spec.ContainerPort, - Name: "memcached", - }}, - Command: []string{"memcached", "--memory-limit=64", "-o", "modern", "-v"}, - }}, - }, - }, - }, - } - - // Set the ownerRef for the Deployment - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/ - if err := ctrl.SetControllerReference(memcached, dep, r.Scheme); err != nil { - return nil, err - } - return dep, nil -} - -// labelsForMemcached returns the labels for selecting the resources -// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/ -func labelsForMemcached() map[string]string { - var imageTag string - image, err := imageForMemcached() - if err == nil { - imageTag = strings.Split(image, ":")[1] - } - return map[string]string{"app.kubernetes.io/name": "project-v4-multigroup", - "app.kubernetes.io/version": imageTag, - "app.kubernetes.io/managed-by": "MemcachedController", - } -} - -// imageForMemcached gets the Operand image which is managed by this controller -// from the MEMCACHED_IMAGE environment variable defined in the config/manager/manager.yaml -func imageForMemcached() (string, error) { - var imageEnvVar = "MEMCACHED_IMAGE" - image, found := os.LookupEnv(imageEnvVar) - if !found { - return "", fmt.Errorf("Unable to find %s environment variable with the image", imageEnvVar) - } - return image, nil -} - -// SetupWithManager sets up the controller with the Manager. -// The whole idea is to be watching the resources that matter for the controller. -// When a resource that the controller is interested in changes, the Watch triggers -// the controller’s reconciliation loop, ensuring that the actual state of the resource -// matches the desired state as defined in the controller’s logic. -// -// Notice how we configured the Manager to monitor events such as the creation, update, -// or deletion of a Custom Resource (CR) of the Memcached kind, as well as any changes -// to the Deployment that the controller manages and owns. -func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - // Watch the Memcached CR(s) and trigger reconciliation whenever it - // is created, updated, or deleted - For(&examplecomv1alpha1.Memcached{}). - Named("example.com-memcached"). - // Watch the Deployment managed by the MemcachedReconciler. If any changes occur to the Deployment - // owned and managed by this controller, it will trigger reconciliation, ensuring that the cluster - // state aligns with the desired state. See that the ownerRef was set when the Deployment was created. - Owns(&appsv1.Deployment{}). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller_test.go b/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller_test.go deleted file mode 100644 index 2a04bf2c4d2..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller_test.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 2024 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 examplecom - -import ( - "context" - "os" - "time" - - //nolint:golint - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" -) - -var _ = Describe("Memcached controller", func() { - Context("Memcached controller test", func() { - - const MemcachedName = "test-memcached" - - ctx := context.Background() - - namespace := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: MemcachedName, - Namespace: MemcachedName, - }, - } - - typeNamespacedName := types.NamespacedName{ - Name: MemcachedName, - Namespace: MemcachedName, - } - memcached := &examplecomv1alpha1.Memcached{} - - SetDefaultEventuallyTimeout(2 * time.Minute) - SetDefaultEventuallyPollingInterval(time.Second) - - BeforeEach(func() { - By("Creating the Namespace to perform the tests") - err := k8sClient.Create(ctx, namespace) - Expect(err).NotTo(HaveOccurred()) - - By("Setting the Image ENV VAR which stores the Operand image") - err = os.Setenv("MEMCACHED_IMAGE", "example.com/image:test") - Expect(err).NotTo(HaveOccurred()) - - By("creating the custom resource for the Kind Memcached") - err = k8sClient.Get(ctx, typeNamespacedName, memcached) - if err != nil && errors.IsNotFound(err) { - // Let's mock our custom resource at the same way that we would - // apply on the cluster the manifest under config/samples - memcached := &examplecomv1alpha1.Memcached{ - ObjectMeta: metav1.ObjectMeta{ - Name: MemcachedName, - Namespace: namespace.Name, - }, - Spec: examplecomv1alpha1.MemcachedSpec{ - Size: 1, - ContainerPort: 11211, - }, - } - - err = k8sClient.Create(ctx, memcached) - Expect(err).NotTo(HaveOccurred()) - } - }) - - AfterEach(func() { - By("removing the custom resource for the Kind Memcached") - found := &examplecomv1alpha1.Memcached{} - err := k8sClient.Get(ctx, typeNamespacedName, found) - Expect(err).NotTo(HaveOccurred()) - - Eventually(func(g Gomega) { - g.Expect(k8sClient.Delete(context.TODO(), found)).To(Succeed()) - }).Should(Succeed()) - - // TODO(user): Attention if you improve this code by adding other context test you MUST - // be aware of the current delete namespace limitations. - // More info: https://book.kubebuilder.io/reference/envtest.html#testing-considerations - By("Deleting the Namespace to perform the tests") - _ = k8sClient.Delete(ctx, namespace) - - By("Removing the Image ENV VAR which stores the Operand image") - _ = os.Unsetenv("MEMCACHED_IMAGE") - }) - - It("should successfully reconcile a custom resource for Memcached", func() { - By("Checking if the custom resource was successfully created") - Eventually(func(g Gomega) { - found := &examplecomv1alpha1.Memcached{} - Expect(k8sClient.Get(ctx, typeNamespacedName, found)).To(Succeed()) - }).Should(Succeed()) - - By("Reconciling the custom resource created") - memcachedReconciler := &MemcachedReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := memcachedReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - - By("Checking if Deployment was successfully created in the reconciliation") - Eventually(func(g Gomega) { - found := &appsv1.Deployment{} - g.Expect(k8sClient.Get(ctx, typeNamespacedName, found)).To(Succeed()) - }).Should(Succeed()) - - By("Reconciling the custom resource again") - _, err = memcachedReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - - By("Checking the latest Status Condition added to the Memcached instance") - Expect(k8sClient.Get(ctx, typeNamespacedName, memcached)).To(Succeed()) - conditions := []metav1.Condition{} - Expect(memcached.Status.Conditions).To(ContainElement( - HaveField("Type", Equal(typeAvailableMemcached)), &conditions)) - Expect(conditions).To(HaveLen(1), "Multiple conditions of type %s", typeAvailableMemcached) - Expect(conditions[0].Status).To(Equal(metav1.ConditionTrue), "condition %s", typeAvailableMemcached) - Expect(conditions[0].Reason).To(Equal("Reconciling"), "condition %s", typeAvailableMemcached) - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/example.com/suite_test.go b/testdata/project-v4-multigroup/internal/controller/example.com/suite_test.go deleted file mode 100644 index 316975ca415..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/example.com/suite_test.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2024 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 examplecom - -import ( - "context" - "fmt" - "path/filepath" - "runtime" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" - // +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 -var ctx context.Context -var cancel context.CancelFunc - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = examplecomv1alpha1.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()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/fiz/bar_controller.go b/testdata/project-v4-multigroup/internal/controller/fiz/bar_controller.go deleted file mode 100644 index 7ef0d3623a5..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/fiz/bar_controller.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2024 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 fiz - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - fizv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/fiz/v1" -) - -// BarReconciler reconciles a Bar object -type BarReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=fiz.testproject.org,resources=bars,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=fiz.testproject.org,resources=bars/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=fiz.testproject.org,resources=bars/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 Bar 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.19.0/pkg/reconcile -func (r *BarReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *BarReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&fizv1.Bar{}). - Named("fiz-bar"). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/fiz/bar_controller_test.go b/testdata/project-v4-multigroup/internal/controller/fiz/bar_controller_test.go deleted file mode 100644 index c9dca3f1172..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/fiz/bar_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2024 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 fiz - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - fizv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/fiz/v1" -) - -var _ = Describe("Bar Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - bar := &fizv1.Bar{} - - BeforeEach(func() { - By("creating the custom resource for the Kind Bar") - err := k8sClient.Get(ctx, typeNamespacedName, bar) - if err != nil && errors.IsNotFound(err) { - resource := &fizv1.Bar{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &fizv1.Bar{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance Bar") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &BarReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/fiz/suite_test.go b/testdata/project-v4-multigroup/internal/controller/fiz/suite_test.go deleted file mode 100644 index 1ef21f902da..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/fiz/suite_test.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2024 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 fiz - -import ( - "context" - "fmt" - "path/filepath" - "runtime" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - fizv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/fiz/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 -var ctx context.Context -var cancel context.CancelFunc - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = fizv1.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()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/foo.policy/healthcheckpolicy_controller.go b/testdata/project-v4-multigroup/internal/controller/foo.policy/healthcheckpolicy_controller.go deleted file mode 100644 index 2d317620dda..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/foo.policy/healthcheckpolicy_controller.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2024 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 foopolicy - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - foopolicyv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo.policy/v1" -) - -// HealthCheckPolicyReconciler reconciles a HealthCheckPolicy object -type HealthCheckPolicyReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=foo.policy.testproject.org,resources=healthcheckpolicies,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=foo.policy.testproject.org,resources=healthcheckpolicies/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=foo.policy.testproject.org,resources=healthcheckpolicies/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 HealthCheckPolicy 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.19.0/pkg/reconcile -func (r *HealthCheckPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *HealthCheckPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&foopolicyv1.HealthCheckPolicy{}). - Named("foo.policy-healthcheckpolicy"). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/foo.policy/healthcheckpolicy_controller_test.go b/testdata/project-v4-multigroup/internal/controller/foo.policy/healthcheckpolicy_controller_test.go deleted file mode 100644 index 55de998a0a2..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/foo.policy/healthcheckpolicy_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2024 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 foopolicy - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - foopolicyv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo.policy/v1" -) - -var _ = Describe("HealthCheckPolicy Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - healthcheckpolicy := &foopolicyv1.HealthCheckPolicy{} - - BeforeEach(func() { - By("creating the custom resource for the Kind HealthCheckPolicy") - err := k8sClient.Get(ctx, typeNamespacedName, healthcheckpolicy) - if err != nil && errors.IsNotFound(err) { - resource := &foopolicyv1.HealthCheckPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &foopolicyv1.HealthCheckPolicy{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance HealthCheckPolicy") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &HealthCheckPolicyReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/foo.policy/suite_test.go b/testdata/project-v4-multigroup/internal/controller/foo.policy/suite_test.go deleted file mode 100644 index a7a3cafc613..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/foo.policy/suite_test.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2024 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 foopolicy - -import ( - "context" - "fmt" - "path/filepath" - "runtime" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - foopolicyv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo.policy/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 -var ctx context.Context -var cancel context.CancelFunc - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = foopolicyv1.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()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/foo/bar_controller.go b/testdata/project-v4-multigroup/internal/controller/foo/bar_controller.go deleted file mode 100644 index 91bf9eff024..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/foo/bar_controller.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2024 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 foo - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - foov1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo/v1" -) - -// BarReconciler reconciles a Bar object -type BarReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=foo.testproject.org,resources=bars,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=foo.testproject.org,resources=bars/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=foo.testproject.org,resources=bars/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 Bar 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.19.0/pkg/reconcile -func (r *BarReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *BarReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&foov1.Bar{}). - Named("foo-bar"). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/foo/bar_controller_test.go b/testdata/project-v4-multigroup/internal/controller/foo/bar_controller_test.go deleted file mode 100644 index 12193854c79..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/foo/bar_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2024 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 foo - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - foov1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo/v1" -) - -var _ = Describe("Bar Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - bar := &foov1.Bar{} - - BeforeEach(func() { - By("creating the custom resource for the Kind Bar") - err := k8sClient.Get(ctx, typeNamespacedName, bar) - if err != nil && errors.IsNotFound(err) { - resource := &foov1.Bar{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &foov1.Bar{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance Bar") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &BarReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/foo/suite_test.go b/testdata/project-v4-multigroup/internal/controller/foo/suite_test.go deleted file mode 100644 index a04113931ba..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/foo/suite_test.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2024 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 foo - -import ( - "context" - "fmt" - "path/filepath" - "runtime" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - foov1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo/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 -var ctx context.Context -var cancel context.CancelFunc - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = foov1.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()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/sea-creatures/kraken_controller.go b/testdata/project-v4-multigroup/internal/controller/sea-creatures/kraken_controller.go deleted file mode 100644 index 0c01e96ab7f..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/sea-creatures/kraken_controller.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2024 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 seacreatures - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - seacreaturesv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta1" -) - -// KrakenReconciler reconciles a Kraken object -type KrakenReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=krakens,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=krakens/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=krakens/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 Kraken 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.19.0/pkg/reconcile -func (r *KrakenReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *KrakenReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&seacreaturesv1beta1.Kraken{}). - Named("sea-creatures-kraken"). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/sea-creatures/kraken_controller_test.go b/testdata/project-v4-multigroup/internal/controller/sea-creatures/kraken_controller_test.go deleted file mode 100644 index b0eae061ff8..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/sea-creatures/kraken_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2024 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 seacreatures - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - seacreaturesv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta1" -) - -var _ = Describe("Kraken Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - kraken := &seacreaturesv1beta1.Kraken{} - - BeforeEach(func() { - By("creating the custom resource for the Kind Kraken") - err := k8sClient.Get(ctx, typeNamespacedName, kraken) - if err != nil && errors.IsNotFound(err) { - resource := &seacreaturesv1beta1.Kraken{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &seacreaturesv1beta1.Kraken{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance Kraken") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &KrakenReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/sea-creatures/leviathan_controller.go b/testdata/project-v4-multigroup/internal/controller/sea-creatures/leviathan_controller.go deleted file mode 100644 index 1a42db100bd..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/sea-creatures/leviathan_controller.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2024 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 seacreatures - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - seacreaturesv1beta2 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta2" -) - -// LeviathanReconciler reconciles a Leviathan object -type LeviathanReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=leviathans,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=leviathans/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=leviathans/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 Leviathan 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.19.0/pkg/reconcile -func (r *LeviathanReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *LeviathanReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&seacreaturesv1beta2.Leviathan{}). - Named("sea-creatures-leviathan"). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/sea-creatures/leviathan_controller_test.go b/testdata/project-v4-multigroup/internal/controller/sea-creatures/leviathan_controller_test.go deleted file mode 100644 index 5b1e491aa89..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/sea-creatures/leviathan_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2024 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 seacreatures - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - seacreaturesv1beta2 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta2" -) - -var _ = Describe("Leviathan Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - leviathan := &seacreaturesv1beta2.Leviathan{} - - BeforeEach(func() { - By("creating the custom resource for the Kind Leviathan") - err := k8sClient.Get(ctx, typeNamespacedName, leviathan) - if err != nil && errors.IsNotFound(err) { - resource := &seacreaturesv1beta2.Leviathan{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &seacreaturesv1beta2.Leviathan{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance Leviathan") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &LeviathanReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/sea-creatures/suite_test.go b/testdata/project-v4-multigroup/internal/controller/sea-creatures/suite_test.go deleted file mode 100644 index d2f44fafbe2..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/sea-creatures/suite_test.go +++ /dev/null @@ -1,100 +0,0 @@ -/* -Copyright 2024 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 seacreatures - -import ( - "context" - "fmt" - "path/filepath" - "runtime" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - seacreaturesv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta1" - seacreaturesv1beta2 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta2" - // +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 -var ctx context.Context -var cancel context.CancelFunc - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = seacreaturesv1beta1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - err = seacreaturesv1beta2.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()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/ship/cruiser_controller.go b/testdata/project-v4-multigroup/internal/controller/ship/cruiser_controller.go deleted file mode 100644 index f8f1bb2c1e3..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/ship/cruiser_controller.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2024 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 ship - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v2alpha1" -) - -// CruiserReconciler reconciles a Cruiser object -type CruiserReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=ship.testproject.org,resources=cruisers,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=ship.testproject.org,resources=cruisers/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=ship.testproject.org,resources=cruisers/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 Cruiser 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.19.0/pkg/reconcile -func (r *CruiserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *CruiserReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&shipv2alpha1.Cruiser{}). - Named("ship-cruiser"). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/ship/cruiser_controller_test.go b/testdata/project-v4-multigroup/internal/controller/ship/cruiser_controller_test.go deleted file mode 100644 index 5d432ab735e..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/ship/cruiser_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2024 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 ship - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v2alpha1" -) - -var _ = Describe("Cruiser Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - cruiser := &shipv2alpha1.Cruiser{} - - BeforeEach(func() { - By("creating the custom resource for the Kind Cruiser") - err := k8sClient.Get(ctx, typeNamespacedName, cruiser) - if err != nil && errors.IsNotFound(err) { - resource := &shipv2alpha1.Cruiser{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &shipv2alpha1.Cruiser{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance Cruiser") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &CruiserReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/ship/destroyer_controller.go b/testdata/project-v4-multigroup/internal/controller/ship/destroyer_controller.go deleted file mode 100644 index ccb1144b6d4..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/ship/destroyer_controller.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2024 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 ship - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - shipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1" -) - -// DestroyerReconciler reconciles a Destroyer object -type DestroyerReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=ship.testproject.org,resources=destroyers,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=ship.testproject.org,resources=destroyers/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=ship.testproject.org,resources=destroyers/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 Destroyer 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.19.0/pkg/reconcile -func (r *DestroyerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *DestroyerReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&shipv1.Destroyer{}). - Named("ship-destroyer"). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/ship/destroyer_controller_test.go b/testdata/project-v4-multigroup/internal/controller/ship/destroyer_controller_test.go deleted file mode 100644 index c1de1afb8b6..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/ship/destroyer_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2024 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 ship - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - shipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1" -) - -var _ = Describe("Destroyer Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - destroyer := &shipv1.Destroyer{} - - BeforeEach(func() { - By("creating the custom resource for the Kind Destroyer") - err := k8sClient.Get(ctx, typeNamespacedName, destroyer) - if err != nil && errors.IsNotFound(err) { - resource := &shipv1.Destroyer{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &shipv1.Destroyer{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance Destroyer") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &DestroyerReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/ship/frigate_controller.go b/testdata/project-v4-multigroup/internal/controller/ship/frigate_controller.go deleted file mode 100644 index a8ee95c5ed4..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/ship/frigate_controller.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2024 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 ship - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - shipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1beta1" -) - -// FrigateReconciler reconciles a Frigate object -type FrigateReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=ship.testproject.org,resources=frigates,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=ship.testproject.org,resources=frigates/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=ship.testproject.org,resources=frigates/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 Frigate 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.19.0/pkg/reconcile -func (r *FrigateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *FrigateReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&shipv1beta1.Frigate{}). - Named("ship-frigate"). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/ship/frigate_controller_test.go b/testdata/project-v4-multigroup/internal/controller/ship/frigate_controller_test.go deleted file mode 100644 index f36a8679754..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/ship/frigate_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2024 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 ship - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - shipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1beta1" -) - -var _ = Describe("Frigate Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - frigate := &shipv1beta1.Frigate{} - - BeforeEach(func() { - By("creating the custom resource for the Kind Frigate") - err := k8sClient.Get(ctx, typeNamespacedName, frigate) - if err != nil && errors.IsNotFound(err) { - resource := &shipv1beta1.Frigate{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &shipv1beta1.Frigate{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance Frigate") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &FrigateReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/ship/suite_test.go b/testdata/project-v4-multigroup/internal/controller/ship/suite_test.go deleted file mode 100644 index a38370a4f56..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/ship/suite_test.go +++ /dev/null @@ -1,104 +0,0 @@ -/* -Copyright 2024 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 ship - -import ( - "context" - "fmt" - "path/filepath" - "runtime" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - shipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1" - shipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1beta1" - shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v2alpha1" - // +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 -var ctx context.Context -var cancel context.CancelFunc - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = shipv1beta1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - err = shipv1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - err = shipv2alpha1.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()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/cert-manager/v1/issuer_webhook.go b/testdata/project-v4-multigroup/internal/webhook/cert-manager/v1/issuer_webhook.go deleted file mode 100644 index 9160e4e89f5..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/cert-manager/v1/issuer_webhook.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 2024 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" - "fmt" - - certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - "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" -) - -// nolint:unused -// log is for logging in this package. -var issuerlog = logf.Log.WithName("issuer-resource") - -// SetupIssuerWebhookWithManager registers the webhook for Issuer in the manager. -func SetupIssuerWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&certmanagerv1.Issuer{}). - WithDefaulter(&IssuerCustomDefaulter{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -// +kubebuilder:webhook:path=/mutate-cert-manager-io-v1-issuer,mutating=true,failurePolicy=fail,sideEffects=None,groups=cert-manager.io,resources=issuers,verbs=create;update,versions=v1,name=missuer-v1.kb.io,admissionReviewVersions=v1 - -// IssuerCustomDefaulter struct is responsible for setting default values on the custom resource of the -// Kind Issuer when those are created or updated. -// -// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, -// as it is used only for temporary operations and does not need to be deeply copied. -type IssuerCustomDefaulter struct { - // TODO(user): Add more fields as needed for defaulting -} - -var _ webhook.CustomDefaulter = &IssuerCustomDefaulter{} - -// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind Issuer. -func (d *IssuerCustomDefaulter) Default(ctx context.Context, obj runtime.Object) error { - issuer, ok := obj.(*certmanagerv1.Issuer) - - if !ok { - return fmt.Errorf("expected an Issuer object but got %T", obj) - } - issuerlog.Info("Defaulting for Issuer", "name", issuer.GetName()) - - // TODO(user): fill in your defaulting logic. - - return nil -} diff --git a/testdata/project-v4-multigroup/internal/webhook/cert-manager/v1/issuer_webhook_test.go b/testdata/project-v4-multigroup/internal/webhook/cert-manager/v1/issuer_webhook_test.go deleted file mode 100644 index b9d0dfeeb23..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/cert-manager/v1/issuer_webhook_test.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2024 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 ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("Issuer Webhook", func() { - var ( - obj *certmanagerv1.Issuer - oldObj *certmanagerv1.Issuer - defaulter IssuerCustomDefaulter - ) - - BeforeEach(func() { - obj = &certmanagerv1.Issuer{} - oldObj = &certmanagerv1.Issuer{} - defaulter = IssuerCustomDefaulter{} - Expect(defaulter).NotTo(BeNil(), "Expected defaulter to be initialized") - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating Issuer under Defaulting Webhook", func() { - // TODO (user): Add logic for defaulting webhooks - // Example: - // It("Should apply defaults when a required field is empty", func() { - // By("simulating a scenario where defaults should be applied") - // obj.SomeFieldWithDefault = "" - // By("calling the Default method to apply defaults") - // defaulter.Default(ctx, obj) - // By("checking that the default values are set") - // Expect(obj.SomeFieldWithDefault).To(Equal("default_value")) - // }) - }) - -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/cert-manager/v1/webhook_suite_test.go b/testdata/project-v4-multigroup/internal/webhook/cert-manager/v1/webhook_suite_test.go deleted file mode 100644 index cd99fe28462..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/cert-manager/v1/webhook_suite_test.go +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright 2024 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" - "runtime" - "testing" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - admissionv1 "k8s.io/api/admission/v1" - - // +kubebuilder:scaffold:imports - apimachineryruntime "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var ( - cancel context.CancelFunc - cfg *rest.Config - ctx context.Context - k8sClient client.Client - testEnv *envtest.Environment -) - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Webhook Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - - WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("..", "..", "..", "..", "config", "webhook")}, - }, - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := apimachineryruntime.NewScheme() - err = certmanagerv1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = admissionv1.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, - WebhookServer: webhook.NewServer(webhook.Options{ - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - }), - LeaderElection: false, - Metrics: metricsserver.Options{BindAddress: "0"}, - }) - Expect(err).NotTo(HaveOccurred()) - - err = SetupIssuerWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() - - // wait for the webhook server to get ready. - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - - return conn.Close() - }).Should(Succeed()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/core/v1/pod_webhook.go b/testdata/project-v4-multigroup/internal/webhook/core/v1/pod_webhook.go deleted file mode 100644 index 125c4afdcfe..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/core/v1/pod_webhook.go +++ /dev/null @@ -1,97 +0,0 @@ -/* -Copyright 2024 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" - "fmt" - - corev1 "k8s.io/api/core/v1" - "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" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -// nolint:unused -// log is for logging in this package. -var podlog = logf.Log.WithName("pod-resource") - -// SetupPodWebhookWithManager registers the webhook for Pod in the manager. -func SetupPodWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&corev1.Pod{}). - WithValidator(&PodCustomValidator{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. -// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. -// +kubebuilder:webhook:path=/validate--v1-pod,mutating=false,failurePolicy=fail,sideEffects=None,groups="",resources=pods,verbs=create;update,versions=v1,name=vpod-v1.kb.io,admissionReviewVersions=v1 - -// PodCustomValidator struct is responsible for validating the Pod resource -// when it is created, updated, or deleted. -// -// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, -// as this struct is used only for temporary operations and does not need to be deeply copied. -type PodCustomValidator struct { - //TODO(user): Add more fields as needed for validation -} - -var _ webhook.CustomValidator = &PodCustomValidator{} - -// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type Pod. -func (v *PodCustomValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - pod, ok := obj.(*corev1.Pod) - if !ok { - return nil, fmt.Errorf("expected a Pod object but got %T", obj) - } - podlog.Info("Validation for Pod upon creation", "name", pod.GetName()) - - // TODO(user): fill in your validation logic upon object creation. - - return nil, nil -} - -// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type Pod. -func (v *PodCustomValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { - pod, ok := newObj.(*corev1.Pod) - if !ok { - return nil, fmt.Errorf("expected a Pod object for the newObj but got %T", newObj) - } - podlog.Info("Validation for Pod upon update", "name", pod.GetName()) - - // TODO(user): fill in your validation logic upon object update. - - return nil, nil -} - -// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type Pod. -func (v *PodCustomValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - pod, ok := obj.(*corev1.Pod) - if !ok { - return nil, fmt.Errorf("expected a Pod object but got %T", obj) - } - podlog.Info("Validation for Pod upon deletion", "name", pod.GetName()) - - // TODO(user): fill in your validation logic upon object deletion. - - return nil, nil -} diff --git a/testdata/project-v4-multigroup/internal/webhook/core/v1/pod_webhook_test.go b/testdata/project-v4-multigroup/internal/webhook/core/v1/pod_webhook_test.go deleted file mode 100644 index 588a28131e9..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/core/v1/pod_webhook_test.go +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 2024 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 ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - corev1 "k8s.io/api/core/v1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("Pod Webhook", func() { - var ( - obj *corev1.Pod - oldObj *corev1.Pod - validator PodCustomValidator - ) - - BeforeEach(func() { - obj = &corev1.Pod{} - oldObj = &corev1.Pod{} - validator = PodCustomValidator{} - Expect(validator).NotTo(BeNil(), "Expected validator to be initialized") - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating or updating Pod under Validating Webhook", func() { - // TODO (user): Add logic for validating webhooks - // Example: - // It("Should deny creation if a required field is missing", func() { - // By("simulating an invalid creation scenario") - // obj.SomeRequiredField = "" - // Expect(validator.ValidateCreate(ctx, obj)).Error().To(HaveOccurred()) - // }) - // - // It("Should admit creation if all required fields are present", func() { - // By("simulating an invalid creation scenario") - // obj.SomeRequiredField = "valid_value" - // Expect(validator.ValidateCreate(ctx, obj)).To(BeNil()) - // }) - // - // It("Should validate updates correctly", func() { - // By("simulating a valid update scenario") - // oldObj.SomeRequiredField = "updated_value" - // obj.SomeRequiredField = "updated_value" - // Expect(validator.ValidateUpdate(ctx, oldObj, obj)).To(BeNil()) - // }) - }) - -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/core/v1/webhook_suite_test.go b/testdata/project-v4-multigroup/internal/webhook/core/v1/webhook_suite_test.go deleted file mode 100644 index c6fcf0ebb14..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/core/v1/webhook_suite_test.go +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright 2024 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" - "runtime" - "testing" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - admissionv1 "k8s.io/api/admission/v1" - corev1 "k8s.io/api/core/v1" - - // +kubebuilder:scaffold:imports - apimachineryruntime "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var ( - cancel context.CancelFunc - cfg *rest.Config - ctx context.Context - k8sClient client.Client - testEnv *envtest.Environment -) - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Webhook Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - - WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("..", "..", "..", "..", "config", "webhook")}, - }, - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := apimachineryruntime.NewScheme() - err = corev1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = admissionv1.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, - WebhookServer: webhook.NewServer(webhook.Options{ - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - }), - LeaderElection: false, - Metrics: metricsserver.Options{BindAddress: "0"}, - }) - Expect(err).NotTo(HaveOccurred()) - - err = SetupPodWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() - - // wait for the webhook server to get ready. - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - - return conn.Close() - }).Should(Succeed()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/crew/v1/captain_webhook.go b/testdata/project-v4-multigroup/internal/webhook/crew/v1/captain_webhook.go deleted file mode 100644 index 5ff17553be1..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/crew/v1/captain_webhook.go +++ /dev/null @@ -1,126 +0,0 @@ -/* -Copyright 2024 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" - "fmt" - - "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" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/crew/v1" -) - -// nolint:unused -// log is for logging in this package. -var captainlog = logf.Log.WithName("captain-resource") - -// SetupCaptainWebhookWithManager registers the webhook for Captain in the manager. -func SetupCaptainWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&crewv1.Captain{}). - WithValidator(&CaptainCustomValidator{}). - WithDefaulter(&CaptainCustomDefaulter{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -// +kubebuilder:webhook:path=/mutate-crew-testproject-org-v1-captain,mutating=true,failurePolicy=fail,sideEffects=None,groups=crew.testproject.org,resources=captains,verbs=create;update,versions=v1,name=mcaptain-v1.kb.io,admissionReviewVersions=v1 - -// CaptainCustomDefaulter struct is responsible for setting default values on the custom resource of the -// Kind Captain when those are created or updated. -// -// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, -// as it is used only for temporary operations and does not need to be deeply copied. -type CaptainCustomDefaulter struct { - // TODO(user): Add more fields as needed for defaulting -} - -var _ webhook.CustomDefaulter = &CaptainCustomDefaulter{} - -// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind Captain. -func (d *CaptainCustomDefaulter) Default(ctx context.Context, obj runtime.Object) error { - captain, ok := obj.(*crewv1.Captain) - - if !ok { - return fmt.Errorf("expected an Captain object but got %T", obj) - } - captainlog.Info("Defaulting for Captain", "name", captain.GetName()) - - // TODO(user): fill in your defaulting logic. - - return nil -} - -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. -// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. -// +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-v1.kb.io,admissionReviewVersions=v1 - -// CaptainCustomValidator struct is responsible for validating the Captain resource -// when it is created, updated, or deleted. -// -// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, -// as this struct is used only for temporary operations and does not need to be deeply copied. -type CaptainCustomValidator struct { - //TODO(user): Add more fields as needed for validation -} - -var _ webhook.CustomValidator = &CaptainCustomValidator{} - -// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type Captain. -func (v *CaptainCustomValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - captain, ok := obj.(*crewv1.Captain) - if !ok { - return nil, fmt.Errorf("expected a Captain object but got %T", obj) - } - captainlog.Info("Validation for Captain upon creation", "name", captain.GetName()) - - // TODO(user): fill in your validation logic upon object creation. - - return nil, nil -} - -// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type Captain. -func (v *CaptainCustomValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { - captain, ok := newObj.(*crewv1.Captain) - if !ok { - return nil, fmt.Errorf("expected a Captain object for the newObj but got %T", newObj) - } - captainlog.Info("Validation for Captain upon update", "name", captain.GetName()) - - // TODO(user): fill in your validation logic upon object update. - - return nil, nil -} - -// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type Captain. -func (v *CaptainCustomValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - captain, ok := obj.(*crewv1.Captain) - if !ok { - return nil, fmt.Errorf("expected a Captain object but got %T", obj) - } - captainlog.Info("Validation for Captain upon deletion", "name", captain.GetName()) - - // TODO(user): fill in your validation logic upon object deletion. - - return nil, nil -} diff --git a/testdata/project-v4-multigroup/internal/webhook/crew/v1/captain_webhook_test.go b/testdata/project-v4-multigroup/internal/webhook/crew/v1/captain_webhook_test.go deleted file mode 100644 index f0e160eeb3c..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/crew/v1/captain_webhook_test.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2024 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 ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/crew/v1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("Captain Webhook", func() { - var ( - obj *crewv1.Captain - oldObj *crewv1.Captain - validator CaptainCustomValidator - defaulter CaptainCustomDefaulter - ) - - BeforeEach(func() { - obj = &crewv1.Captain{} - oldObj = &crewv1.Captain{} - validator = CaptainCustomValidator{} - Expect(validator).NotTo(BeNil(), "Expected validator to be initialized") - defaulter = CaptainCustomDefaulter{} - Expect(defaulter).NotTo(BeNil(), "Expected defaulter to be initialized") - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating Captain under Defaulting Webhook", func() { - // TODO (user): Add logic for defaulting webhooks - // Example: - // It("Should apply defaults when a required field is empty", func() { - // By("simulating a scenario where defaults should be applied") - // obj.SomeFieldWithDefault = "" - // By("calling the Default method to apply defaults") - // defaulter.Default(ctx, obj) - // By("checking that the default values are set") - // Expect(obj.SomeFieldWithDefault).To(Equal("default_value")) - // }) - }) - - Context("When creating or updating Captain under Validating Webhook", func() { - // TODO (user): Add logic for validating webhooks - // Example: - // It("Should deny creation if a required field is missing", func() { - // By("simulating an invalid creation scenario") - // obj.SomeRequiredField = "" - // Expect(validator.ValidateCreate(ctx, obj)).Error().To(HaveOccurred()) - // }) - // - // It("Should admit creation if all required fields are present", func() { - // By("simulating an invalid creation scenario") - // obj.SomeRequiredField = "valid_value" - // Expect(validator.ValidateCreate(ctx, obj)).To(BeNil()) - // }) - // - // It("Should validate updates correctly", func() { - // By("simulating a valid update scenario") - // oldObj.SomeRequiredField = "updated_value" - // obj.SomeRequiredField = "updated_value" - // Expect(validator.ValidateUpdate(ctx, oldObj, obj)).To(BeNil()) - // }) - }) - -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/crew/v1/webhook_suite_test.go b/testdata/project-v4-multigroup/internal/webhook/crew/v1/webhook_suite_test.go deleted file mode 100644 index 21e07938ca4..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/crew/v1/webhook_suite_test.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 2024 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" - "runtime" - "testing" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - admissionv1 "k8s.io/api/admission/v1" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/crew/v1" - - // +kubebuilder:scaffold:imports - apimachineryruntime "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var ( - cancel context.CancelFunc - cfg *rest.Config - ctx context.Context - k8sClient client.Client - testEnv *envtest.Environment -) - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Webhook Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - - WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("..", "..", "..", "..", "config", "webhook")}, - }, - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := apimachineryruntime.NewScheme() - err = crewv1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = admissionv1.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, - WebhookServer: webhook.NewServer(webhook.Options{ - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - }), - LeaderElection: false, - Metrics: metricsserver.Options{BindAddress: "0"}, - }) - Expect(err).NotTo(HaveOccurred()) - - err = SetupCaptainWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() - - // wait for the webhook server to get ready. - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - - return conn.Close() - }).Should(Succeed()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/example.com/v1alpha1/memcached_webhook.go b/testdata/project-v4-multigroup/internal/webhook/example.com/v1alpha1/memcached_webhook.go deleted file mode 100644 index e004affa05f..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/example.com/v1alpha1/memcached_webhook.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 - -import ( - "context" - "fmt" - - "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" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" -) - -// nolint:unused -// log is for logging in this package. -var memcachedlog = logf.Log.WithName("memcached-resource") - -// SetupMemcachedWebhookWithManager registers the webhook for Memcached in the manager. -func SetupMemcachedWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&examplecomv1alpha1.Memcached{}). - WithValidator(&MemcachedCustomValidator{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. -// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. -// +kubebuilder:webhook:path=/validate-example-com-testproject-org-v1alpha1-memcached,mutating=false,failurePolicy=fail,sideEffects=None,groups=example.com.testproject.org,resources=memcacheds,verbs=create;update,versions=v1alpha1,name=vmemcached-v1alpha1.kb.io,admissionReviewVersions=v1 - -// MemcachedCustomValidator struct is responsible for validating the Memcached resource -// when it is created, updated, or deleted. -// -// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, -// as this struct is used only for temporary operations and does not need to be deeply copied. -type MemcachedCustomValidator struct { - //TODO(user): Add more fields as needed for validation -} - -var _ webhook.CustomValidator = &MemcachedCustomValidator{} - -// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type Memcached. -func (v *MemcachedCustomValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - memcached, ok := obj.(*examplecomv1alpha1.Memcached) - if !ok { - return nil, fmt.Errorf("expected a Memcached object but got %T", obj) - } - memcachedlog.Info("Validation for Memcached upon creation", "name", memcached.GetName()) - - // TODO(user): fill in your validation logic upon object creation. - - return nil, nil -} - -// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type Memcached. -func (v *MemcachedCustomValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { - memcached, ok := newObj.(*examplecomv1alpha1.Memcached) - if !ok { - return nil, fmt.Errorf("expected a Memcached object for the newObj but got %T", newObj) - } - memcachedlog.Info("Validation for Memcached upon update", "name", memcached.GetName()) - - // TODO(user): fill in your validation logic upon object update. - - return nil, nil -} - -// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type Memcached. -func (v *MemcachedCustomValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - memcached, ok := obj.(*examplecomv1alpha1.Memcached) - if !ok { - return nil, fmt.Errorf("expected a Memcached object but got %T", obj) - } - memcachedlog.Info("Validation for Memcached upon deletion", "name", memcached.GetName()) - - // TODO(user): fill in your validation logic upon object deletion. - - return nil, nil -} diff --git a/testdata/project-v4-multigroup/internal/webhook/example.com/v1alpha1/memcached_webhook_test.go b/testdata/project-v4-multigroup/internal/webhook/example.com/v1alpha1/memcached_webhook_test.go deleted file mode 100644 index 2ca29f87576..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/example.com/v1alpha1/memcached_webhook_test.go +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("Memcached Webhook", func() { - var ( - obj *examplecomv1alpha1.Memcached - oldObj *examplecomv1alpha1.Memcached - validator MemcachedCustomValidator - ) - - BeforeEach(func() { - obj = &examplecomv1alpha1.Memcached{} - oldObj = &examplecomv1alpha1.Memcached{} - validator = MemcachedCustomValidator{} - Expect(validator).NotTo(BeNil(), "Expected validator to be initialized") - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating or updating Memcached under Validating Webhook", func() { - // TODO (user): Add logic for validating webhooks - // Example: - // It("Should deny creation if a required field is missing", func() { - // By("simulating an invalid creation scenario") - // obj.SomeRequiredField = "" - // Expect(validator.ValidateCreate(ctx, obj)).Error().To(HaveOccurred()) - // }) - // - // It("Should admit creation if all required fields are present", func() { - // By("simulating an invalid creation scenario") - // obj.SomeRequiredField = "valid_value" - // Expect(validator.ValidateCreate(ctx, obj)).To(BeNil()) - // }) - // - // It("Should validate updates correctly", func() { - // By("simulating a valid update scenario") - // oldObj.SomeRequiredField = "updated_value" - // obj.SomeRequiredField = "updated_value" - // Expect(validator.ValidateUpdate(ctx, oldObj, obj)).To(BeNil()) - // }) - }) - -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/example.com/v1alpha1/webhook_suite_test.go b/testdata/project-v4-multigroup/internal/webhook/example.com/v1alpha1/webhook_suite_test.go deleted file mode 100644 index 18d7d16a186..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/example.com/v1alpha1/webhook_suite_test.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 - -import ( - "context" - "crypto/tls" - "fmt" - "net" - "path/filepath" - "runtime" - "testing" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - admissionv1 "k8s.io/api/admission/v1" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" - - // +kubebuilder:scaffold:imports - apimachineryruntime "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var ( - cancel context.CancelFunc - cfg *rest.Config - ctx context.Context - k8sClient client.Client - testEnv *envtest.Environment -) - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Webhook Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - - WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("..", "..", "..", "..", "config", "webhook")}, - }, - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := apimachineryruntime.NewScheme() - err = examplecomv1alpha1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = admissionv1.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, - WebhookServer: webhook.NewServer(webhook.Options{ - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - }), - LeaderElection: false, - Metrics: metricsserver.Options{BindAddress: "0"}, - }) - Expect(err).NotTo(HaveOccurred()) - - err = SetupMemcachedWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() - - // wait for the webhook server to get ready. - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - - return conn.Close() - }).Should(Succeed()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/ship/v1/destroyer_webhook.go b/testdata/project-v4-multigroup/internal/webhook/ship/v1/destroyer_webhook.go deleted file mode 100644 index 37711b210f0..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/ship/v1/destroyer_webhook.go +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright 2024 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" - "fmt" - - "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" - - shipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1" -) - -// nolint:unused -// log is for logging in this package. -var destroyerlog = logf.Log.WithName("destroyer-resource") - -// SetupDestroyerWebhookWithManager registers the webhook for Destroyer in the manager. -func SetupDestroyerWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&shipv1.Destroyer{}). - WithDefaulter(&DestroyerCustomDefaulter{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -// +kubebuilder:webhook:path=/mutate-ship-testproject-org-v1-destroyer,mutating=true,failurePolicy=fail,sideEffects=None,groups=ship.testproject.org,resources=destroyers,verbs=create;update,versions=v1,name=mdestroyer-v1.kb.io,admissionReviewVersions=v1 - -// DestroyerCustomDefaulter struct is responsible for setting default values on the custom resource of the -// Kind Destroyer when those are created or updated. -// -// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, -// as it is used only for temporary operations and does not need to be deeply copied. -type DestroyerCustomDefaulter struct { - // TODO(user): Add more fields as needed for defaulting -} - -var _ webhook.CustomDefaulter = &DestroyerCustomDefaulter{} - -// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind Destroyer. -func (d *DestroyerCustomDefaulter) Default(ctx context.Context, obj runtime.Object) error { - destroyer, ok := obj.(*shipv1.Destroyer) - - if !ok { - return fmt.Errorf("expected an Destroyer object but got %T", obj) - } - destroyerlog.Info("Defaulting for Destroyer", "name", destroyer.GetName()) - - // TODO(user): fill in your defaulting logic. - - return nil -} diff --git a/testdata/project-v4-multigroup/internal/webhook/ship/v1/destroyer_webhook_test.go b/testdata/project-v4-multigroup/internal/webhook/ship/v1/destroyer_webhook_test.go deleted file mode 100644 index 22d950d5092..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/ship/v1/destroyer_webhook_test.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2024 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 ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - shipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("Destroyer Webhook", func() { - var ( - obj *shipv1.Destroyer - oldObj *shipv1.Destroyer - defaulter DestroyerCustomDefaulter - ) - - BeforeEach(func() { - obj = &shipv1.Destroyer{} - oldObj = &shipv1.Destroyer{} - defaulter = DestroyerCustomDefaulter{} - Expect(defaulter).NotTo(BeNil(), "Expected defaulter to be initialized") - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating Destroyer under Defaulting Webhook", func() { - // TODO (user): Add logic for defaulting webhooks - // Example: - // It("Should apply defaults when a required field is empty", func() { - // By("simulating a scenario where defaults should be applied") - // obj.SomeFieldWithDefault = "" - // By("calling the Default method to apply defaults") - // defaulter.Default(ctx, obj) - // By("checking that the default values are set") - // Expect(obj.SomeFieldWithDefault).To(Equal("default_value")) - // }) - }) - -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/ship/v1/webhook_suite_test.go b/testdata/project-v4-multigroup/internal/webhook/ship/v1/webhook_suite_test.go deleted file mode 100644 index 251f78b63fe..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/ship/v1/webhook_suite_test.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 2024 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" - "runtime" - "testing" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - admissionv1 "k8s.io/api/admission/v1" - - shipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1" - - // +kubebuilder:scaffold:imports - apimachineryruntime "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var ( - cancel context.CancelFunc - cfg *rest.Config - ctx context.Context - k8sClient client.Client - testEnv *envtest.Environment -) - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Webhook Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - - WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("..", "..", "..", "..", "config", "webhook")}, - }, - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := apimachineryruntime.NewScheme() - err = shipv1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = admissionv1.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, - WebhookServer: webhook.NewServer(webhook.Options{ - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - }), - LeaderElection: false, - Metrics: metricsserver.Options{BindAddress: "0"}, - }) - Expect(err).NotTo(HaveOccurred()) - - err = SetupDestroyerWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() - - // wait for the webhook server to get ready. - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - - return conn.Close() - }).Should(Succeed()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/ship/v1beta1/frigate_webhook.go b/testdata/project-v4-multigroup/internal/webhook/ship/v1beta1/frigate_webhook.go deleted file mode 100644 index 90b5342fa05..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/ship/v1beta1/frigate_webhook.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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 v1beta1 - -import ( - ctrl "sigs.k8s.io/controller-runtime" - logf "sigs.k8s.io/controller-runtime/pkg/log" - - shipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1beta1" -) - -// nolint:unused -// log is for logging in this package. -var frigatelog = logf.Log.WithName("frigate-resource") - -// SetupFrigateWebhookWithManager registers the webhook for Frigate in the manager. -func SetupFrigateWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&shipv1beta1.Frigate{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! diff --git a/testdata/project-v4-multigroup/internal/webhook/ship/v1beta1/frigate_webhook_test.go b/testdata/project-v4-multigroup/internal/webhook/ship/v1beta1/frigate_webhook_test.go deleted file mode 100644 index 1882c0df82c..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/ship/v1beta1/frigate_webhook_test.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2024 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 v1beta1 - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - shipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v1beta1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("Frigate Webhook", func() { - var ( - obj *shipv1beta1.Frigate - oldObj *shipv1beta1.Frigate - ) - - BeforeEach(func() { - obj = &shipv1beta1.Frigate{} - oldObj = &shipv1beta1.Frigate{} - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating Frigate under Conversion Webhook", func() { - // TODO (user): Add logic to convert the object to the desired version and verify the conversion - // Example: - // It("Should convert the object correctly", func() { - // convertedObj := &shipv1beta1.Frigate{} - // Expect(obj.ConvertTo(convertedObj)).To(Succeed()) - // Expect(convertedObj).ToNot(BeNil()) - // }) - }) - -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/ship/v2alpha1/cruiser_webhook.go b/testdata/project-v4-multigroup/internal/webhook/ship/v2alpha1/cruiser_webhook.go deleted file mode 100644 index 8637e993b4c..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/ship/v2alpha1/cruiser_webhook.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -Copyright 2024 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 v2alpha1 - -import ( - "context" - "fmt" - - "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" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - - shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v2alpha1" -) - -// nolint:unused -// log is for logging in this package. -var cruiserlog = logf.Log.WithName("cruiser-resource") - -// SetupCruiserWebhookWithManager registers the webhook for Cruiser in the manager. -func SetupCruiserWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&shipv2alpha1.Cruiser{}). - WithValidator(&CruiserCustomValidator{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. -// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. -// +kubebuilder:webhook:path=/validate-ship-testproject-org-v2alpha1-cruiser,mutating=false,failurePolicy=fail,sideEffects=None,groups=ship.testproject.org,resources=cruisers,verbs=create;update,versions=v2alpha1,name=vcruiser-v2alpha1.kb.io,admissionReviewVersions=v1 - -// CruiserCustomValidator struct is responsible for validating the Cruiser resource -// when it is created, updated, or deleted. -// -// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, -// as this struct is used only for temporary operations and does not need to be deeply copied. -type CruiserCustomValidator struct { - //TODO(user): Add more fields as needed for validation -} - -var _ webhook.CustomValidator = &CruiserCustomValidator{} - -// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type Cruiser. -func (v *CruiserCustomValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - cruiser, ok := obj.(*shipv2alpha1.Cruiser) - if !ok { - return nil, fmt.Errorf("expected a Cruiser object but got %T", obj) - } - cruiserlog.Info("Validation for Cruiser upon creation", "name", cruiser.GetName()) - - // TODO(user): fill in your validation logic upon object creation. - - return nil, nil -} - -// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type Cruiser. -func (v *CruiserCustomValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { - cruiser, ok := newObj.(*shipv2alpha1.Cruiser) - if !ok { - return nil, fmt.Errorf("expected a Cruiser object for the newObj but got %T", newObj) - } - cruiserlog.Info("Validation for Cruiser upon update", "name", cruiser.GetName()) - - // TODO(user): fill in your validation logic upon object update. - - return nil, nil -} - -// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type Cruiser. -func (v *CruiserCustomValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - cruiser, ok := obj.(*shipv2alpha1.Cruiser) - if !ok { - return nil, fmt.Errorf("expected a Cruiser object but got %T", obj) - } - cruiserlog.Info("Validation for Cruiser upon deletion", "name", cruiser.GetName()) - - // TODO(user): fill in your validation logic upon object deletion. - - return nil, nil -} diff --git a/testdata/project-v4-multigroup/internal/webhook/ship/v2alpha1/cruiser_webhook_test.go b/testdata/project-v4-multigroup/internal/webhook/ship/v2alpha1/cruiser_webhook_test.go deleted file mode 100644 index 2779cdc4fa6..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/ship/v2alpha1/cruiser_webhook_test.go +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 2024 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 v2alpha1 - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v2alpha1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("Cruiser Webhook", func() { - var ( - obj *shipv2alpha1.Cruiser - oldObj *shipv2alpha1.Cruiser - validator CruiserCustomValidator - ) - - BeforeEach(func() { - obj = &shipv2alpha1.Cruiser{} - oldObj = &shipv2alpha1.Cruiser{} - validator = CruiserCustomValidator{} - Expect(validator).NotTo(BeNil(), "Expected validator to be initialized") - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating or updating Cruiser under Validating Webhook", func() { - // TODO (user): Add logic for validating webhooks - // Example: - // It("Should deny creation if a required field is missing", func() { - // By("simulating an invalid creation scenario") - // obj.SomeRequiredField = "" - // Expect(validator.ValidateCreate(ctx, obj)).Error().To(HaveOccurred()) - // }) - // - // It("Should admit creation if all required fields are present", func() { - // By("simulating an invalid creation scenario") - // obj.SomeRequiredField = "valid_value" - // Expect(validator.ValidateCreate(ctx, obj)).To(BeNil()) - // }) - // - // It("Should validate updates correctly", func() { - // By("simulating a valid update scenario") - // oldObj.SomeRequiredField = "updated_value" - // obj.SomeRequiredField = "updated_value" - // Expect(validator.ValidateUpdate(ctx, oldObj, obj)).To(BeNil()) - // }) - }) - -}) diff --git a/testdata/project-v4-multigroup/internal/webhook/ship/v2alpha1/webhook_suite_test.go b/testdata/project-v4-multigroup/internal/webhook/ship/v2alpha1/webhook_suite_test.go deleted file mode 100644 index 22fe9423793..00000000000 --- a/testdata/project-v4-multigroup/internal/webhook/ship/v2alpha1/webhook_suite_test.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 2024 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 v2alpha1 - -import ( - "context" - "crypto/tls" - "fmt" - "net" - "path/filepath" - "runtime" - "testing" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - admissionv1 "k8s.io/api/admission/v1" - - shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/ship/v2alpha1" - - // +kubebuilder:scaffold:imports - apimachineryruntime "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var ( - cancel context.CancelFunc - cfg *rest.Config - ctx context.Context - k8sClient client.Client - testEnv *envtest.Environment -) - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Webhook Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - - WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("..", "..", "..", "..", "config", "webhook")}, - }, - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := apimachineryruntime.NewScheme() - err = shipv2alpha1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = admissionv1.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, - WebhookServer: webhook.NewServer(webhook.Options{ - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - }), - LeaderElection: false, - Metrics: metricsserver.Options{BindAddress: "0"}, - }) - Expect(err).NotTo(HaveOccurred()) - - err = SetupCruiserWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() - - // wait for the webhook server to get ready. - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - - return conn.Close() - }).Should(Succeed()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-multigroup/test/e2e/e2e_suite_test.go b/testdata/project-v4-multigroup/test/e2e/e2e_suite_test.go deleted file mode 100644 index be68fdc2df9..00000000000 --- a/testdata/project-v4-multigroup/test/e2e/e2e_suite_test.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright 2024 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 e2e - -import ( - "fmt" - "os" - "os/exec" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/test/utils" -) - -var ( - // Optional Environment Variables: - // - PROMETHEUS_INSTALL_SKIP=true: Skips Prometheus Operator installation during test setup. - // - CERT_MANAGER_INSTALL_SKIP=true: Skips CertManager installation during test setup. - // These variables are useful if Prometheus or CertManager is already installed, avoiding - // re-installation and conflicts. - skipPrometheusInstall = os.Getenv("PROMETHEUS_INSTALL_SKIP") == "true" - skipCertManagerInstall = os.Getenv("CERT_MANAGER_INSTALL_SKIP") == "true" - // isPrometheusOperatorAlreadyInstalled will be set true when prometheus CRDs be found on the cluster - isPrometheusOperatorAlreadyInstalled = false - // isCertManagerAlreadyInstalled will be set true when CertManager CRDs be found on the cluster - isCertManagerAlreadyInstalled = false - - // projectImage is the name of the image which will be build and loaded - // with the code source changes to be tested. - projectImage = "example.com/project-v4-multigroup:v0.0.1" -) - -// TestE2E runs the end-to-end (e2e) test suite for the project. These tests execute in an isolated, -// temporary environment to validate project changes with the the purposed to be used in CI jobs. -// The default setup requires Kind, builds/loads the Manager Docker image locally, and installs -// CertManager and Prometheus. -func TestE2E(t *testing.T) { - RegisterFailHandler(Fail) - _, _ = fmt.Fprintf(GinkgoWriter, "Starting project-v4-multigroup integration test suite\n") - RunSpecs(t, "e2e suite") -} - -var _ = BeforeSuite(func() { - By("Ensure that Prometheus is enabled") - _ = utils.UncommentCode("config/default/kustomization.yaml", "#- ../prometheus", "#") - - By("generating files") - cmd := exec.Command("make", "generate") - _, err := utils.Run(cmd) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to run make generate") - - By("generating manifests") - cmd = exec.Command("make", "manifests") - _, err = utils.Run(cmd) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to run make manifests") - - By("building the manager(Operator) image") - cmd = exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectImage)) - _, err = utils.Run(cmd) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to build the manager(Operator) image") - - // TODO(user): If you want to change the e2e test vendor from Kind, ensure the image is - // built and available before running the tests. Also, remove the following block. - By("loading the manager(Operator) image on Kind") - err = utils.LoadImageToKindClusterWithName(projectImage) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to load the manager(Operator) image into Kind") - - // The tests-e2e are intended to run on a temporary cluster that is created and destroyed for testing. - // To prevent errors when tests run in environments with Prometheus or CertManager already installed, - // we check for their presence before execution. - // Setup Prometheus and CertManager before the suite if not skipped and if not already installed - if !skipPrometheusInstall { - By("checking if prometheus is installed already") - isPrometheusOperatorAlreadyInstalled = utils.IsPrometheusCRDsInstalled() - if !isPrometheusOperatorAlreadyInstalled { - _, _ = fmt.Fprintf(GinkgoWriter, "Installing Prometheus Operator...\n") - Expect(utils.InstallPrometheusOperator()).To(Succeed(), "Failed to install Prometheus Operator") - } else { - _, _ = fmt.Fprintf(GinkgoWriter, "WARNING: Prometheus Operator is already installed. Skipping installation...\n") - } - } - if !skipCertManagerInstall { - By("checking if cert manager is installed already") - isCertManagerAlreadyInstalled = utils.IsCertManagerCRDsInstalled() - if !isCertManagerAlreadyInstalled { - _, _ = fmt.Fprintf(GinkgoWriter, "Installing CertManager...\n") - Expect(utils.InstallCertManager()).To(Succeed(), "Failed to install CertManager") - } else { - _, _ = fmt.Fprintf(GinkgoWriter, "WARNING: CertManager is already installed. Skipping installation...\n") - } - } -}) - -var _ = AfterSuite(func() { - // Teardown Prometheus and CertManager after the suite if not skipped and if they were not already installed - if !skipPrometheusInstall && !isPrometheusOperatorAlreadyInstalled { - _, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling Prometheus Operator...\n") - utils.UninstallPrometheusOperator() - } - if !skipCertManagerInstall && !isCertManagerAlreadyInstalled { - _, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling CertManager...\n") - utils.UninstallCertManager() - } -}) diff --git a/testdata/project-v4-multigroup/test/e2e/e2e_test.go b/testdata/project-v4-multigroup/test/e2e/e2e_test.go deleted file mode 100644 index b6aae66a78d..00000000000 --- a/testdata/project-v4-multigroup/test/e2e/e2e_test.go +++ /dev/null @@ -1,345 +0,0 @@ -/* -Copyright 2024 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 e2e - -import ( - "encoding/json" - "fmt" - "os" - "os/exec" - "path/filepath" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/test/utils" -) - -// namespace where the project is deployed in -const namespace = "project-v4-multigroup-system" - -// serviceAccountName created for the project -const serviceAccountName = "project-v4-multigroup-controller-manager" - -// metricsServiceName is the name of the metrics service of the project -const metricsServiceName = "project-v4-multigroup-controller-manager-metrics-service" - -// metricsRoleBindingName is the name of the RBAC that will be created to allow get the metrics data -const metricsRoleBindingName = "project-v4-multigroup-metrics-binding" - -var _ = Describe("Manager", Ordered, func() { - var controllerPodName string - - // Before running the tests, set up the environment by creating the namespace, - // installing CRDs, and deploying the controller. - BeforeAll(func() { - By("creating manager namespace") - cmd := exec.Command("kubectl", "create", "ns", namespace) - _, err := utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to create namespace") - - By("installing CRDs") - cmd = exec.Command("make", "install") - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to install CRDs") - - By("deploying the controller-manager") - cmd = exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", projectImage)) - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to deploy the controller-manager") - }) - - // After all tests have been executed, clean up by undeploying the controller, uninstalling CRDs, - // and deleting the namespace. - AfterAll(func() { - By("cleaning up the curl pod for metrics") - cmd := exec.Command("kubectl", "delete", "pod", "curl-metrics", "-n", namespace) - _, _ = utils.Run(cmd) - - By("undeploying the controller-manager") - cmd = exec.Command("make", "undeploy") - _, _ = utils.Run(cmd) - - By("uninstalling CRDs") - cmd = exec.Command("make", "uninstall") - _, _ = utils.Run(cmd) - - By("removing manager namespace") - cmd = exec.Command("kubectl", "delete", "ns", namespace) - _, _ = utils.Run(cmd) - }) - - // After each test, check for failures and collect logs, events, - // and pod descriptions for debugging. - AfterEach(func() { - specReport := CurrentSpecReport() - if specReport.Failed() { - By("Fetching controller manager pod logs") - cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace) - controllerLogs, err := utils.Run(cmd) - if err == nil { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Controller logs:\n %s", controllerLogs)) - } else { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get Controller logs: %s", err)) - } - - By("Fetching Kubernetes events") - cmd = exec.Command("kubectl", "get", "events", "-n", namespace, "--sort-by=.lastTimestamp") - eventsOutput, err := utils.Run(cmd) - if err == nil { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Kubernetes events:\n%s", eventsOutput)) - } else { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get Kubernetes events: %s", err)) - } - - By("Fetching curl-metrics logs") - cmd = exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace) - metricsOutput, err := utils.Run(cmd) - if err == nil { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Metrics logs:\n %s", metricsOutput)) - } else { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get curl-metrics logs: %s", err)) - } - - By("Fetching controller manager pod description") - cmd = exec.Command("kubectl", "describe", "pod", controllerPodName, "-n", namespace) - podDescription, err := utils.Run(cmd) - if err == nil { - fmt.Println("Pod description:\n", podDescription) - } else { - fmt.Println("Failed to describe controller pod") - } - } - }) - - SetDefaultEventuallyTimeout(2 * time.Minute) - SetDefaultEventuallyPollingInterval(time.Second) - - Context("Manager", func() { - It("should run successfully", func() { - By("validating that the controller-manager pod is running as expected") - verifyControllerUp := func(g Gomega) { - // Get the name of the controller-manager pod - cmd := exec.Command("kubectl", "get", - "pods", "-l", "control-plane=controller-manager", - "-o", "go-template={{ range .items }}"+ - "{{ if not .metadata.deletionTimestamp }}"+ - "{{ .metadata.name }}"+ - "{{ \"\\n\" }}{{ end }}{{ end }}", - "-n", namespace, - ) - - podOutput, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred(), "Failed to retrieve controller-manager pod information") - podNames := utils.GetNonEmptyLines(podOutput) - g.Expect(podNames).To(HaveLen(1), "expected 1 controller pod running") - controllerPodName = podNames[0] - g.Expect(controllerPodName).To(ContainSubstring("controller-manager")) - - // Validate the pod's status - cmd = exec.Command("kubectl", "get", - "pods", controllerPodName, "-o", "jsonpath={.status.phase}", - "-n", namespace, - ) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(Equal("Running"), "Incorrect controller-manager pod status") - } - Eventually(verifyControllerUp).Should(Succeed()) - }) - - It("should ensure the metrics endpoint is serving metrics", func() { - By("creating a ClusterRoleBinding for the service account to allow access to metrics") - cmd := exec.Command("kubectl", "create", "clusterrolebinding", metricsRoleBindingName, - "--clusterrole=project-v4-multigroup-metrics-reader", - fmt.Sprintf("--serviceaccount=%s:%s", namespace, serviceAccountName), - ) - _, err := utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to create ClusterRoleBinding") - - By("validating that the metrics service is available") - cmd = exec.Command("kubectl", "get", "service", metricsServiceName, "-n", namespace) - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Metrics service should exist") - - By("validating that the ServiceMonitor for Prometheus is applied in the namespace") - cmd = exec.Command("kubectl", "get", "ServiceMonitor", "-n", namespace) - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "ServiceMonitor should exist") - - By("getting the service account token") - token, err := serviceAccountToken() - Expect(err).NotTo(HaveOccurred()) - Expect(token).NotTo(BeEmpty()) - - By("waiting for the metrics endpoint to be ready") - verifyMetricsEndpointReady := func(g Gomega) { - cmd := exec.Command("kubectl", "get", "endpoints", metricsServiceName, "-n", namespace) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("8443"), "Metrics endpoint is not ready") - } - Eventually(verifyMetricsEndpointReady).Should(Succeed()) - - By("verifying that the controller manager is serving the metrics server") - verifyMetricsServerStarted := func(g Gomega) { - cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("controller-runtime.metrics\tServing metrics server"), - "Metrics server not yet started") - } - Eventually(verifyMetricsServerStarted).Should(Succeed()) - - By("creating the curl-metrics pod to access the metrics endpoint") - cmd = exec.Command("kubectl", "run", "curl-metrics", "--restart=Never", - "--namespace", namespace, - "--image=curlimages/curl:7.78.0", - "--", "/bin/sh", "-c", fmt.Sprintf( - "curl -v -k -H 'Authorization: Bearer %s' https://%s.%s.svc.cluster.local:8443/metrics", - token, metricsServiceName, namespace)) - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to create curl-metrics pod") - - By("waiting for the curl-metrics pod to complete.") - verifyCurlUp := func(g Gomega) { - cmd := exec.Command("kubectl", "get", "pods", "curl-metrics", - "-o", "jsonpath={.status.phase}", - "-n", namespace) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(Equal("Succeeded"), "curl pod in wrong status") - } - Eventually(verifyCurlUp, 5*time.Minute).Should(Succeed()) - - By("getting the metrics by checking curl-metrics logs") - metricsOutput := getMetricsOutput() - Expect(metricsOutput).To(ContainSubstring( - "controller_runtime_reconcile_total", - )) - }) - - It("should provisioned cert-manager", func() { - By("validating that cert-manager has the certificate Secret") - verifyCertManager := func(g Gomega) { - cmd := exec.Command("kubectl", "get", "secrets", "webhook-server-cert", "-n", namespace) - _, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - } - Eventually(verifyCertManager).Should(Succeed()) - }) - - It("should have CA injection for mutating webhooks", func() { - By("checking CA injection for mutating webhooks") - verifyCAInjection := func(g Gomega) { - cmd := exec.Command("kubectl", "get", - "mutatingwebhookconfigurations.admissionregistration.k8s.io", - "project-v4-multigroup-mutating-webhook-configuration", - "-o", "go-template={{ range .webhooks }}{{ .clientConfig.caBundle }}{{ end }}") - mwhOutput, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(len(mwhOutput)).To(BeNumerically(">", 10)) - } - Eventually(verifyCAInjection).Should(Succeed()) - }) - - It("should have CA injection for validating webhooks", func() { - By("checking CA injection for validating webhooks") - verifyCAInjection := func(g Gomega) { - cmd := exec.Command("kubectl", "get", - "validatingwebhookconfigurations.admissionregistration.k8s.io", - "project-v4-multigroup-validating-webhook-configuration", - "-o", "go-template={{ range .webhooks }}{{ .clientConfig.caBundle }}{{ end }}") - vwhOutput, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(len(vwhOutput)).To(BeNumerically(">", 10)) - } - Eventually(verifyCAInjection).Should(Succeed()) - }) - - // +kubebuilder:scaffold:e2e-webhooks-checks - - // TODO: Customize the e2e test suite with scenarios specific to your project. - // Consider applying sample/CR(s) and check their status and/or verifying - // the reconciliation by using the metrics, i.e.: - // metricsOutput := getMetricsOutput() - // Expect(metricsOutput).To(ContainSubstring( - // fmt.Sprintf(`controller_runtime_reconcile_total{controller="%s",result="success"} 1`, - // strings.ToLower(), - // )) - }) -}) - -// serviceAccountToken returns a token for the specified service account in the given namespace. -// It uses the Kubernetes TokenRequest API to generate a token by directly sending a request -// and parsing the resulting token from the API response. -func serviceAccountToken() (string, error) { - const tokenRequestRawString = `{ - "apiVersion": "authentication.k8s.io/v1", - "kind": "TokenRequest" - }` - - // Temporary file to store the token request - secretName := fmt.Sprintf("%s-token-request", serviceAccountName) - tokenRequestFile := filepath.Join("/tmp", secretName) - err := os.WriteFile(tokenRequestFile, []byte(tokenRequestRawString), os.FileMode(0o644)) - if err != nil { - return "", err - } - - var out string - verifyTokenCreation := func(g Gomega) { - // Execute kubectl command to create the token - cmd := exec.Command("kubectl", "create", "--raw", fmt.Sprintf( - "/api/v1/namespaces/%s/serviceaccounts/%s/token", - namespace, - serviceAccountName, - ), "-f", tokenRequestFile) - - output, err := cmd.CombinedOutput() - g.Expect(err).NotTo(HaveOccurred()) - - // Parse the JSON output to extract the token - var token tokenRequest - err = json.Unmarshal([]byte(output), &token) - g.Expect(err).NotTo(HaveOccurred()) - - out = token.Status.Token - } - Eventually(verifyTokenCreation).Should(Succeed()) - - return out, err -} - -// getMetricsOutput retrieves and returns the logs from the curl pod used to access the metrics endpoint. -func getMetricsOutput() string { - By("getting the curl-metrics logs") - cmd := exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace) - metricsOutput, err := utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to retrieve logs from curl pod") - Expect(metricsOutput).To(ContainSubstring("< HTTP/1.1 200 OK")) - return metricsOutput -} - -// tokenRequest is a simplified representation of the Kubernetes TokenRequest API response, -// containing only the token field that we need to extract. -type tokenRequest struct { - Status struct { - Token string `json:"token"` - } `json:"status"` -} diff --git a/testdata/project-v4-multigroup/test/utils/utils.go b/testdata/project-v4-multigroup/test/utils/utils.go deleted file mode 100644 index a239bfd7be2..00000000000 --- a/testdata/project-v4-multigroup/test/utils/utils.go +++ /dev/null @@ -1,251 +0,0 @@ -/* -Copyright 2024 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 utils - -import ( - "bufio" - "bytes" - "fmt" - "os" - "os/exec" - "strings" - - . "github.com/onsi/ginkgo/v2" //nolint:golint,revive -) - -const ( - prometheusOperatorVersion = "v0.77.1" - prometheusOperatorURL = "https://github.com/prometheus-operator/prometheus-operator/" + - "releases/download/%s/bundle.yaml" - - certmanagerVersion = "v1.16.0" - certmanagerURLTmpl = "https://github.com/jetstack/cert-manager/releases/download/%s/cert-manager.yaml" -) - -func warnError(err error) { - _, _ = fmt.Fprintf(GinkgoWriter, "warning: %v\n", err) -} - -// Run executes the provided command within this context -func Run(cmd *exec.Cmd) (string, error) { - dir, _ := GetProjectDir() - cmd.Dir = dir - - if err := os.Chdir(cmd.Dir); err != nil { - _, _ = fmt.Fprintf(GinkgoWriter, "chdir dir: %s\n", err) - } - - cmd.Env = append(os.Environ(), "GO111MODULE=on") - command := strings.Join(cmd.Args, " ") - _, _ = fmt.Fprintf(GinkgoWriter, "running: %s\n", command) - output, err := cmd.CombinedOutput() - if err != nil { - return string(output), fmt.Errorf("%s failed with error: (%v) %s", command, err, string(output)) - } - - return string(output), nil -} - -// InstallPrometheusOperator installs the prometheus Operator to be used to export the enabled metrics. -func InstallPrometheusOperator() error { - url := fmt.Sprintf(prometheusOperatorURL, prometheusOperatorVersion) - cmd := exec.Command("kubectl", "create", "-f", url) - _, err := Run(cmd) - return err -} - -// UninstallPrometheusOperator uninstalls the prometheus -func UninstallPrometheusOperator() { - url := fmt.Sprintf(prometheusOperatorURL, prometheusOperatorVersion) - cmd := exec.Command("kubectl", "delete", "-f", url) - if _, err := Run(cmd); err != nil { - warnError(err) - } -} - -// IsPrometheusCRDsInstalled checks if any Prometheus CRDs are installed -// by verifying the existence of key CRDs related to Prometheus. -func IsPrometheusCRDsInstalled() bool { - // List of common Prometheus CRDs - prometheusCRDs := []string{ - "prometheuses.monitoring.coreos.com", - "prometheusrules.monitoring.coreos.com", - "prometheusagents.monitoring.coreos.com", - } - - cmd := exec.Command("kubectl", "get", "crds", "-o", "custom-columns=NAME:.metadata.name") - output, err := Run(cmd) - if err != nil { - return false - } - crdList := GetNonEmptyLines(string(output)) - for _, crd := range prometheusCRDs { - for _, line := range crdList { - if strings.Contains(line, crd) { - return true - } - } - } - - return false -} - -// UninstallCertManager uninstalls the cert manager -func UninstallCertManager() { - url := fmt.Sprintf(certmanagerURLTmpl, certmanagerVersion) - cmd := exec.Command("kubectl", "delete", "-f", url) - if _, err := Run(cmd); err != nil { - warnError(err) - } -} - -// InstallCertManager installs the cert manager bundle. -func InstallCertManager() error { - url := fmt.Sprintf(certmanagerURLTmpl, certmanagerVersion) - cmd := exec.Command("kubectl", "apply", "-f", url) - if _, err := Run(cmd); err != nil { - return err - } - // Wait for cert-manager-webhook to be ready, which can take time if cert-manager - // was re-installed after uninstalling on a cluster. - cmd = exec.Command("kubectl", "wait", "deployment.apps/cert-manager-webhook", - "--for", "condition=Available", - "--namespace", "cert-manager", - "--timeout", "5m", - ) - - _, err := Run(cmd) - return err -} - -// IsCertManagerCRDsInstalled checks if any Cert Manager CRDs are installed -// by verifying the existence of key CRDs related to Cert Manager. -func IsCertManagerCRDsInstalled() bool { - // List of common Cert Manager CRDs - certManagerCRDs := []string{ - "certificates.cert-manager.io", - "issuers.cert-manager.io", - "clusterissuers.cert-manager.io", - "certificaterequests.cert-manager.io", - "orders.acme.cert-manager.io", - "challenges.acme.cert-manager.io", - } - - // Execute the kubectl command to get all CRDs - cmd := exec.Command("kubectl", "get", "crds") - output, err := Run(cmd) - if err != nil { - return false - } - - // Check if any of the Cert Manager CRDs are present - crdList := GetNonEmptyLines(string(output)) - for _, crd := range certManagerCRDs { - for _, line := range crdList { - if strings.Contains(line, crd) { - return true - } - } - } - - return false -} - -// LoadImageToKindClusterWithName loads a local docker image to the kind cluster -func LoadImageToKindClusterWithName(name string) error { - cluster := "kind" - if v, ok := os.LookupEnv("KIND_CLUSTER"); ok { - cluster = v - } - kindOptions := []string{"load", "docker-image", name, "--name", cluster} - cmd := exec.Command("kind", kindOptions...) - _, err := Run(cmd) - return err -} - -// GetNonEmptyLines converts given command output string into individual objects -// according to line breakers, and ignores the empty elements in it. -func GetNonEmptyLines(output string) []string { - var res []string - elements := strings.Split(output, "\n") - for _, element := range elements { - if element != "" { - res = append(res, element) - } - } - - return res -} - -// GetProjectDir will return the directory where the project is -func GetProjectDir() (string, error) { - wd, err := os.Getwd() - if err != nil { - return wd, err - } - wd = strings.Replace(wd, "/test/e2e", "", -1) - return wd, nil -} - -// UncommentCode searches for target in the file and remove the comment prefix -// of the target content. The target content may span multiple lines. -func UncommentCode(filename, target, prefix string) error { - // false positive - // nolint:gosec - content, err := os.ReadFile(filename) - if err != nil { - return err - } - strContent := string(content) - - idx := strings.Index(strContent, target) - if idx < 0 { - return fmt.Errorf("unable to find the code %s to be uncomment", target) - } - - out := new(bytes.Buffer) - _, err = out.Write(content[:idx]) - if err != nil { - return err - } - - scanner := bufio.NewScanner(bytes.NewBufferString(target)) - if !scanner.Scan() { - return nil - } - for { - _, err := out.WriteString(strings.TrimPrefix(scanner.Text(), prefix)) - if err != nil { - return err - } - // Avoid writing a newline in case the previous line was the last in target. - if !scanner.Scan() { - break - } - if _, err := out.WriteString("\n"); err != nil { - return err - } - } - - _, err = out.Write(content[idx+len(target):]) - if err != nil { - return err - } - // false positive - // nolint:gosec - return os.WriteFile(filename, out.Bytes(), 0644) -} diff --git a/testdata/project-v4-with-plugins/.devcontainer/devcontainer.json b/testdata/project-v4-with-plugins/.devcontainer/devcontainer.json deleted file mode 100644 index e2cdc09c96c..00000000000 --- a/testdata/project-v4-with-plugins/.devcontainer/devcontainer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "Kubebuilder DevContainer", - "image": "golang:1.22", - "features": { - "ghcr.io/devcontainers/features/docker-in-docker:2": {}, - "ghcr.io/devcontainers/features/git:1": {} - }, - - "runArgs": ["--network=host"], - - "customizations": { - "vscode": { - "settings": { - "terminal.integrated.shell.linux": "/bin/bash" - }, - "extensions": [ - "ms-kubernetes-tools.vscode-kubernetes-tools", - "ms-azuretools.vscode-docker" - ] - } - }, - - "onCreateCommand": "bash .devcontainer/post-install.sh" -} - diff --git a/testdata/project-v4-with-plugins/.devcontainer/post-install.sh b/testdata/project-v4-with-plugins/.devcontainer/post-install.sh deleted file mode 100644 index 265c43ee8d3..00000000000 --- a/testdata/project-v4-with-plugins/.devcontainer/post-install.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -set -x - -curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64 -chmod +x ./kind -mv ./kind /usr/local/bin/kind - -curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/linux/amd64 -chmod +x kubebuilder -mv kubebuilder /usr/local/bin/ - -KUBECTL_VERSION=$(curl -L -s https://dl.k8s.io/release/stable.txt) -curl -LO "https://dl.k8s.io/release/$KUBECTL_VERSION/bin/linux/amd64/kubectl" -chmod +x kubectl -mv kubectl /usr/local/bin/kubectl - -docker network create -d=bridge --subnet=172.19.0.0/24 kind - -kind version -kubebuilder version -docker --version -go version -kubectl version --client diff --git a/testdata/project-v4-with-plugins/.dockerignore b/testdata/project-v4-with-plugins/.dockerignore deleted file mode 100644 index a3aab7af70c..00000000000 --- a/testdata/project-v4-with-plugins/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file -# Ignore build and test binaries. -bin/ diff --git a/testdata/project-v4-with-plugins/.github/workflows/lint.yml b/testdata/project-v4-with-plugins/.github/workflows/lint.yml deleted file mode 100644 index b6967b35f4f..00000000000 --- a/testdata/project-v4-with-plugins/.github/workflows/lint.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Lint - -on: - push: - pull_request: - -jobs: - lint: - name: Run on Ubuntu - runs-on: ubuntu-latest - steps: - - name: Clone the code - uses: actions/checkout@v4 - - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: '~1.22' - - - name: Run linter - uses: golangci/golangci-lint-action@v6 - with: - version: v1.59 diff --git a/testdata/project-v4-with-plugins/.github/workflows/test-e2e.yml b/testdata/project-v4-with-plugins/.github/workflows/test-e2e.yml deleted file mode 100644 index 8780644002a..00000000000 --- a/testdata/project-v4-with-plugins/.github/workflows/test-e2e.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: E2E Tests - -on: - push: - pull_request: - -jobs: - test-e2e: - name: Run on Ubuntu - runs-on: ubuntu-latest - steps: - - name: Clone the code - uses: actions/checkout@v4 - - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: '~1.22' - - - name: Install the latest version of kind - run: | - curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64 - chmod +x ./kind - sudo mv ./kind /usr/local/bin/kind - - - name: Verify kind installation - run: kind version - - - name: Create kind cluster - run: kind create cluster - - - name: Running Test e2e - run: | - go mod tidy - make test-e2e diff --git a/testdata/project-v4-with-plugins/.github/workflows/test.yml b/testdata/project-v4-with-plugins/.github/workflows/test.yml deleted file mode 100644 index 7baf6579399..00000000000 --- a/testdata/project-v4-with-plugins/.github/workflows/test.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Tests - -on: - push: - pull_request: - -jobs: - test: - name: Run on Ubuntu - runs-on: ubuntu-latest - steps: - - name: Clone the code - uses: actions/checkout@v4 - - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: '~1.22' - - - name: Running Tests - run: | - go mod tidy - make test diff --git a/testdata/project-v4-with-plugins/.gitignore b/testdata/project-v4-with-plugins/.gitignore deleted file mode 100644 index ada68ff086c..00000000000 --- a/testdata/project-v4-with-plugins/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib -bin/* -Dockerfile.cross - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Go workspace file -go.work - -# Kubernetes Generated files - skip generated files, except for vendored files -!vendor/**/zz_generated.* - -# editor and IDE paraphernalia -.idea -.vscode -*.swp -*.swo -*~ diff --git a/testdata/project-v4-with-plugins/.golangci.yml b/testdata/project-v4-with-plugins/.golangci.yml deleted file mode 100644 index aac8a13f928..00000000000 --- a/testdata/project-v4-with-plugins/.golangci.yml +++ /dev/null @@ -1,47 +0,0 @@ -run: - timeout: 5m - allow-parallel-runners: true - -issues: - # don't skip warning about doc comments - # don't exclude the default set of lint - exclude-use-default: false - # restore some of the defaults - # (fill in the rest as needed) - exclude-rules: - - path: "api/*" - linters: - - lll - - path: "internal/*" - linters: - - dupl - - lll -linters: - disable-all: true - enable: - - dupl - - errcheck - - exportloopref - - ginkgolinter - - goconst - - gocyclo - - gofmt - - goimports - - gosimple - - govet - - ineffassign - - lll - - misspell - - nakedret - - prealloc - - revive - - staticcheck - - typecheck - - unconvert - - unparam - - unused - -linters-settings: - revive: - rules: - - name: comment-spacings diff --git a/testdata/project-v4-with-plugins/Dockerfile b/testdata/project-v4-with-plugins/Dockerfile deleted file mode 100644 index 4ba18b68cc4..00000000000 --- a/testdata/project-v4-with-plugins/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -# Build the manager binary -FROM golang:1.22 AS builder -ARG TARGETOS -ARG TARGETARCH - -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 cmd/main.go cmd/main.go -COPY api/ api/ -COPY internal/ internal/ - -# Build -# the GOARCH has not a default value to allow the binary be built according to the host where the command -# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO -# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, -# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. -RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/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-v4-with-plugins/Makefile b/testdata/project-v4-with-plugins/Makefile deleted file mode 100644 index 2aa7bd8af46..00000000000 --- a/testdata/project-v4-with-plugins/Makefile +++ /dev/null @@ -1,212 +0,0 @@ -# Image URL to use all building/pushing image targets -IMG ?= controller:latest -# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.31.0 - -# 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 - -# CONTAINER_TOOL defines the container tool to be used for building images. -# Be aware that the target commands are only tested with Docker which is -# scaffolded by default. However, you might want to replace it to use other -# tools. (i.e. podman) -CONTAINER_TOOL ?= docker - -# Setting SHELL to bash allows bash commands to be executed by recipes. -# Options are set to exit when a recipe line exits non-zero or a piped command fails. -SHELL = /usr/bin/env bash -o pipefail -.SHELLFLAGS = -ec - -.PHONY: all -all: build - -##@ General - -# The help target prints out all targets with their descriptions organized -# beneath their categories. The categories are represented by '##@' and the -# target descriptions by '##'. The awk command is responsible for reading the -# entire set of makefiles included in this invocation, looking for lines of the -# file as xyz: ## something, and then pretty-format the target and help. Then, -# if there's a line with ##@ something, that gets pretty-printed as a category. -# More info on the usage of ANSI control characters for terminal formatting: -# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters -# More info on the awk command: -# http://linuxcommand.org/lc3_adv_awk.php - -.PHONY: help -help: ## Display this help. - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) - -##@ Development - -.PHONY: manifests -manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. - $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases - -.PHONY: generate -generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." - -.PHONY: fmt -fmt: ## Run go fmt against code. - go fmt ./... - -.PHONY: vet -vet: ## Run go vet against code. - go vet ./... - -.PHONY: test -test: manifests generate fmt vet envtest ## Run tests. - KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out - -# TODO(user): To use a different vendor for e2e tests, modify the setup under 'tests/e2e'. -# The default setup assumes Kind is pre-installed and builds/loads the Manager Docker image locally. -# Prometheus and CertManager are installed by default; skip with: -# - PROMETHEUS_INSTALL_SKIP=true -# - CERT_MANAGER_INSTALL_SKIP=true -.PHONY: test-e2e -test-e2e: manifests generate fmt vet ## Run the e2e tests. Expected an isolated environment using Kind. - @command -v kind >/dev/null 2>&1 || { \ - echo "Kind is not installed. Please install Kind manually."; \ - exit 1; \ - } - @kind get clusters | grep -q 'kind' || { \ - echo "No Kind cluster is running. Please start a Kind cluster before running the e2e tests."; \ - exit 1; \ - } - go test ./test/e2e/ -v -ginkgo.v - -.PHONY: lint -lint: golangci-lint ## Run golangci-lint linter - $(GOLANGCI_LINT) run - -.PHONY: lint-fix -lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes - $(GOLANGCI_LINT) run --fix - -##@ Build - -.PHONY: build -build: manifests generate fmt vet ## Build manager binary. - go build -o bin/manager cmd/main.go - -.PHONY: run -run: manifests generate fmt vet ## Run a controller from your host. - go run ./cmd/main.go - -# If you wish to build the manager image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. -# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -.PHONY: docker-build -docker-build: ## Build docker image with the manager. - $(CONTAINER_TOOL) build -t ${IMG} . - -.PHONY: docker-push -docker-push: ## Push docker image with the manager. - $(CONTAINER_TOOL) push ${IMG} - -# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple -# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: -# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ -# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) -# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. -PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le -.PHONY: docker-buildx -docker-buildx: ## Build and push docker image for the manager for cross-platform support - # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile - sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - - $(CONTAINER_TOOL) buildx create --name project-v4-with-plugins-builder - $(CONTAINER_TOOL) buildx use project-v4-with-plugins-builder - - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . - - $(CONTAINER_TOOL) buildx rm project-v4-with-plugins-builder - rm Dockerfile.cross - -.PHONY: build-installer -build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment. - mkdir -p dist - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default > dist/install.yaml - -##@ Deployment - -ifndef ignore-not-found - ignore-not-found = false -endif - -.PHONY: install -install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. - $(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f - - -.PHONY: uninstall -uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - - -.PHONY: deploy -deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default | $(KUBECTL) apply -f - - -.PHONY: undeploy -undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - - -##@ Dependencies - -## Location to install dependencies to -LOCALBIN ?= $(shell pwd)/bin -$(LOCALBIN): - mkdir -p $(LOCALBIN) - -## Tool Binaries -KUBECTL ?= kubectl -KUSTOMIZE ?= $(LOCALBIN)/kustomize -CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen -ENVTEST ?= $(LOCALBIN)/setup-envtest -GOLANGCI_LINT = $(LOCALBIN)/golangci-lint - -## Tool Versions -KUSTOMIZE_VERSION ?= v5.4.3 -CONTROLLER_TOOLS_VERSION ?= v0.16.4 -ENVTEST_VERSION ?= release-0.19 -GOLANGCI_LINT_VERSION ?= v1.59.1 - -.PHONY: kustomize -kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. -$(KUSTOMIZE): $(LOCALBIN) - $(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_VERSION)) - -.PHONY: controller-gen -controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. -$(CONTROLLER_GEN): $(LOCALBIN) - $(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen,$(CONTROLLER_TOOLS_VERSION)) - -.PHONY: envtest -envtest: $(ENVTEST) ## Download setup-envtest locally if necessary. -$(ENVTEST): $(LOCALBIN) - $(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,$(ENVTEST_VERSION)) - -.PHONY: golangci-lint -golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. -$(GOLANGCI_LINT): $(LOCALBIN) - $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION)) - -# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist -# $1 - target path with name of binary -# $2 - package url which can be installed -# $3 - specific version of package -define go-install-tool -@[ -f "$(1)-$(3)" ] || { \ -set -e; \ -package=$(2)@$(3) ;\ -echo "Downloading $${package}" ;\ -rm -f $(1) || true ;\ -GOBIN=$(LOCALBIN) go install $${package} ;\ -mv $(1) $(1)-$(3) ;\ -} ;\ -ln -sf $(1)-$(3) $(1) -endef diff --git a/testdata/project-v4-with-plugins/PROJECT b/testdata/project-v4-with-plugins/PROJECT deleted file mode 100644 index f006d1cad32..00000000000 --- a/testdata/project-v4-with-plugins/PROJECT +++ /dev/null @@ -1,51 +0,0 @@ -# Code generated by tool. DO NOT EDIT. -# This file is used to track the info used to scaffold your project -# and allow the plugins properly work. -# More info: https://book.kubebuilder.io/reference/project-config.html -domain: testproject.org -layout: -- go.kubebuilder.io/v4 -plugins: - deploy-image.go.kubebuilder.io/v1-alpha: - resources: - - domain: testproject.org - group: example.com - kind: Memcached - options: - containerCommand: memcached,--memory-limit=64,-o,modern,-v - containerPort: "11211" - image: memcached:memcached:1.6.26-alpine3.19 - runAsUser: "1001" - version: v1alpha1 - - domain: testproject.org - group: example.com - kind: Busybox - options: - image: busybox:1.36.1 - version: v1alpha1 - grafana.kubebuilder.io/v1-alpha: {} -projectName: project-v4-with-plugins -repo: sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins -resources: -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: example.com - kind: Memcached - path: sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1alpha1 - version: v1alpha1 - webhooks: - validation: true - webhookVersion: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: example.com - kind: Busybox - path: sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1alpha1 - version: v1alpha1 -version: "3" diff --git a/testdata/project-v4-with-plugins/README.md b/testdata/project-v4-with-plugins/README.md deleted file mode 100644 index 39377250d34..00000000000 --- a/testdata/project-v4-with-plugins/README.md +++ /dev/null @@ -1,114 +0,0 @@ -# project-v4-with-plugins -// TODO(user): Add simple overview of use/purpose - -## Description -// TODO(user): An in-depth paragraph about your project and overview of use - -## Getting Started - -### Prerequisites -- go version v1.22.0+ -- docker version 17.03+. -- kubectl version v1.11.3+. -- Access to a Kubernetes v1.11.3+ cluster. - -### To Deploy on the cluster -**Build and push your image to the location specified by `IMG`:** - -```sh -make docker-build docker-push IMG=/project-v4-with-plugins:tag -``` - -**NOTE:** This image ought to be published in the personal registry you specified. -And it is required to have access to pull the image from the working environment. -Make sure you have the proper permission to the registry if the above commands don’t work. - -**Install the CRDs into the cluster:** - -```sh -make install -``` - -**Deploy the Manager to the cluster with the image specified by `IMG`:** - -```sh -make deploy IMG=/project-v4-with-plugins:tag -``` - -> **NOTE**: If you encounter RBAC errors, you may need to grant yourself cluster-admin -privileges or be logged in as admin. - -**Create instances of your solution** -You can apply the samples (examples) from the config/sample: - -```sh -kubectl apply -k config/samples/ -``` - ->**NOTE**: Ensure that the samples has default values to test it out. - -### To Uninstall -**Delete the instances (CRs) from the cluster:** - -```sh -kubectl delete -k config/samples/ -``` - -**Delete the APIs(CRDs) from the cluster:** - -```sh -make uninstall -``` - -**UnDeploy the controller from the cluster:** - -```sh -make undeploy -``` - -## Project Distribution - -Following are the steps to build the installer and distribute this project to users. - -1. Build the installer for the image built and published in the registry: - -```sh -make build-installer IMG=/project-v4-with-plugins:tag -``` - -NOTE: The makefile target mentioned above generates an 'install.yaml' -file in the dist directory. This file contains all the resources built -with Kustomize, which are necessary to install this project without -its dependencies. - -2. Using the installer - -Users can just run kubectl apply -f to install the project, i.e.: - -```sh -kubectl apply -f https://raw.githubusercontent.com//project-v4-with-plugins//dist/install.yaml -``` - -## Contributing -// TODO(user): Add detailed information on how you would like others to contribute to this project - -**NOTE:** Run `make help` for more information on all potential `make` targets - -More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html) - -## License - -Copyright 2024 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. - diff --git a/testdata/project-v4-with-plugins/api/v1alpha1/busybox_types.go b/testdata/project-v4-with-plugins/api/v1alpha1/busybox_types.go deleted file mode 100644 index cd1fd6da5d6..00000000000 --- a/testdata/project-v4-with-plugins/api/v1alpha1/busybox_types.go +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 - -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. - -// BusyboxSpec defines the desired state of Busybox -type BusyboxSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // Size defines the number of Busybox instances - // The following markers will use OpenAPI v3 schema to validate the value - // More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - // +kubebuilder:validation:Minimum=1 - // +kubebuilder:validation:Maximum=3 - // +kubebuilder:validation:ExclusiveMaximum=false - Size int32 `json:"size,omitempty"` -} - -// BusyboxStatus defines the observed state of Busybox -type BusyboxStatus struct { - // Represents the observations of a Busybox's current state. - // Busybox.status.conditions.type are: "Available", "Progressing", and "Degraded" - // Busybox.status.conditions.status are one of True, False, Unknown. - // Busybox.status.conditions.reason the value should be a CamelCase string and producers of specific - // condition types may define expected values and meanings for this field, and whether the values - // are considered a guaranteed API. - // Busybox.status.conditions.Message is a human readable message indicating details about the transition. - // For further information see: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties - - Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status - -// Busybox is the Schema for the busyboxes API -type Busybox struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec BusyboxSpec `json:"spec,omitempty"` - Status BusyboxStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// BusyboxList contains a list of Busybox -type BusyboxList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Busybox `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Busybox{}, &BusyboxList{}) -} diff --git a/testdata/project-v4-with-plugins/api/v1alpha1/groupversion_info.go b/testdata/project-v4-with-plugins/api/v1alpha1/groupversion_info.go deleted file mode 100644 index 110a9b573a1..00000000000 --- a/testdata/project-v4-with-plugins/api/v1alpha1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 contains API Schema definitions for the example.com v1alpha1 API group. -// +kubebuilder:object:generate=true -// +groupName=example.com.testproject.org -package v1alpha1 - -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: "example.com.testproject.org", Version: "v1alpha1"} - - // 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-v4-with-plugins/api/v1alpha1/memcached_types.go b/testdata/project-v4-with-plugins/api/v1alpha1/memcached_types.go deleted file mode 100644 index 7c4116e82a5..00000000000 --- a/testdata/project-v4-with-plugins/api/v1alpha1/memcached_types.go +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 - -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. - -// MemcachedSpec defines the desired state of Memcached -type MemcachedSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // Size defines the number of Memcached instances - // The following markers will use OpenAPI v3 schema to validate the value - // More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - // +kubebuilder:validation:Minimum=1 - // +kubebuilder:validation:Maximum=3 - // +kubebuilder:validation:ExclusiveMaximum=false - Size int32 `json:"size,omitempty"` - - // Port defines the port that will be used to init the container with the image - ContainerPort int32 `json:"containerPort,omitempty"` -} - -// MemcachedStatus defines the observed state of Memcached -type MemcachedStatus struct { - // Represents the observations of a Memcached's current state. - // Memcached.status.conditions.type are: "Available", "Progressing", and "Degraded" - // Memcached.status.conditions.status are one of True, False, Unknown. - // Memcached.status.conditions.reason the value should be a CamelCase string and producers of specific - // condition types may define expected values and meanings for this field, and whether the values - // are considered a guaranteed API. - // Memcached.status.conditions.Message is a human readable message indicating details about the transition. - // For further information see: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties - - Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status - -// Memcached is the Schema for the memcacheds API -type Memcached struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec MemcachedSpec `json:"spec,omitempty"` - Status MemcachedStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// MemcachedList contains a list of Memcached -type MemcachedList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Memcached `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Memcached{}, &MemcachedList{}) -} diff --git a/testdata/project-v4-with-plugins/api/v1alpha1/zz_generated.deepcopy.go b/testdata/project-v4-with-plugins/api/v1alpha1/zz_generated.deepcopy.go deleted file mode 100644 index 6254bdb0507..00000000000 --- a/testdata/project-v4-with-plugins/api/v1alpha1/zz_generated.deepcopy.go +++ /dev/null @@ -1,218 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Busybox) DeepCopyInto(out *Busybox) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Busybox. -func (in *Busybox) DeepCopy() *Busybox { - if in == nil { - return nil - } - out := new(Busybox) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Busybox) 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 *BusyboxList) DeepCopyInto(out *BusyboxList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Busybox, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusyboxList. -func (in *BusyboxList) DeepCopy() *BusyboxList { - if in == nil { - return nil - } - out := new(BusyboxList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BusyboxList) 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 *BusyboxSpec) DeepCopyInto(out *BusyboxSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusyboxSpec. -func (in *BusyboxSpec) DeepCopy() *BusyboxSpec { - if in == nil { - return nil - } - out := new(BusyboxSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BusyboxStatus) DeepCopyInto(out *BusyboxStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusyboxStatus. -func (in *BusyboxStatus) DeepCopy() *BusyboxStatus { - if in == nil { - return nil - } - out := new(BusyboxStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Memcached) DeepCopyInto(out *Memcached) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Memcached. -func (in *Memcached) DeepCopy() *Memcached { - if in == nil { - return nil - } - out := new(Memcached) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Memcached) 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 *MemcachedList) DeepCopyInto(out *MemcachedList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Memcached, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemcachedList. -func (in *MemcachedList) DeepCopy() *MemcachedList { - if in == nil { - return nil - } - out := new(MemcachedList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *MemcachedList) 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 *MemcachedSpec) DeepCopyInto(out *MemcachedSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemcachedSpec. -func (in *MemcachedSpec) DeepCopy() *MemcachedSpec { - if in == nil { - return nil - } - out := new(MemcachedSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MemcachedStatus) DeepCopyInto(out *MemcachedStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemcachedStatus. -func (in *MemcachedStatus) DeepCopy() *MemcachedStatus { - if in == nil { - return nil - } - out := new(MemcachedStatus) - in.DeepCopyInto(out) - return out -} diff --git a/testdata/project-v4-with-plugins/cmd/main.go b/testdata/project-v4-with-plugins/cmd/main.go deleted file mode 100644 index ed32294e2be..00000000000 --- a/testdata/project-v4-with-plugins/cmd/main.go +++ /dev/null @@ -1,187 +0,0 @@ -/* -Copyright 2024 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 ( - "crypto/tls" - "flag" - "os" - - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - // to ensure that exec-entrypoint and run can make use of them. - _ "k8s.io/client-go/plugin/pkg/client/auth" - - "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/metrics/filters" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1alpha1" - "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/internal/controller" - webhookexamplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/internal/webhook/v1alpha1" - // +kubebuilder:scaffold:imports -) - -var ( - scheme = runtime.NewScheme() - setupLog = ctrl.Log.WithName("setup") -) - -func init() { - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - - utilruntime.Must(examplecomv1alpha1.AddToScheme(scheme)) - // +kubebuilder:scaffold:scheme -} - -func main() { - var metricsAddr string - var enableLeaderElection bool - var probeAddr string - var secureMetrics bool - var enableHTTP2 bool - var tlsOpts []func(*tls.Config) - flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+ - "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.") - flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") - flag.BoolVar(&enableLeaderElection, "leader-elect", false, - "Enable leader election for controller manager. "+ - "Enabling this will ensure there is only one active controller manager.") - flag.BoolVar(&secureMetrics, "metrics-secure", true, - "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.") - flag.BoolVar(&enableHTTP2, "enable-http2", false, - "If set, HTTP/2 will be enabled for the metrics and webhook servers") - opts := zap.Options{ - Development: true, - } - opts.BindFlags(flag.CommandLine) - flag.Parse() - - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - - // if the enable-http2 flag is false (the default), http/2 should be disabled - // due to its vulnerabilities. More specifically, disabling http/2 will - // prevent from being vulnerable to the HTTP/2 Stream Cancellation and - // Rapid Reset CVEs. For more information see: - // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3 - // - https://github.com/advisories/GHSA-4374-p667-p6c8 - disableHTTP2 := func(c *tls.Config) { - setupLog.Info("disabling http/2") - c.NextProtos = []string{"http/1.1"} - } - - if !enableHTTP2 { - tlsOpts = append(tlsOpts, disableHTTP2) - } - - webhookServer := webhook.NewServer(webhook.Options{ - TLSOpts: tlsOpts, - }) - - // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server. - // More info: - // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/metrics/server - // - https://book.kubebuilder.io/reference/metrics.html - metricsServerOptions := metricsserver.Options{ - BindAddress: metricsAddr, - SecureServing: secureMetrics, - // TODO(user): TLSOpts is used to allow configuring the TLS config used for the server. If certificates are - // not provided, self-signed certificates will be generated by default. This option is not recommended for - // production environments as self-signed certificates do not offer the same level of trust and security - // as certificates issued by a trusted Certificate Authority (CA). The primary risk is potentially allowing - // unauthorized access to sensitive metrics data. Consider replacing with CertDir, CertName, and KeyName - // to provide certificates, ensuring the server communicates using trusted and secure certificates. - TLSOpts: tlsOpts, - } - - if secureMetrics { - // FilterProvider is used to protect the metrics endpoint with authn/authz. - // These configurations ensure that only authorized users and service accounts - // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info: - // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/metrics/filters#WithAuthenticationAndAuthorization - metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization - } - - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: scheme, - Metrics: metricsServerOptions, - WebhookServer: webhookServer, - HealthProbeBindAddress: probeAddr, - LeaderElection: enableLeaderElection, - LeaderElectionID: "a13ae5d8.testproject.org", - // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily - // when the Manager ends. This requires the binary to immediately end when the - // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly - // speeds up voluntary leader transitions as the new leader don't have to wait - // LeaseDuration time first. - // - // In the default scaffold provided, the program ends immediately after - // the manager stops, so would be fine to enable this option. However, - // if you are doing or is intended to do any operation such as perform cleanups - // after the manager stops then its usage might be unsafe. - // LeaderElectionReleaseOnCancel: true, - }) - if err != nil { - setupLog.Error(err, "unable to start manager") - os.Exit(1) - } - - if err = (&controller.MemcachedReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Recorder: mgr.GetEventRecorderFor("memcached-controller"), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Memcached") - os.Exit(1) - } - if err = (&controller.BusyboxReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Recorder: mgr.GetEventRecorderFor("busybox-controller"), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Busybox") - os.Exit(1) - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookexamplecomv1alpha1.SetupMemcachedWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Memcached") - os.Exit(1) - } - } - // +kubebuilder:scaffold:builder - - if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up health check") - os.Exit(1) - } - if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up ready check") - os.Exit(1) - } - - setupLog.Info("starting manager") - if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { - setupLog.Error(err, "problem running manager") - os.Exit(1) - } -} diff --git a/testdata/project-v4-with-plugins/config/certmanager/certificate.yaml b/testdata/project-v4-with-plugins/config/certmanager/certificate.yaml deleted file mode 100644 index 68214a62d39..00000000000 --- a/testdata/project-v4-with-plugins/config/certmanager/certificate.yaml +++ /dev/null @@ -1,35 +0,0 @@ -# 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: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: selfsigned-issuer - namespace: system -spec: - selfSigned: {} ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - labels: - app.kubernetes.io/name: certificate - app.kubernetes.io/instance: serving-cert - app.kubernetes.io/component: certificate - app.kubernetes.io/created-by: project-v4-with-plugins - app.kubernetes.io/part-of: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - 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-v4-with-plugins/config/certmanager/kustomization.yaml b/testdata/project-v4-with-plugins/config/certmanager/kustomization.yaml deleted file mode 100644 index bebea5a595e..00000000000 --- a/testdata/project-v4-with-plugins/config/certmanager/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -resources: -- certificate.yaml - -configurations: -- kustomizeconfig.yaml diff --git a/testdata/project-v4-with-plugins/config/certmanager/kustomizeconfig.yaml b/testdata/project-v4-with-plugins/config/certmanager/kustomizeconfig.yaml deleted file mode 100644 index cf6f89e8892..00000000000 --- a/testdata/project-v4-with-plugins/config/certmanager/kustomizeconfig.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# This configuration is for teaching kustomize how to update name ref substitution -nameReference: -- kind: Issuer - group: cert-manager.io - fieldSpecs: - - kind: Certificate - group: cert-manager.io - path: spec/issuerRef/name diff --git a/testdata/project-v4-with-plugins/config/crd/bases/example.com.testproject.org_busyboxes.yaml b/testdata/project-v4-with-plugins/config/crd/bases/example.com.testproject.org_busyboxes.yaml deleted file mode 100644 index 9f02a3d2fa0..00000000000 --- a/testdata/project-v4-with-plugins/config/crd/bases/example.com.testproject.org_busyboxes.yaml +++ /dev/null @@ -1,116 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: busyboxes.example.com.testproject.org -spec: - group: example.com.testproject.org - names: - kind: Busybox - listKind: BusyboxList - plural: busyboxes - singular: busybox - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Busybox is the Schema for the busyboxes 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: BusyboxSpec defines the desired state of Busybox - properties: - size: - description: |- - Size defines the number of Busybox instances - The following markers will use OpenAPI v3 schema to validate the value - More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - format: int32 - maximum: 3 - minimum: 1 - type: integer - type: object - status: - description: BusyboxStatus defines the observed state of Busybox - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-with-plugins/config/crd/bases/example.com.testproject.org_memcacheds.yaml b/testdata/project-v4-with-plugins/config/crd/bases/example.com.testproject.org_memcacheds.yaml deleted file mode 100644 index db5bd44e21d..00000000000 --- a/testdata/project-v4-with-plugins/config/crd/bases/example.com.testproject.org_memcacheds.yaml +++ /dev/null @@ -1,121 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: memcacheds.example.com.testproject.org -spec: - group: example.com.testproject.org - names: - kind: Memcached - listKind: MemcachedList - plural: memcacheds - singular: memcached - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Memcached is the Schema for the memcacheds 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: MemcachedSpec defines the desired state of Memcached - properties: - containerPort: - description: Port defines the port that will be used to init the container - with the image - format: int32 - type: integer - size: - description: |- - Size defines the number of Memcached instances - The following markers will use OpenAPI v3 schema to validate the value - More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - format: int32 - maximum: 3 - minimum: 1 - type: integer - type: object - status: - description: MemcachedStatus defines the observed state of Memcached - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-with-plugins/config/crd/kustomization.yaml b/testdata/project-v4-with-plugins/config/crd/kustomization.yaml deleted file mode 100644 index 7b2aba4eb3c..00000000000 --- a/testdata/project-v4-with-plugins/config/crd/kustomization.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# 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/example.com.testproject.org_memcacheds.yaml -- bases/example.com.testproject.org_busyboxes.yaml -# +kubebuilder:scaffold:crdkustomizeresource - -patches: -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. -# patches here are for enabling the conversion webhook for each CRD -- path: patches/webhook_in_memcacheds.yaml -# +kubebuilder:scaffold:crdkustomizewebhookpatch - -# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. -# patches here are for enabling the CA injection for each CRD -#- path: patches/cainjection_in_memcacheds.yaml -#- path: patches/cainjection_in_busyboxes.yaml -# +kubebuilder:scaffold:crdkustomizecainjectionpatch - -# [WEBHOOK] To enable webhook, uncomment the following section -# the following config is for teaching kustomize how to do kustomization for CRDs. - -configurations: -- kustomizeconfig.yaml diff --git a/testdata/project-v4-with-plugins/config/crd/kustomizeconfig.yaml b/testdata/project-v4-with-plugins/config/crd/kustomizeconfig.yaml deleted file mode 100644 index ec5c150a9df..00000000000 --- a/testdata/project-v4-with-plugins/config/crd/kustomizeconfig.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# 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-v4-with-plugins/config/crd/patches/cainjection_in_memcacheds.yaml b/testdata/project-v4-with-plugins/config/crd/patches/cainjection_in_memcacheds.yaml deleted file mode 100644 index 5b9e839364d..00000000000 --- a/testdata/project-v4-with-plugins/config/crd/patches/cainjection_in_memcacheds.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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: memcacheds.example.com.testproject.org diff --git a/testdata/project-v4-with-plugins/config/crd/patches/webhook_in_memcacheds.yaml b/testdata/project-v4-with-plugins/config/crd/patches/webhook_in_memcacheds.yaml deleted file mode 100644 index 4a56b0f4c69..00000000000 --- a/testdata/project-v4-with-plugins/config/crd/patches/webhook_in_memcacheds.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: memcacheds.example.com.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4-with-plugins/config/default/kustomization.yaml b/testdata/project-v4-with-plugins/config/default/kustomization.yaml deleted file mode 100644 index feac2c91a36..00000000000 --- a/testdata/project-v4-with-plugins/config/default/kustomization.yaml +++ /dev/null @@ -1,177 +0,0 @@ -# Adds namespace to all resources. -namespace: project-v4-with-plugins-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-v4-with-plugins- - -# Labels to add to all resources and selectors. -#labels: -#- includeSelectors: true -# pairs: -# someName: someValue - -resources: -- ../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 -# [METRICS] Expose the controller manager metrics service. -- metrics_service.yaml -# [NETWORK POLICY] Protect the /metrics endpoint and Webhook Server with NetworkPolicy. -# Only Pod(s) running a namespace labeled with 'metrics: enabled' will be able to gather the metrics. -# Only CR(s) which requires webhooks and are applied on namespaces labeled with 'webhooks: enabled' will -# be able to communicate with the Webhook Server. -#- ../network-policy - -# Uncomment the patches line if you enable Metrics, and/or are using webhooks and cert-manager -patches: -# [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. -# More info: https://book.kubebuilder.io/reference/metrics -- path: manager_metrics_patch.yaml - target: - kind: Deployment - -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -- path: manager_webhook_patch.yaml - -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -# Uncomment the following replacements to add the cert-manager CA injection annotations -#replacements: -# - source: # Uncomment the following block if you have a ValidatingWebhook (--programmatic-validation) -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.namespace # Namespace of the certificate CR -# targets: -# - select: -# kind: ValidatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.name -# targets: -# - select: -# kind: ValidatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# -# - source: # Uncomment the following block if you have a DefaultingWebhook (--defaulting ) -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.namespace # Namespace of the certificate CR -# targets: -# - select: -# kind: MutatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.name -# targets: -# - select: -# kind: MutatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# -# - source: # Uncomment the following block if you have a ConversionWebhook (--conversion) -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.namespace # Namespace of the certificate CR -# targets: -# - select: -# kind: CustomResourceDefinition -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.name -# targets: -# - select: -# kind: CustomResourceDefinition -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# -# - source: # Uncomment the following block if you enable cert-manager -# kind: Service -# version: v1 -# name: webhook-service -# fieldPath: .metadata.name # Name of the service -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# fieldPaths: -# - .spec.dnsNames.0 -# - .spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 0 -# create: true -# - source: -# kind: Service -# version: v1 -# name: webhook-service -# fieldPath: .metadata.namespace # Namespace of the service -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# fieldPaths: -# - .spec.dnsNames.0 -# - .spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 1 -# create: true diff --git a/testdata/project-v4-with-plugins/config/default/manager_metrics_patch.yaml b/testdata/project-v4-with-plugins/config/default/manager_metrics_patch.yaml deleted file mode 100644 index 2aaef6536f4..00000000000 --- a/testdata/project-v4-with-plugins/config/default/manager_metrics_patch.yaml +++ /dev/null @@ -1,4 +0,0 @@ -# This patch adds the args to allow exposing the metrics endpoint using HTTPS -- op: add - path: /spec/template/spec/containers/0/args/0 - value: --metrics-bind-address=:8443 diff --git a/testdata/project-v4-with-plugins/config/default/manager_webhook_patch.yaml b/testdata/project-v4-with-plugins/config/default/manager_webhook_patch.yaml deleted file mode 100644 index 34989fbbeb1..00000000000 --- a/testdata/project-v4-with-plugins/config/default/manager_webhook_patch.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize -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-v4-with-plugins/config/default/metrics_service.yaml b/testdata/project-v4-with-plugins/config/default/metrics_service.yaml deleted file mode 100644 index 45339096982..00000000000 --- a/testdata/project-v4-with-plugins/config/default/metrics_service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: controller-manager-metrics-service - namespace: system -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: 8443 - selector: - control-plane: controller-manager diff --git a/testdata/project-v4-with-plugins/config/manager/kustomization.yaml b/testdata/project-v4-with-plugins/config/manager/kustomization.yaml deleted file mode 100644 index ad13e96b3fc..00000000000 --- a/testdata/project-v4-with-plugins/config/manager/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -resources: -- manager.yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -images: -- name: controller - newName: controller - newTag: latest diff --git a/testdata/project-v4-with-plugins/config/manager/manager.yaml b/testdata/project-v4-with-plugins/config/manager/manager.yaml deleted file mode 100644 index b04cea1a357..00000000000 --- a/testdata/project-v4-with-plugins/config/manager/manager.yaml +++ /dev/null @@ -1,100 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: system ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system - labels: - control-plane: controller-manager - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize -spec: - selector: - matchLabels: - control-plane: controller-manager - replicas: 1 - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - control-plane: controller-manager - spec: - # TODO(user): Uncomment the following code to configure the nodeAffinity expression - # according to the platforms which are supported by your solution. - # It is considered best practice to support multiple architectures. You can - # build your manager image using the makefile target docker-buildx. - # affinity: - # nodeAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # nodeSelectorTerms: - # - matchExpressions: - # - key: kubernetes.io/arch - # operator: In - # values: - # - amd64 - # - arm64 - # - ppc64le - # - s390x - # - key: kubernetes.io/os - # operator: In - # values: - # - linux - securityContext: - runAsNonRoot: true - # TODO(user): For common cases that do not require escalating privileges - # it is recommended to ensure that all your Pods/Containers are restrictive. - # More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - # Please uncomment the following code if your project does NOT have to work on old Kubernetes - # versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ). - # seccompProfile: - # type: RuntimeDefault - containers: - - command: - - /manager - args: - - --leader-elect - - --health-probe-bind-address=:8081 - image: controller:latest - name: manager - env: - - name: BUSYBOX_IMAGE - value: busybox:1.36.1 - - name: MEMCACHED_IMAGE - value: memcached:memcached:1.6.26-alpine3.19 - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - # TODO(user): Configure the resources accordingly based on the project requirements. - # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - serviceAccountName: controller-manager - terminationGracePeriodSeconds: 10 diff --git a/testdata/project-v4-with-plugins/config/network-policy/allow-metrics-traffic.yaml b/testdata/project-v4-with-plugins/config/network-policy/allow-metrics-traffic.yaml deleted file mode 100644 index c7a0bf9dd58..00000000000 --- a/testdata/project-v4-with-plugins/config/network-policy/allow-metrics-traffic.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# This NetworkPolicy allows ingress traffic -# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those -# namespaces are able to gathering data from the metrics endpoint. -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: allow-metrics-traffic - namespace: system -spec: - podSelector: - matchLabels: - control-plane: controller-manager - policyTypes: - - Ingress - ingress: - # This allows ingress traffic from any namespace with the label metrics: enabled - - from: - - namespaceSelector: - matchLabels: - metrics: enabled # Only from namespaces with this label - ports: - - port: 8443 - protocol: TCP diff --git a/testdata/project-v4-with-plugins/config/network-policy/allow-webhook-traffic.yaml b/testdata/project-v4-with-plugins/config/network-policy/allow-webhook-traffic.yaml deleted file mode 100644 index c75092b53e2..00000000000 --- a/testdata/project-v4-with-plugins/config/network-policy/allow-webhook-traffic.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# This NetworkPolicy allows ingress traffic to your webhook server running -# as part of the controller-manager from specific namespaces and pods. CR(s) which uses webhooks -# will only work when applied in namespaces labeled with 'webhook: enabled' -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: allow-webhook-traffic - namespace: system -spec: - podSelector: - matchLabels: - control-plane: controller-manager - policyTypes: - - Ingress - ingress: - # This allows ingress traffic from any namespace with the label webhook: enabled - - from: - - namespaceSelector: - matchLabels: - webhook: enabled # Only from namespaces with this label - ports: - - port: 443 - protocol: TCP diff --git a/testdata/project-v4-with-plugins/config/network-policy/kustomization.yaml b/testdata/project-v4-with-plugins/config/network-policy/kustomization.yaml deleted file mode 100644 index 0872bee124c..00000000000 --- a/testdata/project-v4-with-plugins/config/network-policy/kustomization.yaml +++ /dev/null @@ -1,3 +0,0 @@ -resources: -- allow-webhook-traffic.yaml -- allow-metrics-traffic.yaml diff --git a/testdata/project-v4-with-plugins/config/prometheus/kustomization.yaml b/testdata/project-v4-with-plugins/config/prometheus/kustomization.yaml deleted file mode 100644 index ed137168a1d..00000000000 --- a/testdata/project-v4-with-plugins/config/prometheus/kustomization.yaml +++ /dev/null @@ -1,2 +0,0 @@ -resources: -- monitor.yaml diff --git a/testdata/project-v4-with-plugins/config/prometheus/monitor.yaml b/testdata/project-v4-with-plugins/config/prometheus/monitor.yaml deleted file mode 100644 index 58e9d5440eb..00000000000 --- a/testdata/project-v4-with-plugins/config/prometheus/monitor.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# Prometheus Monitor Service (Metrics) -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: controller-manager-metrics-monitor - namespace: system -spec: - endpoints: - - path: /metrics - port: https # Ensure this is the name of the port that exposes HTTPS metrics - scheme: https - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - tlsConfig: - # TODO(user): The option insecureSkipVerify: true is not recommended for production since it disables - # certificate verification. This poses a significant security risk by making the system vulnerable to - # man-in-the-middle attacks, where an attacker could intercept and manipulate the communication between - # Prometheus and the monitored services. This could lead to unauthorized access to sensitive metrics data, - # compromising the integrity and confidentiality of the information. - # Please use the following options for secure configurations: - # caFile: /etc/metrics-certs/ca.crt - # certFile: /etc/metrics-certs/tls.crt - # keyFile: /etc/metrics-certs/tls.key - insecureSkipVerify: true - selector: - matchLabels: - control-plane: controller-manager diff --git a/testdata/project-v4-with-plugins/config/rbac/busybox_editor_role.yaml b/testdata/project-v4-with-plugins/config/rbac/busybox_editor_role.yaml deleted file mode 100644 index cce1597dd9b..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/busybox_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit busyboxes. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: busybox-editor-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - verbs: - - get diff --git a/testdata/project-v4-with-plugins/config/rbac/busybox_viewer_role.yaml b/testdata/project-v4-with-plugins/config/rbac/busybox_viewer_role.yaml deleted file mode 100644 index 9ff4ba57069..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/busybox_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view busyboxes. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: busybox-viewer-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - verbs: - - get - - list - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - verbs: - - get diff --git a/testdata/project-v4-with-plugins/config/rbac/kustomization.yaml b/testdata/project-v4-with-plugins/config/rbac/kustomization.yaml deleted file mode 100644 index 60653a8cf59..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/kustomization.yaml +++ /dev/null @@ -1,29 +0,0 @@ -resources: -# All RBAC will be applied under this service account in -# the deployment namespace. You may comment out this resource -# if your manager will use a service account that exists at -# runtime. Be sure to update RoleBinding and ClusterRoleBinding -# subjects if changing service account names. -- service_account.yaml -- role.yaml -- role_binding.yaml -- leader_election_role.yaml -- leader_election_role_binding.yaml -# The following RBAC configurations are used to protect -# the metrics endpoint with authn/authz. These configurations -# ensure that only authorized users and service accounts -# can access the metrics endpoint. Comment the following -# permissions if you want to disable this protection. -# More info: https://book.kubebuilder.io/reference/metrics.html -- metrics_auth_role.yaml -- metrics_auth_role_binding.yaml -- metrics_reader_role.yaml -# For each CRD, "Editor" and "Viewer" roles are scaffolded by -# default, aiding admins in cluster management. Those roles are -# not used by the Project itself. You can comment the following lines -# if you do not want those helpers be installed with your Project. -- busybox_editor_role.yaml -- busybox_viewer_role.yaml -- memcached_editor_role.yaml -- memcached_viewer_role.yaml - diff --git a/testdata/project-v4-with-plugins/config/rbac/leader_election_role.yaml b/testdata/project-v4-with-plugins/config/rbac/leader_election_role.yaml deleted file mode 100644 index 330d2352ba7..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/leader_election_role.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# permissions to do leader election. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: leader-election-role -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch diff --git a/testdata/project-v4-with-plugins/config/rbac/leader_election_role_binding.yaml b/testdata/project-v4-with-plugins/config/rbac/leader_election_role_binding.yaml deleted file mode 100644 index b86da7901f0..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/leader_election_role_binding.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: leader-election-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: leader-election-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/testdata/project-v4-with-plugins/config/rbac/memcached_editor_role.yaml b/testdata/project-v4-with-plugins/config/rbac/memcached_editor_role.yaml deleted file mode 100644 index 37feccf6a64..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/memcached_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit memcacheds. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: memcached-editor-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/status - verbs: - - get diff --git a/testdata/project-v4-with-plugins/config/rbac/memcached_viewer_role.yaml b/testdata/project-v4-with-plugins/config/rbac/memcached_viewer_role.yaml deleted file mode 100644 index 655f7986162..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/memcached_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view memcacheds. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: memcached-viewer-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds - verbs: - - get - - list - - watch -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/status - verbs: - - get diff --git a/testdata/project-v4-with-plugins/config/rbac/metrics_auth_role.yaml b/testdata/project-v4-with-plugins/config/rbac/metrics_auth_role.yaml deleted file mode 100644 index 32d2e4ec6b0..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/metrics_auth_role.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: metrics-auth-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create diff --git a/testdata/project-v4-with-plugins/config/rbac/metrics_auth_role_binding.yaml b/testdata/project-v4-with-plugins/config/rbac/metrics_auth_role_binding.yaml deleted file mode 100644 index e775d67ff08..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/metrics_auth_role_binding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: metrics-auth-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: metrics-auth-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/testdata/project-v4-with-plugins/config/rbac/metrics_reader_role.yaml b/testdata/project-v4-with-plugins/config/rbac/metrics_reader_role.yaml deleted file mode 100644 index 51a75db47a5..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/metrics_reader_role.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: metrics-reader -rules: -- nonResourceURLs: - - "/metrics" - verbs: - - get diff --git a/testdata/project-v4-with-plugins/config/rbac/role.yaml b/testdata/project-v4-with-plugins/config/rbac/role.yaml deleted file mode 100644 index a2db0d25cca..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/role.yaml +++ /dev/null @@ -1,62 +0,0 @@ ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: manager-role -rules: -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch -- apiGroups: - - "" - resources: - - pods - verbs: - - get - - list - - watch -- apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - - memcacheds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/finalizers - - memcacheds/finalizers - verbs: - - update -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - - memcacheds/status - verbs: - - get - - patch - - update diff --git a/testdata/project-v4-with-plugins/config/rbac/role_binding.yaml b/testdata/project-v4-with-plugins/config/rbac/role_binding.yaml deleted file mode 100644 index e9c53696a9e..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/role_binding.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: manager-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/testdata/project-v4-with-plugins/config/rbac/service_account.yaml b/testdata/project-v4-with-plugins/config/rbac/service_account.yaml deleted file mode 100644 index 3f3872d879f..00000000000 --- a/testdata/project-v4-with-plugins/config/rbac/service_account.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: controller-manager - namespace: system diff --git a/testdata/project-v4-with-plugins/config/samples/example.com_v1alpha1_busybox.yaml b/testdata/project-v4-with-plugins/config/samples/example.com_v1alpha1_busybox.yaml deleted file mode 100644 index 2265d1caf7f..00000000000 --- a/testdata/project-v4-with-plugins/config/samples/example.com_v1alpha1_busybox.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: example.com.testproject.org/v1alpha1 -kind: Busybox -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: busybox-sample -spec: - # TODO(user): edit the following value to ensure the number - # of Pods/Instances your Operand must have on cluster - size: 1 diff --git a/testdata/project-v4-with-plugins/config/samples/example.com_v1alpha1_memcached.yaml b/testdata/project-v4-with-plugins/config/samples/example.com_v1alpha1_memcached.yaml deleted file mode 100644 index e15fd410c68..00000000000 --- a/testdata/project-v4-with-plugins/config/samples/example.com_v1alpha1_memcached.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: example.com.testproject.org/v1alpha1 -kind: Memcached -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: memcached-sample -spec: - # TODO(user): edit the following value to ensure the number - # of Pods/Instances your Operand must have on cluster - size: 1 - - # TODO(user): edit the following value to ensure the container has the right port to be initialized - containerPort: 11211 diff --git a/testdata/project-v4-with-plugins/config/samples/kustomization.yaml b/testdata/project-v4-with-plugins/config/samples/kustomization.yaml deleted file mode 100644 index 44b0f44adcb..00000000000 --- a/testdata/project-v4-with-plugins/config/samples/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -## Append samples of your project ## -resources: -- example.com_v1alpha1_memcached.yaml -- example.com_v1alpha1_busybox.yaml -# +kubebuilder:scaffold:manifestskustomizesamples diff --git a/testdata/project-v4-with-plugins/config/webhook/kustomization.yaml b/testdata/project-v4-with-plugins/config/webhook/kustomization.yaml deleted file mode 100644 index 9cf26134e4d..00000000000 --- a/testdata/project-v4-with-plugins/config/webhook/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -resources: -- manifests.yaml -- service.yaml - -configurations: -- kustomizeconfig.yaml diff --git a/testdata/project-v4-with-plugins/config/webhook/kustomizeconfig.yaml b/testdata/project-v4-with-plugins/config/webhook/kustomizeconfig.yaml deleted file mode 100644 index 206316e54ff..00000000000 --- a/testdata/project-v4-with-plugins/config/webhook/kustomizeconfig.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# the following config is for teaching kustomize where to look at when substituting nameReference. -# 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 diff --git a/testdata/project-v4-with-plugins/config/webhook/manifests.yaml b/testdata/project-v4-with-plugins/config/webhook/manifests.yaml deleted file mode 100644 index 99b797e22f4..00000000000 --- a/testdata/project-v4-with-plugins/config/webhook/manifests.yaml +++ /dev/null @@ -1,26 +0,0 @@ ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: validating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /validate-example-com-testproject-org-v1alpha1-memcached - failurePolicy: Fail - name: vmemcached-v1alpha1.kb.io - rules: - - apiGroups: - - example.com.testproject.org - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - memcacheds - sideEffects: None diff --git a/testdata/project-v4-with-plugins/config/webhook/service.yaml b/testdata/project-v4-with-plugins/config/webhook/service.yaml deleted file mode 100644 index a2c259db493..00000000000 --- a/testdata/project-v4-with-plugins/config/webhook/service.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/name: project-v4-with-plugins - app.kubernetes.io/managed-by: kustomize - name: webhook-service - namespace: system -spec: - ports: - - port: 443 - protocol: TCP - targetPort: 9443 - selector: - control-plane: controller-manager diff --git a/testdata/project-v4-with-plugins/dist/install.yaml b/testdata/project-v4-with-plugins/dist/install.yaml deleted file mode 100644 index 7969821c0be..00000000000 --- a/testdata/project-v4-with-plugins/dist/install.yaml +++ /dev/null @@ -1,678 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - control-plane: controller-manager - name: project-v4-with-plugins-system ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: busyboxes.example.com.testproject.org -spec: - group: example.com.testproject.org - names: - kind: Busybox - listKind: BusyboxList - plural: busyboxes - singular: busybox - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Busybox is the Schema for the busyboxes 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: BusyboxSpec defines the desired state of Busybox - properties: - size: - description: |- - Size defines the number of Busybox instances - The following markers will use OpenAPI v3 schema to validate the value - More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - format: int32 - maximum: 3 - minimum: 1 - type: integer - type: object - status: - description: BusyboxStatus defines the observed state of Busybox - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: memcacheds.example.com.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - name: project-v4-with-plugins-webhook-service - namespace: project-v4-with-plugins-system - path: /convert - conversionReviewVersions: - - v1 - group: example.com.testproject.org - names: - kind: Memcached - listKind: MemcachedList - plural: memcacheds - singular: memcached - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Memcached is the Schema for the memcacheds 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: MemcachedSpec defines the desired state of Memcached - properties: - containerPort: - description: Port defines the port that will be used to init the container - with the image - format: int32 - type: integer - size: - description: |- - Size defines the number of Memcached instances - The following markers will use OpenAPI v3 schema to validate the value - More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - format: int32 - maximum: 3 - minimum: 1 - type: integer - type: object - status: - description: MemcachedStatus defines the observed state of Memcached - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - name: project-v4-with-plugins-controller-manager - namespace: project-v4-with-plugins-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - name: project-v4-with-plugins-leader-election-role - namespace: project-v4-with-plugins-system -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - name: project-v4-with-plugins-busybox-editor-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - name: project-v4-with-plugins-busybox-viewer-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - verbs: - - get - - list - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: project-v4-with-plugins-manager-role -rules: -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch -- apiGroups: - - "" - resources: - - pods - verbs: - - get - - list - - watch -- apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - - memcacheds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/finalizers - - memcacheds/finalizers - verbs: - - update -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - - memcacheds/status - verbs: - - get - - patch - - update ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - name: project-v4-with-plugins-memcached-editor-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - name: project-v4-with-plugins-memcached-viewer-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds - verbs: - - get - - list - - watch -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: project-v4-with-plugins-metrics-auth-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: project-v4-with-plugins-metrics-reader -rules: -- nonResourceURLs: - - /metrics - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - name: project-v4-with-plugins-leader-election-rolebinding - namespace: project-v4-with-plugins-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: project-v4-with-plugins-leader-election-role -subjects: -- kind: ServiceAccount - name: project-v4-with-plugins-controller-manager - namespace: project-v4-with-plugins-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - name: project-v4-with-plugins-manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-v4-with-plugins-manager-role -subjects: -- kind: ServiceAccount - name: project-v4-with-plugins-controller-manager - namespace: project-v4-with-plugins-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: project-v4-with-plugins-metrics-auth-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-v4-with-plugins-metrics-auth-role -subjects: -- kind: ServiceAccount - name: project-v4-with-plugins-controller-manager - namespace: project-v4-with-plugins-system ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - control-plane: controller-manager - name: project-v4-with-plugins-controller-manager-metrics-service - namespace: project-v4-with-plugins-system -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: 8443 - selector: - control-plane: controller-manager ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - name: project-v4-with-plugins-webhook-service - namespace: project-v4-with-plugins-system -spec: - ports: - - port: 443 - protocol: TCP - targetPort: 9443 - selector: - control-plane: controller-manager ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4-with-plugins - control-plane: controller-manager - name: project-v4-with-plugins-controller-manager - namespace: project-v4-with-plugins-system -spec: - replicas: 1 - selector: - matchLabels: - control-plane: controller-manager - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - control-plane: controller-manager - spec: - containers: - - args: - - --metrics-bind-address=:8443 - - --leader-elect - - --health-probe-bind-address=:8081 - command: - - /manager - env: - - name: BUSYBOX_IMAGE - value: busybox:1.36.1 - - name: MEMCACHED_IMAGE - value: memcached:memcached:1.6.26-alpine3.19 - image: controller:latest - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - name: manager - ports: - - containerPort: 9443 - name: webhook-server - protocol: TCP - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - volumeMounts: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cert - readOnly: true - securityContext: - runAsNonRoot: true - serviceAccountName: project-v4-with-plugins-controller-manager - terminationGracePeriodSeconds: 10 - volumes: - - name: cert - secret: - defaultMode: 420 - secretName: webhook-server-cert ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: project-v4-with-plugins-validating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-with-plugins-webhook-service - namespace: project-v4-with-plugins-system - path: /validate-example-com-testproject-org-v1alpha1-memcached - failurePolicy: Fail - name: vmemcached-v1alpha1.kb.io - rules: - - apiGroups: - - example.com.testproject.org - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - memcacheds - sideEffects: None diff --git a/testdata/project-v4-with-plugins/go.mod b/testdata/project-v4-with-plugins/go.mod deleted file mode 100644 index 6e87ffd0948..00000000000 --- a/testdata/project-v4-with-plugins/go.mod +++ /dev/null @@ -1,98 +0,0 @@ -module sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins - -go 1.22.0 - -require ( - github.com/onsi/ginkgo/v2 v2.19.0 - github.com/onsi/gomega v1.33.1 - k8s.io/api v0.31.0 - k8s.io/apimachinery v0.31.0 - k8s.io/client-go v0.31.0 - sigs.k8s.io/controller-runtime v0.19.0 -) - -require ( - github.com/antlr4-go/antlr/v4 v4.13.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/google/cel-go v0.20.1 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect - github.com/imdario/mergo v0.3.6 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect - github.com/spf13/cobra v1.8.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/stoewer/go-strcase v1.2.0 // indirect - github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/sdk v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect - google.golang.org/grpc v1.65.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.31.0 // indirect - k8s.io/apiserver v0.31.0 // indirect - k8s.io/component-base v0.31.0 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect -) diff --git a/testdata/project-v4-with-plugins/grafana/controller-resources-metrics.json b/testdata/project-v4-with-plugins/grafana/controller-resources-metrics.json deleted file mode 100644 index 629e0d3c9b1..00000000000 --- a/testdata/project-v4-with-plugins/grafana/controller-resources-metrics.json +++ /dev/null @@ -1,306 +0,0 @@ -{ - "__inputs": [ - { - "name": "DS_PROMETHEUS", - "label": "Prometheus", - "description": "", - "type": "datasource", - "pluginId": "prometheus", - "pluginName": "Prometheus" - } - ], - "__requires": [ - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "1.0.0" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "links": [], - "liveNow": false, - "panels": [ - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "percent" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 0 - }, - "id": 2, - "interval": "1m", - "links": [], - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.4.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "rate(process_cpu_seconds_total{job=\"$job\", namespace=\"$namespace\", pod=\"$pod\"}[5m]) * 100", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "Pod: {{pod}} | Container: {{container}}", - "refId": "A", - "step": 10 - } - ], - "title": "Controller CPU Usage", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 0 - }, - "id": 4, - "interval": "1m", - "links": [], - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.4.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "process_resident_memory_bytes{job=\"$job\", namespace=\"$namespace\", pod=\"$pod\"}", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "Pod: {{pod}} | Container: {{container}}", - "refId": "A", - "step": 10 - } - ], - "title": "Controller Memory Usage", - "type": "timeseries" - } - ], - "refresh": "", - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "job", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "current": { - "selected": false, - "text": "observability", - "value": "observability" - }, - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total, namespace)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "namespace", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total, namespace)", - "refId": "StandardVariableQuery" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "current": { - "selected": false, - "text": "All", - "value": "$__all" - }, - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "hide": 2, - "includeAll": true, - "label": "pod", - "multi": true, - "name": "pod", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Controller-Resources-Metrics", - "weekStart": "" -} diff --git a/testdata/project-v4-with-plugins/grafana/controller-runtime-metrics.json b/testdata/project-v4-with-plugins/grafana/controller-runtime-metrics.json deleted file mode 100644 index c8eea4cb434..00000000000 --- a/testdata/project-v4-with-plugins/grafana/controller-runtime-metrics.json +++ /dev/null @@ -1,898 +0,0 @@ -{ - "__inputs": [ - { - "name": "DS_PROMETHEUS", - "label": "Prometheus", - "description": "", - "type": "datasource", - "pluginId": "prometheus", - "pluginName": "Prometheus" - } - ], - "__requires": [ - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "1.0.0" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "links": [], - "liveNow": false, - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 9, - "panels": [], - "title": "Reconciliation Metrics", - "type": "row" - }, - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "percentage", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "orange", - "value": 70 - }, - { - "color": "red", - "value": 85 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 3, - "x": 0, - "y": 1 - }, - "id": 24, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "controller_runtime_active_workers{job=\"$job\", namespace=\"$namespace\"}", - "interval": "", - "legendFormat": "{{controller}} {{instance}}", - "refId": "A" - } - ], - "title": "Number of workers in use", - "type": "gauge" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "Total number of reconciliations per controller", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "cpm" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 11, - "x": 3, - "y": 1 - }, - "id": 7, - "options": { - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "editorMode": "code", - "exemplar": true, - "expr": "sum(rate(controller_runtime_reconcile_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, pod)", - "interval": "", - "legendFormat": "{{instance}} {{pod}}", - "range": true, - "refId": "A" - } - ], - "title": "Total Reconciliation Count Per Controller", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "Total number of reconciliation errors per controller", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "cpm" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 10, - "x": 14, - "y": 1 - }, - "id": 6, - "options": { - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "editorMode": "code", - "exemplar": true, - "expr": "sum(rate(controller_runtime_reconcile_errors_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, pod)", - "interval": "", - "legendFormat": "{{instance}} {{pod}}", - "range": true, - "refId": "A" - } - ], - "title": "Reconciliation Error Count Per Controller", - "type": "timeseries" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 9 - }, - "id": 11, - "panels": [], - "title": "Work Queue Metrics", - "type": "row" - }, - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "percentage", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "orange", - "value": 70 - }, - { - "color": "red", - "value": 85 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 3, - "x": 0, - "y": 10 - }, - "id": 22, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "workqueue_depth{job=\"$job\", namespace=\"$namespace\"}", - "interval": "", - "legendFormat": "", - "refId": "A" - } - ], - "title": "WorkQueue Depth", - "type": "gauge" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "How long in seconds an item stays in workqueue before being requested", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "normal" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 11, - "x": 3, - "y": 10 - }, - "id": 13, - "options": { - "legend": { - "calcs": [ - "max", - "mean" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.50, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "interval": "", - "legendFormat": "P50 {{name}} {{instance}} ", - "refId": "A" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.90, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P90 {{name}} {{instance}} ", - "refId": "B" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P99 {{name}} {{instance}} ", - "refId": "C" - } - ], - "title": "Seconds For Items Stay In Queue (before being requested) (P50, P90, P99)", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "ops" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 10, - "x": 14, - "y": 10 - }, - "id": 15, - "options": { - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.4.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "sum(rate(workqueue_adds_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name)", - "interval": "", - "legendFormat": "{{name}} {{instance}}", - "refId": "A" - } - ], - "title": "Work Queue Add Rate", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "How many seconds of work has done that is in progress and hasn't been observed by work_duration.\nLarge values indicate stuck threads.\nOne can deduce the number of stuck threads by observing the rate at which this increases.", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "percentage", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "orange", - "value": 70 - }, - { - "color": "red", - "value": 85 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 9, - "w": 3, - "x": 0, - "y": 18 - }, - "id": 23, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "rate(workqueue_unfinished_work_seconds{job=\"$job\", namespace=\"$namespace\"}[5m])", - "interval": "", - "legendFormat": "", - "refId": "A" - } - ], - "title": "Unfinished Seconds", - "type": "gauge" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "How long in seconds processing an item from workqueue takes.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 9, - "w": 11, - "x": 3, - "y": 18 - }, - "id": 19, - "options": { - "legend": { - "calcs": [ - "max", - "mean" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.50, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "interval": "", - "legendFormat": "P50 {{name}} {{instance}} ", - "refId": "A" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.90, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P90 {{name}} {{instance}} ", - "refId": "B" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.99, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P99 {{name}} {{instance}} ", - "refId": "C" - } - ], - "title": "Seconds Processing Items From WorkQueue (P50, P90, P99)", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "Total number of retries handled by workqueue", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "ops" - }, - "overrides": [] - }, - "gridPos": { - "h": 9, - "w": 10, - "x": 14, - "y": 18 - }, - "id": 17, - "options": { - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "sum(rate(workqueue_retries_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name)", - "interval": "", - "legendFormat": "{{name}} {{instance}} ", - "refId": "A" - } - ], - "title": "Work Queue Retries Rate", - "type": "timeseries" - } - ], - "refresh": "", - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "job", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total, namespace)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "namespace", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total, namespace)", - "refId": "StandardVariableQuery" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "current": { - "selected": true, - "text": [ - "All" - ], - "value": [ - "$__all" - ] - }, - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "hide": 2, - "includeAll": true, - "label": "pod", - "multi": true, - "name": "pod", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Controller-Runtime-Metrics", - "weekStart": "" -} diff --git a/testdata/project-v4-with-plugins/grafana/custom-metrics/config.yaml b/testdata/project-v4-with-plugins/grafana/custom-metrics/config.yaml deleted file mode 100644 index 3ee1bebdf24..00000000000 --- a/testdata/project-v4-with-plugins/grafana/custom-metrics/config.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -customMetrics: -# - metric: # Raw custom metric (required) -# type: # Metric type: counter/gauge/histogram (required) -# expr: # Prom_ql for the metric (optional) -# unit: # Unit of measurement, examples: s,none,bytes,percent,etc. (optional) -# -# -# Example: -# --- -# customMetrics: -# - metric: foo_bar -# unit: none -# type: histogram -# expr: histogram_quantile(0.90, sum by(instance, le) (rate(foo_bar{job=\"$job\", namespace=\"$namespace\"}[5m]))) diff --git a/testdata/project-v4-with-plugins/hack/boilerplate.go.txt b/testdata/project-v4-with-plugins/hack/boilerplate.go.txt deleted file mode 100644 index 0d32012672a..00000000000 --- a/testdata/project-v4-with-plugins/hack/boilerplate.go.txt +++ /dev/null @@ -1,15 +0,0 @@ -/* -Copyright 2024 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-v4-with-plugins/internal/controller/busybox_controller.go b/testdata/project-v4-with-plugins/internal/controller/busybox_controller.go deleted file mode 100644 index 792e34a2a7e..00000000000 --- a/testdata/project-v4-with-plugins/internal/controller/busybox_controller.go +++ /dev/null @@ -1,443 +0,0 @@ -/* -Copyright 2024 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 controller - -import ( - "context" - "fmt" - "os" - "strings" - "time" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/log" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1alpha1" -) - -const busyboxFinalizer = "example.com.testproject.org/finalizer" - -// Definitions to manage status conditions -const ( - // typeAvailableBusybox represents the status of the Deployment reconciliation - typeAvailableBusybox = "Available" - // typeDegradedBusybox represents the status used when the custom resource is deleted and the finalizer operations are yet to occur. - typeDegradedBusybox = "Degraded" -) - -// BusyboxReconciler reconciles a Busybox object -type BusyboxReconciler struct { - client.Client - Scheme *runtime.Scheme - Recorder record.EventRecorder -} - -// The following markers are used to generate the rules permissions (RBAC) on config/rbac using controller-gen -// when the command is executed. -// To know more about markers see: https://book.kubebuilder.io/reference/markers.html - -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=busyboxes,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=busyboxes/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=busyboxes/finalizers,verbs=update -// +kubebuilder:rbac:groups=core,resources=events,verbs=create;patch -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// It is essential for the controller's reconciliation loop to be idempotent. By following the Operator -// pattern you will create Controllers which provide a reconcile function -// responsible for synchronizing resources until the desired state is reached on the cluster. -// Breaking this recommendation goes against the design principles of controller-runtime. -// and may lead to unforeseen consequences such as resources becoming stuck and requiring manual intervention. -// For further info: -// - About Operator Pattern: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/ -// - About Controllers: https://kubernetes.io/docs/concepts/architecture/controller/ -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/reconcile -func (r *BusyboxReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - log := log.FromContext(ctx) - - // Fetch the Busybox instance - // The purpose is check if the Custom Resource for the Kind Busybox - // is applied on the cluster if not we return nil to stop the reconciliation - busybox := &examplecomv1alpha1.Busybox{} - err := r.Get(ctx, req.NamespacedName, busybox) - if err != nil { - if apierrors.IsNotFound(err) { - // If the custom resource is not found then it usually means that it was deleted or not created - // In this way, we will stop the reconciliation - log.Info("busybox resource not found. Ignoring since object must be deleted") - return ctrl.Result{}, nil - } - // Error reading the object - requeue the request. - log.Error(err, "Failed to get busybox") - return ctrl.Result{}, err - } - - // Let's just set the status as Unknown when no status is available - if busybox.Status.Conditions == nil || len(busybox.Status.Conditions) == 0 { - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, Status: metav1.ConditionUnknown, Reason: "Reconciling", Message: "Starting reconciliation"}) - if err = r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - // Let's re-fetch the busybox Custom Resource after updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - // if we try to update it again in the following operations - if err := r.Get(ctx, req.NamespacedName, busybox); err != nil { - log.Error(err, "Failed to re-fetch busybox") - return ctrl.Result{}, err - } - } - - // Let's add a finalizer. Then, we can define some operations which should - // occur before the custom resource is deleted. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers - if !controllerutil.ContainsFinalizer(busybox, busyboxFinalizer) { - log.Info("Adding Finalizer for Busybox") - if ok := controllerutil.AddFinalizer(busybox, busyboxFinalizer); !ok { - log.Error(err, "Failed to add finalizer into the custom resource") - return ctrl.Result{Requeue: true}, nil - } - - if err = r.Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update custom resource to add finalizer") - return ctrl.Result{}, err - } - } - - // Check if the Busybox instance is marked to be deleted, which is - // indicated by the deletion timestamp being set. - isBusyboxMarkedToBeDeleted := busybox.GetDeletionTimestamp() != nil - if isBusyboxMarkedToBeDeleted { - if controllerutil.ContainsFinalizer(busybox, busyboxFinalizer) { - log.Info("Performing Finalizer Operations for Busybox before delete CR") - - // Let's add here a status "Downgrade" to reflect that this resource began its process to be terminated. - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeDegradedBusybox, - Status: metav1.ConditionUnknown, Reason: "Finalizing", - Message: fmt.Sprintf("Performing finalizer operations for the custom resource: %s ", busybox.Name)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - // Perform all operations required before removing the finalizer and allow - // the Kubernetes API to remove the custom resource. - r.doFinalizerOperationsForBusybox(busybox) - - // TODO(user): If you add operations to the doFinalizerOperationsForBusybox method - // then you need to ensure that all worked fine before deleting and updating the Downgrade status - // otherwise, you should requeue here. - - // Re-fetch the busybox Custom Resource before updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, busybox); err != nil { - log.Error(err, "Failed to re-fetch busybox") - return ctrl.Result{}, err - } - - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeDegradedBusybox, - Status: metav1.ConditionTrue, Reason: "Finalizing", - Message: fmt.Sprintf("Finalizer operations for custom resource %s name were successfully accomplished", busybox.Name)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - log.Info("Removing Finalizer for Busybox after successfully perform the operations") - if ok := controllerutil.RemoveFinalizer(busybox, busyboxFinalizer); !ok { - log.Error(err, "Failed to remove finalizer for Busybox") - return ctrl.Result{Requeue: true}, nil - } - - if err := r.Update(ctx, busybox); err != nil { - log.Error(err, "Failed to remove finalizer for Busybox") - return ctrl.Result{}, err - } - } - return ctrl.Result{}, nil - } - - // Check if the deployment already exists, if not create a new one - found := &appsv1.Deployment{} - err = r.Get(ctx, types.NamespacedName{Name: busybox.Name, Namespace: busybox.Namespace}, found) - if err != nil && apierrors.IsNotFound(err) { - // Define a new deployment - dep, err := r.deploymentForBusybox(busybox) - if err != nil { - log.Error(err, "Failed to define new Deployment resource for Busybox") - - // The following implementation will update the status - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, - Status: metav1.ConditionFalse, Reason: "Reconciling", - Message: fmt.Sprintf("Failed to create Deployment for the custom resource (%s): (%s)", busybox.Name, err)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - log.Info("Creating a new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - if err = r.Create(ctx, dep); err != nil { - log.Error(err, "Failed to create new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - return ctrl.Result{}, err - } - - // Deployment created successfully - // We will requeue the reconciliation so that we can ensure the state - // and move forward for the next operations - return ctrl.Result{RequeueAfter: time.Minute}, nil - } else if err != nil { - log.Error(err, "Failed to get Deployment") - // Let's return the error for the reconciliation be re-trigged again - return ctrl.Result{}, err - } - - // The CRD API defines that the Busybox type have a BusyboxSpec.Size field - // to set the quantity of Deployment instances to the desired state on the cluster. - // Therefore, the following code will ensure the Deployment size is the same as defined - // via the Size spec of the Custom Resource which we are reconciling. - size := busybox.Spec.Size - if *found.Spec.Replicas != size { - found.Spec.Replicas = &size - if err = r.Update(ctx, found); err != nil { - log.Error(err, "Failed to update Deployment", - "Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name) - - // Re-fetch the busybox Custom Resource before updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, busybox); err != nil { - log.Error(err, "Failed to re-fetch busybox") - return ctrl.Result{}, err - } - - // The following implementation will update the status - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, - Status: metav1.ConditionFalse, Reason: "Resizing", - Message: fmt.Sprintf("Failed to update the size for the custom resource (%s): (%s)", busybox.Name, err)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - // Now, that we update the size we want to requeue the reconciliation - // so that we can ensure that we have the latest state of the resource before - // update. Also, it will help ensure the desired state on the cluster - return ctrl.Result{Requeue: true}, nil - } - - // The following implementation will update the status - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, - Status: metav1.ConditionTrue, Reason: "Reconciling", - Message: fmt.Sprintf("Deployment for custom resource (%s) with %d replicas created successfully", busybox.Name, size)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, nil -} - -// finalizeBusybox will perform the required operations before delete the CR. -func (r *BusyboxReconciler) doFinalizerOperationsForBusybox(cr *examplecomv1alpha1.Busybox) { - // TODO(user): Add the cleanup steps that the operator - // needs to do before the CR can be deleted. Examples - // of finalizers include performing backups and deleting - // resources that are not owned by this CR, like a PVC. - - // Note: It is not recommended to use finalizers with the purpose of deleting resources which are - // created and managed in the reconciliation. These ones, such as the Deployment created on this reconcile, - // are defined as dependent of the custom resource. See that we use the method ctrl.SetControllerReference. - // to set the ownerRef which means that the Deployment will be deleted by the Kubernetes API. - // More info: https://kubernetes.io/docs/tasks/administer-cluster/use-cascading-deletion/ - - // The following implementation will raise an event - r.Recorder.Event(cr, "Warning", "Deleting", - fmt.Sprintf("Custom Resource %s is being deleted from the namespace %s", - cr.Name, - cr.Namespace)) -} - -// deploymentForBusybox returns a Busybox Deployment object -func (r *BusyboxReconciler) deploymentForBusybox( - busybox *examplecomv1alpha1.Busybox) (*appsv1.Deployment, error) { - ls := labelsForBusybox() - replicas := busybox.Spec.Size - - // Get the Operand image - image, err := imageForBusybox() - if err != nil { - return nil, err - } - - dep := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: busybox.Name, - Namespace: busybox.Namespace, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: ls, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: ls, - }, - Spec: corev1.PodSpec{ - // TODO(user): Uncomment the following code to configure the nodeAffinity expression - // according to the platforms which are supported by your solution. It is considered - // best practice to support multiple architectures. build your manager image using the - // makefile target docker-buildx. Also, you can use docker manifest inspect - // to check what are the platforms supported. - // More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity - // Affinity: &corev1.Affinity{ - // NodeAffinity: &corev1.NodeAffinity{ - // RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ - // NodeSelectorTerms: []corev1.NodeSelectorTerm{ - // { - // MatchExpressions: []corev1.NodeSelectorRequirement{ - // { - // Key: "kubernetes.io/arch", - // Operator: "In", - // Values: []string{"amd64", "arm64", "ppc64le", "s390x"}, - // }, - // { - // Key: "kubernetes.io/os", - // Operator: "In", - // Values: []string{"linux"}, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - SecurityContext: &corev1.PodSecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - // IMPORTANT: seccomProfile was introduced with Kubernetes 1.19 - // If you are looking for to produce solutions to be supported - // on lower versions you must remove this option. - SeccompProfile: &corev1.SeccompProfile{ - Type: corev1.SeccompProfileTypeRuntimeDefault, - }, - }, - Containers: []corev1.Container{{ - Image: image, - Name: "busybox", - ImagePullPolicy: corev1.PullIfNotPresent, - // Ensure restrictive context for the container - // More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - SecurityContext: &corev1.SecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - AllowPrivilegeEscalation: &[]bool{false}[0], - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - }, - }}, - }, - }, - }, - } - - // Set the ownerRef for the Deployment - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/ - if err := ctrl.SetControllerReference(busybox, dep, r.Scheme); err != nil { - return nil, err - } - return dep, nil -} - -// labelsForBusybox returns the labels for selecting the resources -// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/ -func labelsForBusybox() map[string]string { - var imageTag string - image, err := imageForBusybox() - if err == nil { - imageTag = strings.Split(image, ":")[1] - } - return map[string]string{"app.kubernetes.io/name": "project-v4-with-plugins", - "app.kubernetes.io/version": imageTag, - "app.kubernetes.io/managed-by": "BusyboxController", - } -} - -// imageForBusybox gets the Operand image which is managed by this controller -// from the BUSYBOX_IMAGE environment variable defined in the config/manager/manager.yaml -func imageForBusybox() (string, error) { - var imageEnvVar = "BUSYBOX_IMAGE" - image, found := os.LookupEnv(imageEnvVar) - if !found { - return "", fmt.Errorf("Unable to find %s environment variable with the image", imageEnvVar) - } - return image, nil -} - -// SetupWithManager sets up the controller with the Manager. -// The whole idea is to be watching the resources that matter for the controller. -// When a resource that the controller is interested in changes, the Watch triggers -// the controller’s reconciliation loop, ensuring that the actual state of the resource -// matches the desired state as defined in the controller’s logic. -// -// Notice how we configured the Manager to monitor events such as the creation, update, -// or deletion of a Custom Resource (CR) of the Busybox kind, as well as any changes -// to the Deployment that the controller manages and owns. -func (r *BusyboxReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - // Watch the Busybox CR(s) and trigger reconciliation whenever it - // is created, updated, or deleted - For(&examplecomv1alpha1.Busybox{}). - Named("busybox"). - // Watch the Deployment managed by the BusyboxReconciler. If any changes occur to the Deployment - // owned and managed by this controller, it will trigger reconciliation, ensuring that the cluster - // state aligns with the desired state. See that the ownerRef was set when the Deployment was created. - Owns(&appsv1.Deployment{}). - Complete(r) -} diff --git a/testdata/project-v4-with-plugins/internal/controller/busybox_controller_test.go b/testdata/project-v4-with-plugins/internal/controller/busybox_controller_test.go deleted file mode 100644 index fb696269aa0..00000000000 --- a/testdata/project-v4-with-plugins/internal/controller/busybox_controller_test.go +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright 2024 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 controller - -import ( - "context" - "os" - "time" - - //nolint:golint - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1alpha1" -) - -var _ = Describe("Busybox controller", func() { - Context("Busybox controller test", func() { - - const BusyboxName = "test-busybox" - - ctx := context.Background() - - namespace := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: BusyboxName, - Namespace: BusyboxName, - }, - } - - typeNamespacedName := types.NamespacedName{ - Name: BusyboxName, - Namespace: BusyboxName, - } - busybox := &examplecomv1alpha1.Busybox{} - - SetDefaultEventuallyTimeout(2 * time.Minute) - SetDefaultEventuallyPollingInterval(time.Second) - - BeforeEach(func() { - By("Creating the Namespace to perform the tests") - err := k8sClient.Create(ctx, namespace) - Expect(err).NotTo(HaveOccurred()) - - By("Setting the Image ENV VAR which stores the Operand image") - err = os.Setenv("BUSYBOX_IMAGE", "example.com/image:test") - Expect(err).NotTo(HaveOccurred()) - - By("creating the custom resource for the Kind Busybox") - err = k8sClient.Get(ctx, typeNamespacedName, busybox) - if err != nil && errors.IsNotFound(err) { - // Let's mock our custom resource at the same way that we would - // apply on the cluster the manifest under config/samples - busybox := &examplecomv1alpha1.Busybox{ - ObjectMeta: metav1.ObjectMeta{ - Name: BusyboxName, - Namespace: namespace.Name, - }, - Spec: examplecomv1alpha1.BusyboxSpec{ - Size: 1, - }, - } - - err = k8sClient.Create(ctx, busybox) - Expect(err).NotTo(HaveOccurred()) - } - }) - - AfterEach(func() { - By("removing the custom resource for the Kind Busybox") - found := &examplecomv1alpha1.Busybox{} - err := k8sClient.Get(ctx, typeNamespacedName, found) - Expect(err).NotTo(HaveOccurred()) - - Eventually(func(g Gomega) { - g.Expect(k8sClient.Delete(context.TODO(), found)).To(Succeed()) - }).Should(Succeed()) - - // TODO(user): Attention if you improve this code by adding other context test you MUST - // be aware of the current delete namespace limitations. - // More info: https://book.kubebuilder.io/reference/envtest.html#testing-considerations - By("Deleting the Namespace to perform the tests") - _ = k8sClient.Delete(ctx, namespace) - - By("Removing the Image ENV VAR which stores the Operand image") - _ = os.Unsetenv("BUSYBOX_IMAGE") - }) - - It("should successfully reconcile a custom resource for Busybox", func() { - By("Checking if the custom resource was successfully created") - Eventually(func(g Gomega) { - found := &examplecomv1alpha1.Busybox{} - Expect(k8sClient.Get(ctx, typeNamespacedName, found)).To(Succeed()) - }).Should(Succeed()) - - By("Reconciling the custom resource created") - busyboxReconciler := &BusyboxReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := busyboxReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - - By("Checking if Deployment was successfully created in the reconciliation") - Eventually(func(g Gomega) { - found := &appsv1.Deployment{} - g.Expect(k8sClient.Get(ctx, typeNamespacedName, found)).To(Succeed()) - }).Should(Succeed()) - - By("Reconciling the custom resource again") - _, err = busyboxReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - - By("Checking the latest Status Condition added to the Busybox instance") - Expect(k8sClient.Get(ctx, typeNamespacedName, busybox)).To(Succeed()) - conditions := []metav1.Condition{} - Expect(busybox.Status.Conditions).To(ContainElement( - HaveField("Type", Equal(typeAvailableBusybox)), &conditions)) - Expect(conditions).To(HaveLen(1), "Multiple conditions of type %s", typeAvailableBusybox) - Expect(conditions[0].Status).To(Equal(metav1.ConditionTrue), "condition %s", typeAvailableBusybox) - Expect(conditions[0].Reason).To(Equal("Reconciling"), "condition %s", typeAvailableBusybox) - }) - }) -}) diff --git a/testdata/project-v4-with-plugins/internal/controller/memcached_controller.go b/testdata/project-v4-with-plugins/internal/controller/memcached_controller.go deleted file mode 100644 index 8d667ce4741..00000000000 --- a/testdata/project-v4-with-plugins/internal/controller/memcached_controller.go +++ /dev/null @@ -1,449 +0,0 @@ -/* -Copyright 2024 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 controller - -import ( - "context" - "fmt" - "os" - "strings" - "time" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/log" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1alpha1" -) - -const memcachedFinalizer = "example.com.testproject.org/finalizer" - -// Definitions to manage status conditions -const ( - // typeAvailableMemcached represents the status of the Deployment reconciliation - typeAvailableMemcached = "Available" - // typeDegradedMemcached represents the status used when the custom resource is deleted and the finalizer operations are yet to occur. - typeDegradedMemcached = "Degraded" -) - -// MemcachedReconciler reconciles a Memcached object -type MemcachedReconciler struct { - client.Client - Scheme *runtime.Scheme - Recorder record.EventRecorder -} - -// The following markers are used to generate the rules permissions (RBAC) on config/rbac using controller-gen -// when the command is executed. -// To know more about markers see: https://book.kubebuilder.io/reference/markers.html - -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=memcacheds/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=example.com.testproject.org,resources=memcacheds/finalizers,verbs=update -// +kubebuilder:rbac:groups=core,resources=events,verbs=create;patch -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// It is essential for the controller's reconciliation loop to be idempotent. By following the Operator -// pattern you will create Controllers which provide a reconcile function -// responsible for synchronizing resources until the desired state is reached on the cluster. -// Breaking this recommendation goes against the design principles of controller-runtime. -// and may lead to unforeseen consequences such as resources becoming stuck and requiring manual intervention. -// For further info: -// - About Operator Pattern: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/ -// - About Controllers: https://kubernetes.io/docs/concepts/architecture/controller/ -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/reconcile -func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - log := log.FromContext(ctx) - - // Fetch the Memcached instance - // The purpose is check if the Custom Resource for the Kind Memcached - // is applied on the cluster if not we return nil to stop the reconciliation - memcached := &examplecomv1alpha1.Memcached{} - err := r.Get(ctx, req.NamespacedName, memcached) - if err != nil { - if apierrors.IsNotFound(err) { - // If the custom resource is not found then it usually means that it was deleted or not created - // In this way, we will stop the reconciliation - log.Info("memcached resource not found. Ignoring since object must be deleted") - return ctrl.Result{}, nil - } - // Error reading the object - requeue the request. - log.Error(err, "Failed to get memcached") - return ctrl.Result{}, err - } - - // Let's just set the status as Unknown when no status is available - if memcached.Status.Conditions == nil || len(memcached.Status.Conditions) == 0 { - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, Status: metav1.ConditionUnknown, Reason: "Reconciling", Message: "Starting reconciliation"}) - if err = r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - // Let's re-fetch the memcached Custom Resource after updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - // if we try to update it again in the following operations - if err := r.Get(ctx, req.NamespacedName, memcached); err != nil { - log.Error(err, "Failed to re-fetch memcached") - return ctrl.Result{}, err - } - } - - // Let's add a finalizer. Then, we can define some operations which should - // occur before the custom resource is deleted. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers - if !controllerutil.ContainsFinalizer(memcached, memcachedFinalizer) { - log.Info("Adding Finalizer for Memcached") - if ok := controllerutil.AddFinalizer(memcached, memcachedFinalizer); !ok { - log.Error(err, "Failed to add finalizer into the custom resource") - return ctrl.Result{Requeue: true}, nil - } - - if err = r.Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update custom resource to add finalizer") - return ctrl.Result{}, err - } - } - - // Check if the Memcached instance is marked to be deleted, which is - // indicated by the deletion timestamp being set. - isMemcachedMarkedToBeDeleted := memcached.GetDeletionTimestamp() != nil - if isMemcachedMarkedToBeDeleted { - if controllerutil.ContainsFinalizer(memcached, memcachedFinalizer) { - log.Info("Performing Finalizer Operations for Memcached before delete CR") - - // Let's add here a status "Downgrade" to reflect that this resource began its process to be terminated. - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeDegradedMemcached, - Status: metav1.ConditionUnknown, Reason: "Finalizing", - Message: fmt.Sprintf("Performing finalizer operations for the custom resource: %s ", memcached.Name)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - // Perform all operations required before removing the finalizer and allow - // the Kubernetes API to remove the custom resource. - r.doFinalizerOperationsForMemcached(memcached) - - // TODO(user): If you add operations to the doFinalizerOperationsForMemcached method - // then you need to ensure that all worked fine before deleting and updating the Downgrade status - // otherwise, you should requeue here. - - // Re-fetch the memcached Custom Resource before updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, memcached); err != nil { - log.Error(err, "Failed to re-fetch memcached") - return ctrl.Result{}, err - } - - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeDegradedMemcached, - Status: metav1.ConditionTrue, Reason: "Finalizing", - Message: fmt.Sprintf("Finalizer operations for custom resource %s name were successfully accomplished", memcached.Name)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - log.Info("Removing Finalizer for Memcached after successfully perform the operations") - if ok := controllerutil.RemoveFinalizer(memcached, memcachedFinalizer); !ok { - log.Error(err, "Failed to remove finalizer for Memcached") - return ctrl.Result{Requeue: true}, nil - } - - if err := r.Update(ctx, memcached); err != nil { - log.Error(err, "Failed to remove finalizer for Memcached") - return ctrl.Result{}, err - } - } - return ctrl.Result{}, nil - } - - // Check if the deployment already exists, if not create a new one - found := &appsv1.Deployment{} - err = r.Get(ctx, types.NamespacedName{Name: memcached.Name, Namespace: memcached.Namespace}, found) - if err != nil && apierrors.IsNotFound(err) { - // Define a new deployment - dep, err := r.deploymentForMemcached(memcached) - if err != nil { - log.Error(err, "Failed to define new Deployment resource for Memcached") - - // The following implementation will update the status - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, - Status: metav1.ConditionFalse, Reason: "Reconciling", - Message: fmt.Sprintf("Failed to create Deployment for the custom resource (%s): (%s)", memcached.Name, err)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - log.Info("Creating a new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - if err = r.Create(ctx, dep); err != nil { - log.Error(err, "Failed to create new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - return ctrl.Result{}, err - } - - // Deployment created successfully - // We will requeue the reconciliation so that we can ensure the state - // and move forward for the next operations - return ctrl.Result{RequeueAfter: time.Minute}, nil - } else if err != nil { - log.Error(err, "Failed to get Deployment") - // Let's return the error for the reconciliation be re-trigged again - return ctrl.Result{}, err - } - - // The CRD API defines that the Memcached type have a MemcachedSpec.Size field - // to set the quantity of Deployment instances to the desired state on the cluster. - // Therefore, the following code will ensure the Deployment size is the same as defined - // via the Size spec of the Custom Resource which we are reconciling. - size := memcached.Spec.Size - if *found.Spec.Replicas != size { - found.Spec.Replicas = &size - if err = r.Update(ctx, found); err != nil { - log.Error(err, "Failed to update Deployment", - "Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name) - - // Re-fetch the memcached Custom Resource before updating the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raising the error "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, memcached); err != nil { - log.Error(err, "Failed to re-fetch memcached") - return ctrl.Result{}, err - } - - // The following implementation will update the status - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, - Status: metav1.ConditionFalse, Reason: "Resizing", - Message: fmt.Sprintf("Failed to update the size for the custom resource (%s): (%s)", memcached.Name, err)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - // Now, that we update the size we want to requeue the reconciliation - // so that we can ensure that we have the latest state of the resource before - // update. Also, it will help ensure the desired state on the cluster - return ctrl.Result{Requeue: true}, nil - } - - // The following implementation will update the status - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, - Status: metav1.ConditionTrue, Reason: "Reconciling", - Message: fmt.Sprintf("Deployment for custom resource (%s) with %d replicas created successfully", memcached.Name, size)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, nil -} - -// finalizeMemcached will perform the required operations before delete the CR. -func (r *MemcachedReconciler) doFinalizerOperationsForMemcached(cr *examplecomv1alpha1.Memcached) { - // TODO(user): Add the cleanup steps that the operator - // needs to do before the CR can be deleted. Examples - // of finalizers include performing backups and deleting - // resources that are not owned by this CR, like a PVC. - - // Note: It is not recommended to use finalizers with the purpose of deleting resources which are - // created and managed in the reconciliation. These ones, such as the Deployment created on this reconcile, - // are defined as dependent of the custom resource. See that we use the method ctrl.SetControllerReference. - // to set the ownerRef which means that the Deployment will be deleted by the Kubernetes API. - // More info: https://kubernetes.io/docs/tasks/administer-cluster/use-cascading-deletion/ - - // The following implementation will raise an event - r.Recorder.Event(cr, "Warning", "Deleting", - fmt.Sprintf("Custom Resource %s is being deleted from the namespace %s", - cr.Name, - cr.Namespace)) -} - -// deploymentForMemcached returns a Memcached Deployment object -func (r *MemcachedReconciler) deploymentForMemcached( - memcached *examplecomv1alpha1.Memcached) (*appsv1.Deployment, error) { - ls := labelsForMemcached() - replicas := memcached.Spec.Size - - // Get the Operand image - image, err := imageForMemcached() - if err != nil { - return nil, err - } - - dep := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: memcached.Name, - Namespace: memcached.Namespace, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: ls, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: ls, - }, - Spec: corev1.PodSpec{ - // TODO(user): Uncomment the following code to configure the nodeAffinity expression - // according to the platforms which are supported by your solution. It is considered - // best practice to support multiple architectures. build your manager image using the - // makefile target docker-buildx. Also, you can use docker manifest inspect - // to check what are the platforms supported. - // More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity - // Affinity: &corev1.Affinity{ - // NodeAffinity: &corev1.NodeAffinity{ - // RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ - // NodeSelectorTerms: []corev1.NodeSelectorTerm{ - // { - // MatchExpressions: []corev1.NodeSelectorRequirement{ - // { - // Key: "kubernetes.io/arch", - // Operator: "In", - // Values: []string{"amd64", "arm64", "ppc64le", "s390x"}, - // }, - // { - // Key: "kubernetes.io/os", - // Operator: "In", - // Values: []string{"linux"}, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - SecurityContext: &corev1.PodSecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - // IMPORTANT: seccomProfile was introduced with Kubernetes 1.19 - // If you are looking for to produce solutions to be supported - // on lower versions you must remove this option. - SeccompProfile: &corev1.SeccompProfile{ - Type: corev1.SeccompProfileTypeRuntimeDefault, - }, - }, - Containers: []corev1.Container{{ - Image: image, - Name: "memcached", - ImagePullPolicy: corev1.PullIfNotPresent, - // Ensure restrictive context for the container - // More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - SecurityContext: &corev1.SecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - RunAsUser: &[]int64{1001}[0], - AllowPrivilegeEscalation: &[]bool{false}[0], - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - }, - Ports: []corev1.ContainerPort{{ - ContainerPort: memcached.Spec.ContainerPort, - Name: "memcached", - }}, - Command: []string{"memcached", "--memory-limit=64", "-o", "modern", "-v"}, - }}, - }, - }, - }, - } - - // Set the ownerRef for the Deployment - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/ - if err := ctrl.SetControllerReference(memcached, dep, r.Scheme); err != nil { - return nil, err - } - return dep, nil -} - -// labelsForMemcached returns the labels for selecting the resources -// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/ -func labelsForMemcached() map[string]string { - var imageTag string - image, err := imageForMemcached() - if err == nil { - imageTag = strings.Split(image, ":")[1] - } - return map[string]string{"app.kubernetes.io/name": "project-v4-with-plugins", - "app.kubernetes.io/version": imageTag, - "app.kubernetes.io/managed-by": "MemcachedController", - } -} - -// imageForMemcached gets the Operand image which is managed by this controller -// from the MEMCACHED_IMAGE environment variable defined in the config/manager/manager.yaml -func imageForMemcached() (string, error) { - var imageEnvVar = "MEMCACHED_IMAGE" - image, found := os.LookupEnv(imageEnvVar) - if !found { - return "", fmt.Errorf("Unable to find %s environment variable with the image", imageEnvVar) - } - return image, nil -} - -// SetupWithManager sets up the controller with the Manager. -// The whole idea is to be watching the resources that matter for the controller. -// When a resource that the controller is interested in changes, the Watch triggers -// the controller’s reconciliation loop, ensuring that the actual state of the resource -// matches the desired state as defined in the controller’s logic. -// -// Notice how we configured the Manager to monitor events such as the creation, update, -// or deletion of a Custom Resource (CR) of the Memcached kind, as well as any changes -// to the Deployment that the controller manages and owns. -func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - // Watch the Memcached CR(s) and trigger reconciliation whenever it - // is created, updated, or deleted - For(&examplecomv1alpha1.Memcached{}). - Named("memcached"). - // Watch the Deployment managed by the MemcachedReconciler. If any changes occur to the Deployment - // owned and managed by this controller, it will trigger reconciliation, ensuring that the cluster - // state aligns with the desired state. See that the ownerRef was set when the Deployment was created. - Owns(&appsv1.Deployment{}). - Complete(r) -} diff --git a/testdata/project-v4-with-plugins/internal/controller/memcached_controller_test.go b/testdata/project-v4-with-plugins/internal/controller/memcached_controller_test.go deleted file mode 100644 index 821d44261f3..00000000000 --- a/testdata/project-v4-with-plugins/internal/controller/memcached_controller_test.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 2024 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 controller - -import ( - "context" - "os" - "time" - - //nolint:golint - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1alpha1" -) - -var _ = Describe("Memcached controller", func() { - Context("Memcached controller test", func() { - - const MemcachedName = "test-memcached" - - ctx := context.Background() - - namespace := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: MemcachedName, - Namespace: MemcachedName, - }, - } - - typeNamespacedName := types.NamespacedName{ - Name: MemcachedName, - Namespace: MemcachedName, - } - memcached := &examplecomv1alpha1.Memcached{} - - SetDefaultEventuallyTimeout(2 * time.Minute) - SetDefaultEventuallyPollingInterval(time.Second) - - BeforeEach(func() { - By("Creating the Namespace to perform the tests") - err := k8sClient.Create(ctx, namespace) - Expect(err).NotTo(HaveOccurred()) - - By("Setting the Image ENV VAR which stores the Operand image") - err = os.Setenv("MEMCACHED_IMAGE", "example.com/image:test") - Expect(err).NotTo(HaveOccurred()) - - By("creating the custom resource for the Kind Memcached") - err = k8sClient.Get(ctx, typeNamespacedName, memcached) - if err != nil && errors.IsNotFound(err) { - // Let's mock our custom resource at the same way that we would - // apply on the cluster the manifest under config/samples - memcached := &examplecomv1alpha1.Memcached{ - ObjectMeta: metav1.ObjectMeta{ - Name: MemcachedName, - Namespace: namespace.Name, - }, - Spec: examplecomv1alpha1.MemcachedSpec{ - Size: 1, - ContainerPort: 11211, - }, - } - - err = k8sClient.Create(ctx, memcached) - Expect(err).NotTo(HaveOccurred()) - } - }) - - AfterEach(func() { - By("removing the custom resource for the Kind Memcached") - found := &examplecomv1alpha1.Memcached{} - err := k8sClient.Get(ctx, typeNamespacedName, found) - Expect(err).NotTo(HaveOccurred()) - - Eventually(func(g Gomega) { - g.Expect(k8sClient.Delete(context.TODO(), found)).To(Succeed()) - }).Should(Succeed()) - - // TODO(user): Attention if you improve this code by adding other context test you MUST - // be aware of the current delete namespace limitations. - // More info: https://book.kubebuilder.io/reference/envtest.html#testing-considerations - By("Deleting the Namespace to perform the tests") - _ = k8sClient.Delete(ctx, namespace) - - By("Removing the Image ENV VAR which stores the Operand image") - _ = os.Unsetenv("MEMCACHED_IMAGE") - }) - - It("should successfully reconcile a custom resource for Memcached", func() { - By("Checking if the custom resource was successfully created") - Eventually(func(g Gomega) { - found := &examplecomv1alpha1.Memcached{} - Expect(k8sClient.Get(ctx, typeNamespacedName, found)).To(Succeed()) - }).Should(Succeed()) - - By("Reconciling the custom resource created") - memcachedReconciler := &MemcachedReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := memcachedReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - - By("Checking if Deployment was successfully created in the reconciliation") - Eventually(func(g Gomega) { - found := &appsv1.Deployment{} - g.Expect(k8sClient.Get(ctx, typeNamespacedName, found)).To(Succeed()) - }).Should(Succeed()) - - By("Reconciling the custom resource again") - _, err = memcachedReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - - By("Checking the latest Status Condition added to the Memcached instance") - Expect(k8sClient.Get(ctx, typeNamespacedName, memcached)).To(Succeed()) - conditions := []metav1.Condition{} - Expect(memcached.Status.Conditions).To(ContainElement( - HaveField("Type", Equal(typeAvailableMemcached)), &conditions)) - Expect(conditions).To(HaveLen(1), "Multiple conditions of type %s", typeAvailableMemcached) - Expect(conditions[0].Status).To(Equal(metav1.ConditionTrue), "condition %s", typeAvailableMemcached) - Expect(conditions[0].Reason).To(Equal("Reconciling"), "condition %s", typeAvailableMemcached) - }) - }) -}) diff --git a/testdata/project-v4-with-plugins/internal/controller/suite_test.go b/testdata/project-v4-with-plugins/internal/controller/suite_test.go deleted file mode 100644 index 5259421161e..00000000000 --- a/testdata/project-v4-with-plugins/internal/controller/suite_test.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2024 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 controller - -import ( - "context" - "fmt" - "path/filepath" - "runtime" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1alpha1" - // +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 -var ctx context.Context -var cancel context.CancelFunc - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = examplecomv1alpha1.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()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-with-plugins/internal/webhook/v1alpha1/memcached_webhook.go b/testdata/project-v4-with-plugins/internal/webhook/v1alpha1/memcached_webhook.go deleted file mode 100644 index 496877aaf71..00000000000 --- a/testdata/project-v4-with-plugins/internal/webhook/v1alpha1/memcached_webhook.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 - -import ( - "context" - "fmt" - - "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" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1alpha1" -) - -// nolint:unused -// log is for logging in this package. -var memcachedlog = logf.Log.WithName("memcached-resource") - -// SetupMemcachedWebhookWithManager registers the webhook for Memcached in the manager. -func SetupMemcachedWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&examplecomv1alpha1.Memcached{}). - WithValidator(&MemcachedCustomValidator{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. -// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. -// +kubebuilder:webhook:path=/validate-example-com-testproject-org-v1alpha1-memcached,mutating=false,failurePolicy=fail,sideEffects=None,groups=example.com.testproject.org,resources=memcacheds,verbs=create;update,versions=v1alpha1,name=vmemcached-v1alpha1.kb.io,admissionReviewVersions=v1 - -// MemcachedCustomValidator struct is responsible for validating the Memcached resource -// when it is created, updated, or deleted. -// -// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, -// as this struct is used only for temporary operations and does not need to be deeply copied. -type MemcachedCustomValidator struct { - //TODO(user): Add more fields as needed for validation -} - -var _ webhook.CustomValidator = &MemcachedCustomValidator{} - -// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type Memcached. -func (v *MemcachedCustomValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - memcached, ok := obj.(*examplecomv1alpha1.Memcached) - if !ok { - return nil, fmt.Errorf("expected a Memcached object but got %T", obj) - } - memcachedlog.Info("Validation for Memcached upon creation", "name", memcached.GetName()) - - // TODO(user): fill in your validation logic upon object creation. - - return nil, nil -} - -// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type Memcached. -func (v *MemcachedCustomValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { - memcached, ok := newObj.(*examplecomv1alpha1.Memcached) - if !ok { - return nil, fmt.Errorf("expected a Memcached object for the newObj but got %T", newObj) - } - memcachedlog.Info("Validation for Memcached upon update", "name", memcached.GetName()) - - // TODO(user): fill in your validation logic upon object update. - - return nil, nil -} - -// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type Memcached. -func (v *MemcachedCustomValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - memcached, ok := obj.(*examplecomv1alpha1.Memcached) - if !ok { - return nil, fmt.Errorf("expected a Memcached object but got %T", obj) - } - memcachedlog.Info("Validation for Memcached upon deletion", "name", memcached.GetName()) - - // TODO(user): fill in your validation logic upon object deletion. - - return nil, nil -} diff --git a/testdata/project-v4-with-plugins/internal/webhook/v1alpha1/memcached_webhook_test.go b/testdata/project-v4-with-plugins/internal/webhook/v1alpha1/memcached_webhook_test.go deleted file mode 100644 index 99e32bafcac..00000000000 --- a/testdata/project-v4-with-plugins/internal/webhook/v1alpha1/memcached_webhook_test.go +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1alpha1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("Memcached Webhook", func() { - var ( - obj *examplecomv1alpha1.Memcached - oldObj *examplecomv1alpha1.Memcached - validator MemcachedCustomValidator - ) - - BeforeEach(func() { - obj = &examplecomv1alpha1.Memcached{} - oldObj = &examplecomv1alpha1.Memcached{} - validator = MemcachedCustomValidator{} - Expect(validator).NotTo(BeNil(), "Expected validator to be initialized") - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating or updating Memcached under Validating Webhook", func() { - // TODO (user): Add logic for validating webhooks - // Example: - // It("Should deny creation if a required field is missing", func() { - // By("simulating an invalid creation scenario") - // obj.SomeRequiredField = "" - // Expect(validator.ValidateCreate(ctx, obj)).Error().To(HaveOccurred()) - // }) - // - // It("Should admit creation if all required fields are present", func() { - // By("simulating an invalid creation scenario") - // obj.SomeRequiredField = "valid_value" - // Expect(validator.ValidateCreate(ctx, obj)).To(BeNil()) - // }) - // - // It("Should validate updates correctly", func() { - // By("simulating a valid update scenario") - // oldObj.SomeRequiredField = "updated_value" - // obj.SomeRequiredField = "updated_value" - // Expect(validator.ValidateUpdate(ctx, oldObj, obj)).To(BeNil()) - // }) - }) - -}) diff --git a/testdata/project-v4-with-plugins/internal/webhook/v1alpha1/webhook_suite_test.go b/testdata/project-v4-with-plugins/internal/webhook/v1alpha1/webhook_suite_test.go deleted file mode 100644 index 7e2fed6c3ae..00000000000 --- a/testdata/project-v4-with-plugins/internal/webhook/v1alpha1/webhook_suite_test.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 - -import ( - "context" - "crypto/tls" - "fmt" - "net" - "path/filepath" - "runtime" - "testing" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - admissionv1 "k8s.io/api/admission/v1" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1alpha1" - - // +kubebuilder:scaffold:imports - apimachineryruntime "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" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var ( - cancel context.CancelFunc - cfg *rest.Config - ctx context.Context - k8sClient client.Client - testEnv *envtest.Environment -) - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Webhook Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - - WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")}, - }, - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := apimachineryruntime.NewScheme() - err = examplecomv1alpha1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = admissionv1.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, - WebhookServer: webhook.NewServer(webhook.Options{ - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - }), - LeaderElection: false, - Metrics: metricsserver.Options{BindAddress: "0"}, - }) - Expect(err).NotTo(HaveOccurred()) - - err = SetupMemcachedWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() - - // wait for the webhook server to get ready. - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - - return conn.Close() - }).Should(Succeed()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/testdata/project-v4-with-plugins/test/e2e/e2e_suite_test.go b/testdata/project-v4-with-plugins/test/e2e/e2e_suite_test.go deleted file mode 100644 index 6250b847b2c..00000000000 --- a/testdata/project-v4-with-plugins/test/e2e/e2e_suite_test.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright 2024 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 e2e - -import ( - "fmt" - "os" - "os/exec" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/test/utils" -) - -var ( - // Optional Environment Variables: - // - PROMETHEUS_INSTALL_SKIP=true: Skips Prometheus Operator installation during test setup. - // - CERT_MANAGER_INSTALL_SKIP=true: Skips CertManager installation during test setup. - // These variables are useful if Prometheus or CertManager is already installed, avoiding - // re-installation and conflicts. - skipPrometheusInstall = os.Getenv("PROMETHEUS_INSTALL_SKIP") == "true" - skipCertManagerInstall = os.Getenv("CERT_MANAGER_INSTALL_SKIP") == "true" - // isPrometheusOperatorAlreadyInstalled will be set true when prometheus CRDs be found on the cluster - isPrometheusOperatorAlreadyInstalled = false - // isCertManagerAlreadyInstalled will be set true when CertManager CRDs be found on the cluster - isCertManagerAlreadyInstalled = false - - // projectImage is the name of the image which will be build and loaded - // with the code source changes to be tested. - projectImage = "example.com/project-v4-with-plugins:v0.0.1" -) - -// TestE2E runs the end-to-end (e2e) test suite for the project. These tests execute in an isolated, -// temporary environment to validate project changes with the the purposed to be used in CI jobs. -// The default setup requires Kind, builds/loads the Manager Docker image locally, and installs -// CertManager and Prometheus. -func TestE2E(t *testing.T) { - RegisterFailHandler(Fail) - _, _ = fmt.Fprintf(GinkgoWriter, "Starting project-v4-with-plugins integration test suite\n") - RunSpecs(t, "e2e suite") -} - -var _ = BeforeSuite(func() { - By("Ensure that Prometheus is enabled") - _ = utils.UncommentCode("config/default/kustomization.yaml", "#- ../prometheus", "#") - - By("generating files") - cmd := exec.Command("make", "generate") - _, err := utils.Run(cmd) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to run make generate") - - By("generating manifests") - cmd = exec.Command("make", "manifests") - _, err = utils.Run(cmd) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to run make manifests") - - By("building the manager(Operator) image") - cmd = exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectImage)) - _, err = utils.Run(cmd) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to build the manager(Operator) image") - - // TODO(user): If you want to change the e2e test vendor from Kind, ensure the image is - // built and available before running the tests. Also, remove the following block. - By("loading the manager(Operator) image on Kind") - err = utils.LoadImageToKindClusterWithName(projectImage) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to load the manager(Operator) image into Kind") - - // The tests-e2e are intended to run on a temporary cluster that is created and destroyed for testing. - // To prevent errors when tests run in environments with Prometheus or CertManager already installed, - // we check for their presence before execution. - // Setup Prometheus and CertManager before the suite if not skipped and if not already installed - if !skipPrometheusInstall { - By("checking if prometheus is installed already") - isPrometheusOperatorAlreadyInstalled = utils.IsPrometheusCRDsInstalled() - if !isPrometheusOperatorAlreadyInstalled { - _, _ = fmt.Fprintf(GinkgoWriter, "Installing Prometheus Operator...\n") - Expect(utils.InstallPrometheusOperator()).To(Succeed(), "Failed to install Prometheus Operator") - } else { - _, _ = fmt.Fprintf(GinkgoWriter, "WARNING: Prometheus Operator is already installed. Skipping installation...\n") - } - } - if !skipCertManagerInstall { - By("checking if cert manager is installed already") - isCertManagerAlreadyInstalled = utils.IsCertManagerCRDsInstalled() - if !isCertManagerAlreadyInstalled { - _, _ = fmt.Fprintf(GinkgoWriter, "Installing CertManager...\n") - Expect(utils.InstallCertManager()).To(Succeed(), "Failed to install CertManager") - } else { - _, _ = fmt.Fprintf(GinkgoWriter, "WARNING: CertManager is already installed. Skipping installation...\n") - } - } -}) - -var _ = AfterSuite(func() { - // Teardown Prometheus and CertManager after the suite if not skipped and if they were not already installed - if !skipPrometheusInstall && !isPrometheusOperatorAlreadyInstalled { - _, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling Prometheus Operator...\n") - utils.UninstallPrometheusOperator() - } - if !skipCertManagerInstall && !isCertManagerAlreadyInstalled { - _, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling CertManager...\n") - utils.UninstallCertManager() - } -}) diff --git a/testdata/project-v4-with-plugins/test/e2e/e2e_test.go b/testdata/project-v4-with-plugins/test/e2e/e2e_test.go deleted file mode 100644 index 08f2abd755a..00000000000 --- a/testdata/project-v4-with-plugins/test/e2e/e2e_test.go +++ /dev/null @@ -1,331 +0,0 @@ -/* -Copyright 2024 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 e2e - -import ( - "encoding/json" - "fmt" - "os" - "os/exec" - "path/filepath" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/test/utils" -) - -// namespace where the project is deployed in -const namespace = "project-v4-with-plugins-system" - -// serviceAccountName created for the project -const serviceAccountName = "project-v4-with-plugins-controller-manager" - -// metricsServiceName is the name of the metrics service of the project -const metricsServiceName = "project-v4-with-plugins-controller-manager-metrics-service" - -// metricsRoleBindingName is the name of the RBAC that will be created to allow get the metrics data -const metricsRoleBindingName = "project-v4-with-plugins-metrics-binding" - -var _ = Describe("Manager", Ordered, func() { - var controllerPodName string - - // Before running the tests, set up the environment by creating the namespace, - // installing CRDs, and deploying the controller. - BeforeAll(func() { - By("creating manager namespace") - cmd := exec.Command("kubectl", "create", "ns", namespace) - _, err := utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to create namespace") - - By("installing CRDs") - cmd = exec.Command("make", "install") - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to install CRDs") - - By("deploying the controller-manager") - cmd = exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", projectImage)) - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to deploy the controller-manager") - }) - - // After all tests have been executed, clean up by undeploying the controller, uninstalling CRDs, - // and deleting the namespace. - AfterAll(func() { - By("cleaning up the curl pod for metrics") - cmd := exec.Command("kubectl", "delete", "pod", "curl-metrics", "-n", namespace) - _, _ = utils.Run(cmd) - - By("undeploying the controller-manager") - cmd = exec.Command("make", "undeploy") - _, _ = utils.Run(cmd) - - By("uninstalling CRDs") - cmd = exec.Command("make", "uninstall") - _, _ = utils.Run(cmd) - - By("removing manager namespace") - cmd = exec.Command("kubectl", "delete", "ns", namespace) - _, _ = utils.Run(cmd) - }) - - // After each test, check for failures and collect logs, events, - // and pod descriptions for debugging. - AfterEach(func() { - specReport := CurrentSpecReport() - if specReport.Failed() { - By("Fetching controller manager pod logs") - cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace) - controllerLogs, err := utils.Run(cmd) - if err == nil { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Controller logs:\n %s", controllerLogs)) - } else { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get Controller logs: %s", err)) - } - - By("Fetching Kubernetes events") - cmd = exec.Command("kubectl", "get", "events", "-n", namespace, "--sort-by=.lastTimestamp") - eventsOutput, err := utils.Run(cmd) - if err == nil { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Kubernetes events:\n%s", eventsOutput)) - } else { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get Kubernetes events: %s", err)) - } - - By("Fetching curl-metrics logs") - cmd = exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace) - metricsOutput, err := utils.Run(cmd) - if err == nil { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Metrics logs:\n %s", metricsOutput)) - } else { - _, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get curl-metrics logs: %s", err)) - } - - By("Fetching controller manager pod description") - cmd = exec.Command("kubectl", "describe", "pod", controllerPodName, "-n", namespace) - podDescription, err := utils.Run(cmd) - if err == nil { - fmt.Println("Pod description:\n", podDescription) - } else { - fmt.Println("Failed to describe controller pod") - } - } - }) - - SetDefaultEventuallyTimeout(2 * time.Minute) - SetDefaultEventuallyPollingInterval(time.Second) - - Context("Manager", func() { - It("should run successfully", func() { - By("validating that the controller-manager pod is running as expected") - verifyControllerUp := func(g Gomega) { - // Get the name of the controller-manager pod - cmd := exec.Command("kubectl", "get", - "pods", "-l", "control-plane=controller-manager", - "-o", "go-template={{ range .items }}"+ - "{{ if not .metadata.deletionTimestamp }}"+ - "{{ .metadata.name }}"+ - "{{ \"\\n\" }}{{ end }}{{ end }}", - "-n", namespace, - ) - - podOutput, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred(), "Failed to retrieve controller-manager pod information") - podNames := utils.GetNonEmptyLines(podOutput) - g.Expect(podNames).To(HaveLen(1), "expected 1 controller pod running") - controllerPodName = podNames[0] - g.Expect(controllerPodName).To(ContainSubstring("controller-manager")) - - // Validate the pod's status - cmd = exec.Command("kubectl", "get", - "pods", controllerPodName, "-o", "jsonpath={.status.phase}", - "-n", namespace, - ) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(Equal("Running"), "Incorrect controller-manager pod status") - } - Eventually(verifyControllerUp).Should(Succeed()) - }) - - It("should ensure the metrics endpoint is serving metrics", func() { - By("creating a ClusterRoleBinding for the service account to allow access to metrics") - cmd := exec.Command("kubectl", "create", "clusterrolebinding", metricsRoleBindingName, - "--clusterrole=project-v4-with-plugins-metrics-reader", - fmt.Sprintf("--serviceaccount=%s:%s", namespace, serviceAccountName), - ) - _, err := utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to create ClusterRoleBinding") - - By("validating that the metrics service is available") - cmd = exec.Command("kubectl", "get", "service", metricsServiceName, "-n", namespace) - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Metrics service should exist") - - By("validating that the ServiceMonitor for Prometheus is applied in the namespace") - cmd = exec.Command("kubectl", "get", "ServiceMonitor", "-n", namespace) - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "ServiceMonitor should exist") - - By("getting the service account token") - token, err := serviceAccountToken() - Expect(err).NotTo(HaveOccurred()) - Expect(token).NotTo(BeEmpty()) - - By("waiting for the metrics endpoint to be ready") - verifyMetricsEndpointReady := func(g Gomega) { - cmd := exec.Command("kubectl", "get", "endpoints", metricsServiceName, "-n", namespace) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("8443"), "Metrics endpoint is not ready") - } - Eventually(verifyMetricsEndpointReady).Should(Succeed()) - - By("verifying that the controller manager is serving the metrics server") - verifyMetricsServerStarted := func(g Gomega) { - cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("controller-runtime.metrics\tServing metrics server"), - "Metrics server not yet started") - } - Eventually(verifyMetricsServerStarted).Should(Succeed()) - - By("creating the curl-metrics pod to access the metrics endpoint") - cmd = exec.Command("kubectl", "run", "curl-metrics", "--restart=Never", - "--namespace", namespace, - "--image=curlimages/curl:7.78.0", - "--", "/bin/sh", "-c", fmt.Sprintf( - "curl -v -k -H 'Authorization: Bearer %s' https://%s.%s.svc.cluster.local:8443/metrics", - token, metricsServiceName, namespace)) - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to create curl-metrics pod") - - By("waiting for the curl-metrics pod to complete.") - verifyCurlUp := func(g Gomega) { - cmd := exec.Command("kubectl", "get", "pods", "curl-metrics", - "-o", "jsonpath={.status.phase}", - "-n", namespace) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(Equal("Succeeded"), "curl pod in wrong status") - } - Eventually(verifyCurlUp, 5*time.Minute).Should(Succeed()) - - By("getting the metrics by checking curl-metrics logs") - metricsOutput := getMetricsOutput() - Expect(metricsOutput).To(ContainSubstring( - "controller_runtime_reconcile_total", - )) - }) - - It("should provisioned cert-manager", func() { - By("validating that cert-manager has the certificate Secret") - verifyCertManager := func(g Gomega) { - cmd := exec.Command("kubectl", "get", "secrets", "webhook-server-cert", "-n", namespace) - _, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - } - Eventually(verifyCertManager).Should(Succeed()) - }) - - It("should have CA injection for validating webhooks", func() { - By("checking CA injection for validating webhooks") - verifyCAInjection := func(g Gomega) { - cmd := exec.Command("kubectl", "get", - "validatingwebhookconfigurations.admissionregistration.k8s.io", - "project-v4-with-plugins-validating-webhook-configuration", - "-o", "go-template={{ range .webhooks }}{{ .clientConfig.caBundle }}{{ end }}") - vwhOutput, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(len(vwhOutput)).To(BeNumerically(">", 10)) - } - Eventually(verifyCAInjection).Should(Succeed()) - }) - - // +kubebuilder:scaffold:e2e-webhooks-checks - - // TODO: Customize the e2e test suite with scenarios specific to your project. - // Consider applying sample/CR(s) and check their status and/or verifying - // the reconciliation by using the metrics, i.e.: - // metricsOutput := getMetricsOutput() - // Expect(metricsOutput).To(ContainSubstring( - // fmt.Sprintf(`controller_runtime_reconcile_total{controller="%s",result="success"} 1`, - // strings.ToLower(), - // )) - }) -}) - -// serviceAccountToken returns a token for the specified service account in the given namespace. -// It uses the Kubernetes TokenRequest API to generate a token by directly sending a request -// and parsing the resulting token from the API response. -func serviceAccountToken() (string, error) { - const tokenRequestRawString = `{ - "apiVersion": "authentication.k8s.io/v1", - "kind": "TokenRequest" - }` - - // Temporary file to store the token request - secretName := fmt.Sprintf("%s-token-request", serviceAccountName) - tokenRequestFile := filepath.Join("/tmp", secretName) - err := os.WriteFile(tokenRequestFile, []byte(tokenRequestRawString), os.FileMode(0o644)) - if err != nil { - return "", err - } - - var out string - verifyTokenCreation := func(g Gomega) { - // Execute kubectl command to create the token - cmd := exec.Command("kubectl", "create", "--raw", fmt.Sprintf( - "/api/v1/namespaces/%s/serviceaccounts/%s/token", - namespace, - serviceAccountName, - ), "-f", tokenRequestFile) - - output, err := cmd.CombinedOutput() - g.Expect(err).NotTo(HaveOccurred()) - - // Parse the JSON output to extract the token - var token tokenRequest - err = json.Unmarshal([]byte(output), &token) - g.Expect(err).NotTo(HaveOccurred()) - - out = token.Status.Token - } - Eventually(verifyTokenCreation).Should(Succeed()) - - return out, err -} - -// getMetricsOutput retrieves and returns the logs from the curl pod used to access the metrics endpoint. -func getMetricsOutput() string { - By("getting the curl-metrics logs") - cmd := exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace) - metricsOutput, err := utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to retrieve logs from curl pod") - Expect(metricsOutput).To(ContainSubstring("< HTTP/1.1 200 OK")) - return metricsOutput -} - -// tokenRequest is a simplified representation of the Kubernetes TokenRequest API response, -// containing only the token field that we need to extract. -type tokenRequest struct { - Status struct { - Token string `json:"token"` - } `json:"status"` -} diff --git a/testdata/project-v4-with-plugins/test/utils/utils.go b/testdata/project-v4-with-plugins/test/utils/utils.go deleted file mode 100644 index a239bfd7be2..00000000000 --- a/testdata/project-v4-with-plugins/test/utils/utils.go +++ /dev/null @@ -1,251 +0,0 @@ -/* -Copyright 2024 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 utils - -import ( - "bufio" - "bytes" - "fmt" - "os" - "os/exec" - "strings" - - . "github.com/onsi/ginkgo/v2" //nolint:golint,revive -) - -const ( - prometheusOperatorVersion = "v0.77.1" - prometheusOperatorURL = "https://github.com/prometheus-operator/prometheus-operator/" + - "releases/download/%s/bundle.yaml" - - certmanagerVersion = "v1.16.0" - certmanagerURLTmpl = "https://github.com/jetstack/cert-manager/releases/download/%s/cert-manager.yaml" -) - -func warnError(err error) { - _, _ = fmt.Fprintf(GinkgoWriter, "warning: %v\n", err) -} - -// Run executes the provided command within this context -func Run(cmd *exec.Cmd) (string, error) { - dir, _ := GetProjectDir() - cmd.Dir = dir - - if err := os.Chdir(cmd.Dir); err != nil { - _, _ = fmt.Fprintf(GinkgoWriter, "chdir dir: %s\n", err) - } - - cmd.Env = append(os.Environ(), "GO111MODULE=on") - command := strings.Join(cmd.Args, " ") - _, _ = fmt.Fprintf(GinkgoWriter, "running: %s\n", command) - output, err := cmd.CombinedOutput() - if err != nil { - return string(output), fmt.Errorf("%s failed with error: (%v) %s", command, err, string(output)) - } - - return string(output), nil -} - -// InstallPrometheusOperator installs the prometheus Operator to be used to export the enabled metrics. -func InstallPrometheusOperator() error { - url := fmt.Sprintf(prometheusOperatorURL, prometheusOperatorVersion) - cmd := exec.Command("kubectl", "create", "-f", url) - _, err := Run(cmd) - return err -} - -// UninstallPrometheusOperator uninstalls the prometheus -func UninstallPrometheusOperator() { - url := fmt.Sprintf(prometheusOperatorURL, prometheusOperatorVersion) - cmd := exec.Command("kubectl", "delete", "-f", url) - if _, err := Run(cmd); err != nil { - warnError(err) - } -} - -// IsPrometheusCRDsInstalled checks if any Prometheus CRDs are installed -// by verifying the existence of key CRDs related to Prometheus. -func IsPrometheusCRDsInstalled() bool { - // List of common Prometheus CRDs - prometheusCRDs := []string{ - "prometheuses.monitoring.coreos.com", - "prometheusrules.monitoring.coreos.com", - "prometheusagents.monitoring.coreos.com", - } - - cmd := exec.Command("kubectl", "get", "crds", "-o", "custom-columns=NAME:.metadata.name") - output, err := Run(cmd) - if err != nil { - return false - } - crdList := GetNonEmptyLines(string(output)) - for _, crd := range prometheusCRDs { - for _, line := range crdList { - if strings.Contains(line, crd) { - return true - } - } - } - - return false -} - -// UninstallCertManager uninstalls the cert manager -func UninstallCertManager() { - url := fmt.Sprintf(certmanagerURLTmpl, certmanagerVersion) - cmd := exec.Command("kubectl", "delete", "-f", url) - if _, err := Run(cmd); err != nil { - warnError(err) - } -} - -// InstallCertManager installs the cert manager bundle. -func InstallCertManager() error { - url := fmt.Sprintf(certmanagerURLTmpl, certmanagerVersion) - cmd := exec.Command("kubectl", "apply", "-f", url) - if _, err := Run(cmd); err != nil { - return err - } - // Wait for cert-manager-webhook to be ready, which can take time if cert-manager - // was re-installed after uninstalling on a cluster. - cmd = exec.Command("kubectl", "wait", "deployment.apps/cert-manager-webhook", - "--for", "condition=Available", - "--namespace", "cert-manager", - "--timeout", "5m", - ) - - _, err := Run(cmd) - return err -} - -// IsCertManagerCRDsInstalled checks if any Cert Manager CRDs are installed -// by verifying the existence of key CRDs related to Cert Manager. -func IsCertManagerCRDsInstalled() bool { - // List of common Cert Manager CRDs - certManagerCRDs := []string{ - "certificates.cert-manager.io", - "issuers.cert-manager.io", - "clusterissuers.cert-manager.io", - "certificaterequests.cert-manager.io", - "orders.acme.cert-manager.io", - "challenges.acme.cert-manager.io", - } - - // Execute the kubectl command to get all CRDs - cmd := exec.Command("kubectl", "get", "crds") - output, err := Run(cmd) - if err != nil { - return false - } - - // Check if any of the Cert Manager CRDs are present - crdList := GetNonEmptyLines(string(output)) - for _, crd := range certManagerCRDs { - for _, line := range crdList { - if strings.Contains(line, crd) { - return true - } - } - } - - return false -} - -// LoadImageToKindClusterWithName loads a local docker image to the kind cluster -func LoadImageToKindClusterWithName(name string) error { - cluster := "kind" - if v, ok := os.LookupEnv("KIND_CLUSTER"); ok { - cluster = v - } - kindOptions := []string{"load", "docker-image", name, "--name", cluster} - cmd := exec.Command("kind", kindOptions...) - _, err := Run(cmd) - return err -} - -// GetNonEmptyLines converts given command output string into individual objects -// according to line breakers, and ignores the empty elements in it. -func GetNonEmptyLines(output string) []string { - var res []string - elements := strings.Split(output, "\n") - for _, element := range elements { - if element != "" { - res = append(res, element) - } - } - - return res -} - -// GetProjectDir will return the directory where the project is -func GetProjectDir() (string, error) { - wd, err := os.Getwd() - if err != nil { - return wd, err - } - wd = strings.Replace(wd, "/test/e2e", "", -1) - return wd, nil -} - -// UncommentCode searches for target in the file and remove the comment prefix -// of the target content. The target content may span multiple lines. -func UncommentCode(filename, target, prefix string) error { - // false positive - // nolint:gosec - content, err := os.ReadFile(filename) - if err != nil { - return err - } - strContent := string(content) - - idx := strings.Index(strContent, target) - if idx < 0 { - return fmt.Errorf("unable to find the code %s to be uncomment", target) - } - - out := new(bytes.Buffer) - _, err = out.Write(content[:idx]) - if err != nil { - return err - } - - scanner := bufio.NewScanner(bytes.NewBufferString(target)) - if !scanner.Scan() { - return nil - } - for { - _, err := out.WriteString(strings.TrimPrefix(scanner.Text(), prefix)) - if err != nil { - return err - } - // Avoid writing a newline in case the previous line was the last in target. - if !scanner.Scan() { - break - } - if _, err := out.WriteString("\n"); err != nil { - return err - } - } - - _, err = out.Write(content[idx+len(target):]) - if err != nil { - return err - } - // false positive - // nolint:gosec - return os.WriteFile(filename, out.Bytes(), 0644) -} diff --git a/testdata/project-v4/PROJECT b/testdata/project-v4/PROJECT index 1ea7da269fe..fbbd28b3fdd 100644 --- a/testdata/project-v4/PROJECT +++ b/testdata/project-v4/PROJECT @@ -21,52 +21,4 @@ resources: defaulting: true validation: true webhookVersion: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: crew - kind: FirstMate - path: sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1 - version: v1 - webhooks: - conversion: true - webhookVersion: v1 -- api: - crdVersion: v1 - controller: true - domain: testproject.org - group: crew - kind: Admiral - path: sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1 - plural: admirales - version: v1 - webhooks: - defaulting: true - webhookVersion: v1 -- controller: true - domain: io - external: true - group: cert-manager - kind: Certificate - path: github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1 - version: v1 -- domain: io - external: true - group: cert-manager - kind: Issuer - path: github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1 - version: v1 - webhooks: - defaulting: true - webhookVersion: v1 -- core: true - group: core - kind: Pod - path: k8s.io/api/core/v1 - version: v1 - webhooks: - defaulting: true - webhookVersion: v1 version: "3" diff --git a/testdata/project-v4/api/v1/admiral_types.go b/testdata/project-v4/api/v1/admiral_types.go deleted file mode 100644 index 9531fe8d58d..00000000000 --- a/testdata/project-v4/api/v1/admiral_types.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2024 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:path=admirales,scope=Cluster - -// Admiral is the Schema for the admirales 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-v4/api/v1/firstmate_types.go b/testdata/project-v4/api/v1/firstmate_types.go deleted file mode 100644 index 63ce2a69d17..00000000000 --- a/testdata/project-v4/api/v1/firstmate_types.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2024 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-v4/api/v1/zz_generated.deepcopy.go b/testdata/project-v4/api/v1/zz_generated.deepcopy.go deleted file mode 100644 index 24fb3a25515..00000000000 --- a/testdata/project-v4/api/v1/zz_generated.deepcopy.go +++ /dev/null @@ -1,292 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024 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 ( - runtime "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-v4/cmd/main.go b/testdata/project-v4/cmd/main.go index da7b88aacd1..6cfad0cb7a1 100644 --- a/testdata/project-v4/cmd/main.go +++ b/testdata/project-v4/cmd/main.go @@ -35,12 +35,8 @@ import ( metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" - certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" "sigs.k8s.io/kubebuilder/testdata/project-v4/internal/controller" - webhookcertmanagerv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/internal/webhook/v1" - webhookcorev1 "sigs.k8s.io/kubebuilder/testdata/project-v4/internal/webhook/v1" webhookcrewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/internal/webhook/v1" // +kubebuilder:scaffold:imports ) @@ -54,7 +50,6 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(crewv1.AddToScheme(scheme)) - utilruntime.Must(certmanagerv1.AddToScheme(scheme)) // +kubebuilder:scaffold:scheme } @@ -164,55 +159,6 @@ func main() { os.Exit(1) } } - if err = (&controller.FirstMateReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "FirstMate") - os.Exit(1) - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookcrewv1.SetupFirstMateWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "FirstMate") - os.Exit(1) - } - } - if err = (&controller.AdmiralReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Admiral") - os.Exit(1) - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookcrewv1.SetupAdmiralWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Admiral") - os.Exit(1) - } - } - if err = (&controller.CertificateReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Certificate") - os.Exit(1) - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookcertmanagerv1.SetupIssuerWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Issuer") - os.Exit(1) - } - } - // nolint:goconst - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookcorev1.SetupPodWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Pod") - os.Exit(1) - } - } // +kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { diff --git a/testdata/project-v4/config/crd/bases/crew.testproject.org_admirales.yaml b/testdata/project-v4/config/crd/bases/crew.testproject.org_admirales.yaml deleted file mode 100644 index ecaf0a7ce85..00000000000 --- a/testdata/project-v4/config/crd/bases/crew.testproject.org_admirales.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: admirales.crew.testproject.org -spec: - group: crew.testproject.org - names: - kind: Admiral - listKind: AdmiralList - plural: admirales - singular: admiral - scope: Cluster - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Admiral is the Schema for the admirales 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: {} diff --git a/testdata/project-v4/config/crd/bases/crew.testproject.org_captains.yaml b/testdata/project-v4/config/crd/bases/crew.testproject.org_captains.yaml deleted file mode 100644 index b9a8b5d4da8..00000000000 --- a/testdata/project-v4/config/crd/bases/crew.testproject.org_captains.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - 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: {} diff --git a/testdata/project-v4/config/crd/bases/crew.testproject.org_firstmates.yaml b/testdata/project-v4/config/crd/bases/crew.testproject.org_firstmates.yaml deleted file mode 100644 index 550eb68d8e6..00000000000 --- a/testdata/project-v4/config/crd/bases/crew.testproject.org_firstmates.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - 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: {} diff --git a/testdata/project-v4/config/crd/kustomization.yaml b/testdata/project-v4/config/crd/kustomization.yaml index 614a75ff244..ddadd458678 100644 --- a/testdata/project-v4/config/crd/kustomization.yaml +++ b/testdata/project-v4/config/crd/kustomization.yaml @@ -3,23 +3,17 @@ # It should be run by config/default resources: - bases/crew.testproject.org_captains.yaml -- bases/crew.testproject.org_firstmates.yaml -- bases/crew.testproject.org_admirales.yaml # +kubebuilder:scaffold:crdkustomizeresource patches: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD - path: patches/webhook_in_captains.yaml -- path: patches/webhook_in_firstmates.yaml -- path: patches/webhook_in_admirales.yaml # +kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD #- path: patches/cainjection_in_captains.yaml -#- path: patches/cainjection_in_firstmates.yaml -#- path: patches/cainjection_in_admirales.yaml # +kubebuilder:scaffold:crdkustomizecainjectionpatch # [WEBHOOK] To enable webhook, uncomment the following section diff --git a/testdata/project-v4/config/crd/patches/cainjection_in_admirales.yaml b/testdata/project-v4/config/crd/patches/cainjection_in_admirales.yaml deleted file mode 100644 index 62b3a694a37..00000000000 --- a/testdata/project-v4/config/crd/patches/cainjection_in_admirales.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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: admirales.crew.testproject.org diff --git a/testdata/project-v4/config/crd/patches/cainjection_in_firstmates.yaml b/testdata/project-v4/config/crd/patches/cainjection_in_firstmates.yaml deleted file mode 100644 index 69292458eb5..00000000000 --- a/testdata/project-v4/config/crd/patches/cainjection_in_firstmates.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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-v4/config/crd/patches/cainjection_in_issuers.yaml b/testdata/project-v4/config/crd/patches/cainjection_in_issuers.yaml deleted file mode 100644 index c23d48081df..00000000000 --- a/testdata/project-v4/config/crd/patches/cainjection_in_issuers.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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: issuers.cert-manager.io diff --git a/testdata/project-v4/config/crd/patches/cainjection_in_pods.yaml b/testdata/project-v4/config/crd/patches/cainjection_in_pods.yaml deleted file mode 100644 index b1ab830f8f6..00000000000 --- a/testdata/project-v4/config/crd/patches/cainjection_in_pods.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# 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: pods.core diff --git a/testdata/project-v4/config/crd/patches/webhook_in_admirales.yaml b/testdata/project-v4/config/crd/patches/webhook_in_admirales.yaml deleted file mode 100644 index cf986a6a411..00000000000 --- a/testdata/project-v4/config/crd/patches/webhook_in_admirales.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: admirales.crew.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4/config/crd/patches/webhook_in_firstmates.yaml b/testdata/project-v4/config/crd/patches/webhook_in_firstmates.yaml deleted file mode 100644 index 76ee5acedbd..00000000000 --- a/testdata/project-v4/config/crd/patches/webhook_in_firstmates.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: firstmates.crew.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4/config/crd/patches/webhook_in_issuers.yaml b/testdata/project-v4/config/crd/patches/webhook_in_issuers.yaml deleted file mode 100644 index 29988f44a9b..00000000000 --- a/testdata/project-v4/config/crd/patches/webhook_in_issuers.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: issuers.cert-manager.io -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4/config/crd/patches/webhook_in_pods.yaml b/testdata/project-v4/config/crd/patches/webhook_in_pods.yaml deleted file mode 100644 index 8fa5d252208..00000000000 --- a/testdata/project-v4/config/crd/patches/webhook_in_pods.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: pods.core -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/testdata/project-v4/config/manager/kustomization.yaml b/testdata/project-v4/config/manager/kustomization.yaml index ad13e96b3fc..5c5f0b84cba 100644 --- a/testdata/project-v4/config/manager/kustomization.yaml +++ b/testdata/project-v4/config/manager/kustomization.yaml @@ -1,8 +1,2 @@ resources: - manager.yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -images: -- name: controller - newName: controller - newTag: latest diff --git a/testdata/project-v4/config/rbac/admiral_editor_role.yaml b/testdata/project-v4/config/rbac/admiral_editor_role.yaml deleted file mode 100644 index ab77210de89..00000000000 --- a/testdata/project-v4/config/rbac/admiral_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit admirales. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4 - app.kubernetes.io/managed-by: kustomize - name: admiral-editor-role -rules: -- apiGroups: - - crew.testproject.org - resources: - - admirales - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - crew.testproject.org - resources: - - admirales/status - verbs: - - get diff --git a/testdata/project-v4/config/rbac/admiral_viewer_role.yaml b/testdata/project-v4/config/rbac/admiral_viewer_role.yaml deleted file mode 100644 index cc0da99283e..00000000000 --- a/testdata/project-v4/config/rbac/admiral_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view admirales. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4 - app.kubernetes.io/managed-by: kustomize - name: admiral-viewer-role -rules: -- apiGroups: - - crew.testproject.org - resources: - - admirales - verbs: - - get - - list - - watch -- apiGroups: - - crew.testproject.org - resources: - - admirales/status - verbs: - - get diff --git a/testdata/project-v4/config/rbac/firstmate_editor_role.yaml b/testdata/project-v4/config/rbac/firstmate_editor_role.yaml deleted file mode 100644 index 4e39922e64a..00000000000 --- a/testdata/project-v4/config/rbac/firstmate_editor_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to edit firstmates. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4 - app.kubernetes.io/managed-by: kustomize - 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-v4/config/rbac/firstmate_viewer_role.yaml b/testdata/project-v4/config/rbac/firstmate_viewer_role.yaml deleted file mode 100644 index c17cd0a5237..00000000000 --- a/testdata/project-v4/config/rbac/firstmate_viewer_role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# permissions for end users to view firstmates. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: project-v4 - app.kubernetes.io/managed-by: kustomize - 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-v4/config/rbac/kustomization.yaml b/testdata/project-v4/config/rbac/kustomization.yaml index b6ac31fc556..96bc57fd097 100644 --- a/testdata/project-v4/config/rbac/kustomization.yaml +++ b/testdata/project-v4/config/rbac/kustomization.yaml @@ -22,10 +22,6 @@ resources: # default, aiding admins in cluster management. Those roles are # not used by the Project itself. You can comment the following lines # if you do not want those helpers be installed with your Project. -- admiral_editor_role.yaml -- admiral_viewer_role.yaml -- firstmate_editor_role.yaml -- firstmate_viewer_role.yaml - captain_editor_role.yaml - captain_viewer_role.yaml diff --git a/testdata/project-v4/config/rbac/role.yaml b/testdata/project-v4/config/rbac/role.yaml index dfa4ad22cab..9cb6e70e830 100644 --- a/testdata/project-v4/config/rbac/role.yaml +++ b/testdata/project-v4/config/rbac/role.yaml @@ -1,64 +1,11 @@ ---- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: project-v4 + app.kubernetes.io/managed-by: kustomize name: manager-role rules: -- apiGroups: - - cert-manager.io - resources: - - certificates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - cert-manager.io - resources: - - certificates/finalizers - verbs: - - update -- apiGroups: - - cert-manager.io - resources: - - certificates/status - verbs: - - get - - patch - - update -- apiGroups: - - crew.testproject.org - resources: - - admirales - - captains - - firstmates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - crew.testproject.org - resources: - - admirales/finalizers - - captains/finalizers - - firstmates/finalizers - verbs: - - update -- apiGroups: - - crew.testproject.org - resources: - - admirales/status - - captains/status - - firstmates/status - verbs: - - get - - patch - - update +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] diff --git a/testdata/project-v4/config/samples/crew_v1_admiral.yaml b/testdata/project-v4/config/samples/crew_v1_admiral.yaml deleted file mode 100644 index 509a62be362..00000000000 --- a/testdata/project-v4/config/samples/crew_v1_admiral.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: crew.testproject.org/v1 -kind: Admiral -metadata: - labels: - app.kubernetes.io/name: project-v4 - app.kubernetes.io/managed-by: kustomize - name: admiral-sample -spec: - # TODO(user): Add fields here diff --git a/testdata/project-v4/config/samples/crew_v1_firstmate.yaml b/testdata/project-v4/config/samples/crew_v1_firstmate.yaml deleted file mode 100644 index 6aca7b03b33..00000000000 --- a/testdata/project-v4/config/samples/crew_v1_firstmate.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: crew.testproject.org/v1 -kind: FirstMate -metadata: - labels: - app.kubernetes.io/name: project-v4 - app.kubernetes.io/managed-by: kustomize - name: firstmate-sample -spec: - # TODO(user): Add fields here diff --git a/testdata/project-v4/config/samples/kustomization.yaml b/testdata/project-v4/config/samples/kustomization.yaml index 787262813fe..f7fe393f2a8 100644 --- a/testdata/project-v4/config/samples/kustomization.yaml +++ b/testdata/project-v4/config/samples/kustomization.yaml @@ -1,6 +1,4 @@ ## Append samples of your project ## resources: - crew_v1_captain.yaml -- crew_v1_firstmate.yaml -- crew_v1_admiral.yaml # +kubebuilder:scaffold:manifestskustomizesamples diff --git a/testdata/project-v4/config/webhook/manifests.yaml b/testdata/project-v4/config/webhook/manifests.yaml deleted file mode 100644 index c2154d9674e..00000000000 --- a/testdata/project-v4/config/webhook/manifests.yaml +++ /dev/null @@ -1,112 +0,0 @@ ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: mutating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-crew-testproject-org-v1-admiral - failurePolicy: Fail - name: madmiral-v1.kb.io - rules: - - apiGroups: - - crew.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - admirales - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-crew-testproject-org-v1-captain - failurePolicy: Fail - name: mcaptain-v1.kb.io - rules: - - apiGroups: - - crew.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - captains - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-cert-manager-io-v1-issuer - failurePolicy: Fail - name: missuer-v1.kb.io - rules: - - apiGroups: - - cert-manager.io - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - issuers - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate--v1-pod - failurePolicy: Fail - name: mpod-v1.kb.io - rules: - - apiGroups: - - "" - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - pods - sideEffects: None ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: validating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /validate-crew-testproject-org-v1-captain - failurePolicy: Fail - name: vcaptain-v1.kb.io - rules: - - apiGroups: - - crew.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - captains - sideEffects: None diff --git a/testdata/project-v4/dist/install.yaml b/testdata/project-v4/dist/install.yaml deleted file mode 100644 index 644e7898cf7..00000000000 --- a/testdata/project-v4/dist/install.yaml +++ /dev/null @@ -1,756 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - control-plane: controller-manager - name: project-v4-system ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: admirales.crew.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - name: project-v4-webhook-service - namespace: project-v4-system - path: /convert - conversionReviewVersions: - - v1 - group: crew.testproject.org - names: - kind: Admiral - listKind: AdmiralList - plural: admirales - singular: admiral - scope: Cluster - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Admiral is the Schema for the admirales 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: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: captains.crew.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - name: project-v4-webhook-service - namespace: project-v4-system - path: /convert - conversionReviewVersions: - - v1 - 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: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.4 - name: firstmates.crew.testproject.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - name: project-v4-webhook-service - namespace: project-v4-system - path: /convert - conversionReviewVersions: - - v1 - 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: {} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - name: project-v4-controller-manager - namespace: project-v4-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - name: project-v4-leader-election-role - namespace: project-v4-system -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - name: project-v4-admiral-editor-role -rules: -- apiGroups: - - crew.testproject.org - resources: - - admirales - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - crew.testproject.org - resources: - - admirales/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - name: project-v4-admiral-viewer-role -rules: -- apiGroups: - - crew.testproject.org - resources: - - admirales - verbs: - - get - - list - - watch -- apiGroups: - - crew.testproject.org - resources: - - admirales/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - name: project-v4-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 ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - name: project-v4-captain-viewer-role -rules: -- apiGroups: - - crew.testproject.org - resources: - - captains - verbs: - - get - - list - - watch -- apiGroups: - - crew.testproject.org - resources: - - captains/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - name: project-v4-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 ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - name: project-v4-firstmate-viewer-role -rules: -- apiGroups: - - crew.testproject.org - resources: - - firstmates - verbs: - - get - - list - - watch -- apiGroups: - - crew.testproject.org - resources: - - firstmates/status - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: project-v4-manager-role -rules: -- apiGroups: - - cert-manager.io - resources: - - certificates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - cert-manager.io - resources: - - certificates/finalizers - verbs: - - update -- apiGroups: - - cert-manager.io - resources: - - certificates/status - verbs: - - get - - patch - - update -- apiGroups: - - crew.testproject.org - resources: - - admirales - - captains - - firstmates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - crew.testproject.org - resources: - - admirales/finalizers - - captains/finalizers - - firstmates/finalizers - verbs: - - update -- apiGroups: - - crew.testproject.org - resources: - - admirales/status - - captains/status - - firstmates/status - verbs: - - get - - patch - - update ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: project-v4-metrics-auth-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: project-v4-metrics-reader -rules: -- nonResourceURLs: - - /metrics - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - name: project-v4-leader-election-rolebinding - namespace: project-v4-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: project-v4-leader-election-role -subjects: -- kind: ServiceAccount - name: project-v4-controller-manager - namespace: project-v4-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - name: project-v4-manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-v4-manager-role -subjects: -- kind: ServiceAccount - name: project-v4-controller-manager - namespace: project-v4-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: project-v4-metrics-auth-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-v4-metrics-auth-role -subjects: -- kind: ServiceAccount - name: project-v4-controller-manager - namespace: project-v4-system ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - control-plane: controller-manager - name: project-v4-controller-manager-metrics-service - namespace: project-v4-system -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: 8443 - selector: - control-plane: controller-manager ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - name: project-v4-webhook-service - namespace: project-v4-system -spec: - ports: - - port: 443 - protocol: TCP - targetPort: 9443 - selector: - control-plane: controller-manager ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: project-v4 - control-plane: controller-manager - name: project-v4-controller-manager - namespace: project-v4-system -spec: - replicas: 1 - selector: - matchLabels: - control-plane: controller-manager - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - control-plane: controller-manager - spec: - containers: - - args: - - --metrics-bind-address=:8443 - - --leader-elect - - --health-probe-bind-address=:8081 - command: - - /manager - image: controller:latest - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - name: manager - ports: - - containerPort: 9443 - name: webhook-server - protocol: TCP - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - volumeMounts: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cert - readOnly: true - securityContext: - runAsNonRoot: true - serviceAccountName: project-v4-controller-manager - terminationGracePeriodSeconds: 10 - volumes: - - name: cert - secret: - defaultMode: 420 - secretName: webhook-server-cert ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: project-v4-mutating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-webhook-service - namespace: project-v4-system - path: /mutate-crew-testproject-org-v1-admiral - failurePolicy: Fail - name: madmiral-v1.kb.io - rules: - - apiGroups: - - crew.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - admirales - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-webhook-service - namespace: project-v4-system - path: /mutate-crew-testproject-org-v1-captain - failurePolicy: Fail - name: mcaptain-v1.kb.io - rules: - - apiGroups: - - crew.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - captains - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-webhook-service - namespace: project-v4-system - path: /mutate-cert-manager-io-v1-issuer - failurePolicy: Fail - name: missuer-v1.kb.io - rules: - - apiGroups: - - cert-manager.io - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - issuers - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-webhook-service - namespace: project-v4-system - path: /mutate--v1-pod - failurePolicy: Fail - name: mpod-v1.kb.io - rules: - - apiGroups: - - "" - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - pods - sideEffects: None ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: project-v4-validating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: project-v4-webhook-service - namespace: project-v4-system - path: /validate-crew-testproject-org-v1-captain - failurePolicy: Fail - name: vcaptain-v1.kb.io - rules: - - apiGroups: - - crew.testproject.org - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - captains - sideEffects: None diff --git a/testdata/project-v4/go.mod b/testdata/project-v4/go.mod index a0b070c87ac..09810a66577 100644 --- a/testdata/project-v4/go.mod +++ b/testdata/project-v4/go.mod @@ -3,24 +3,23 @@ module sigs.k8s.io/kubebuilder/testdata/project-v4 go 1.22.0 require ( - github.com/cert-manager/cert-manager v1.16.1 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 - k8s.io/api v0.31.1 - k8s.io/apimachinery v0.31.1 - k8s.io/client-go v0.31.1 + k8s.io/api v0.31.0 + k8s.io/apimachinery v0.31.0 + k8s.io/client-go v0.31.0 sigs.k8s.io/controller-runtime v0.19.0 ) require ( github.com/antlr4-go/antlr/v4 v4.13.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.12.1 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect @@ -28,9 +27,9 @@ require ( github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.4 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -39,62 +38,60 @@ require ( github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect + github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect + github.com/imdario/mergo v0.3.6 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.9 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.20.4 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stoewer/go-strcase v1.3.0 // indirect + github.com/stoewer/go-strcase v1.2.0 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect - go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.29.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.24.0 // indirect + go.uber.org/zap v1.26.0 // indirect + golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/grpc v1.66.2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.31.1 // indirect - k8s.io/apiserver v0.31.1 // indirect - k8s.io/component-base v0.31.1 // indirect + k8s.io/apiextensions-apiserver v0.31.0 // indirect + k8s.io/apiserver v0.31.0 // indirect + k8s.io/component-base v0.31.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 // indirect - k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect - sigs.k8s.io/gateway-api v1.1.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/testdata/project-v4/internal/controller/admiral_controller.go b/testdata/project-v4/internal/controller/admiral_controller.go deleted file mode 100644 index 397aa618e76..00000000000 --- a/testdata/project-v4/internal/controller/admiral_controller.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2024 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 controller - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" -) - -// AdmiralReconciler reconciles a Admiral object -type AdmiralReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=crew.testproject.org,resources=admirales,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=crew.testproject.org,resources=admirales/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=crew.testproject.org,resources=admirales/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.19.0/pkg/reconcile -func (r *AdmiralReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *AdmiralReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&crewv1.Admiral{}). - Named("admiral"). - Complete(r) -} diff --git a/testdata/project-v4/internal/controller/admiral_controller_test.go b/testdata/project-v4/internal/controller/admiral_controller_test.go deleted file mode 100644 index c807fe051f9..00000000000 --- a/testdata/project-v4/internal/controller/admiral_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2024 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 controller - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" -) - -var _ = Describe("Admiral Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - admiral := &crewv1.Admiral{} - - BeforeEach(func() { - By("creating the custom resource for the Kind Admiral") - err := k8sClient.Get(ctx, typeNamespacedName, admiral) - if err != nil && errors.IsNotFound(err) { - resource := &crewv1.Admiral{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &crewv1.Admiral{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance Admiral") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &AdmiralReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4/internal/controller/certificate_controller.go b/testdata/project-v4/internal/controller/certificate_controller.go deleted file mode 100644 index 4681dca6e68..00000000000 --- a/testdata/project-v4/internal/controller/certificate_controller.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2024 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 controller - -import ( - "context" - - certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" -) - -// CertificateReconciler reconciles a Certificate object -type CertificateReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates/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 Certificate 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.19.0/pkg/reconcile -func (r *CertificateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *CertificateReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&certmanagerv1.Certificate{}). - Named("certificate"). - Complete(r) -} diff --git a/testdata/project-v4/internal/controller/certificate_controller_test.go b/testdata/project-v4/internal/controller/certificate_controller_test.go deleted file mode 100644 index 258f99dc795..00000000000 --- a/testdata/project-v4/internal/controller/certificate_controller_test.go +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright 2024 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 controller - -import ( - . "github.com/onsi/ginkgo/v2" -) - -var _ = Describe("Certificate Controller", func() { - Context("When reconciling a resource", func() { - - It("should successfully reconcile the resource", func() { - - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4/internal/controller/firstmate_controller.go b/testdata/project-v4/internal/controller/firstmate_controller.go deleted file mode 100644 index 7f4a58c99a9..00000000000 --- a/testdata/project-v4/internal/controller/firstmate_controller.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2024 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 controller - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" -) - -// FirstMateReconciler reconciles a FirstMate object -type FirstMateReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -// +kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates/finalizers,verbs=update - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// TODO(user): Modify the Reconcile function to compare the state specified by -// the FirstMate object against the actual cluster state, and then -// perform operations to make the cluster state reflect the state specified by -// the user. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/reconcile -func (r *FirstMateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) - - // TODO(user): your logic here - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *FirstMateReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&crewv1.FirstMate{}). - Named("firstmate"). - Complete(r) -} diff --git a/testdata/project-v4/internal/controller/firstmate_controller_test.go b/testdata/project-v4/internal/controller/firstmate_controller_test.go deleted file mode 100644 index e5bc9666411..00000000000 --- a/testdata/project-v4/internal/controller/firstmate_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2024 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 controller - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" -) - -var _ = Describe("FirstMate Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - firstmate := &crewv1.FirstMate{} - - BeforeEach(func() { - By("creating the custom resource for the Kind FirstMate") - err := k8sClient.Get(ctx, typeNamespacedName, firstmate) - if err != nil && errors.IsNotFound(err) { - resource := &crewv1.FirstMate{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &crewv1.FirstMate{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance FirstMate") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &FirstMateReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/testdata/project-v4/internal/controller/suite_test.go b/testdata/project-v4/internal/controller/suite_test.go index 1bb1c72bada..a0cd2217f5a 100644 --- a/testdata/project-v4/internal/controller/suite_test.go +++ b/testdata/project-v4/internal/controller/suite_test.go @@ -33,8 +33,6 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" // +kubebuilder:scaffold:imports ) @@ -82,9 +80,6 @@ var _ = BeforeSuite(func() { err = crewv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = certmanagerv1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - // +kubebuilder:scaffold:scheme k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) diff --git a/testdata/project-v4/internal/webhook/v1/admiral_webhook.go b/testdata/project-v4/internal/webhook/v1/admiral_webhook.go deleted file mode 100644 index c4b9086f4ef..00000000000 --- a/testdata/project-v4/internal/webhook/v1/admiral_webhook.go +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright 2024 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" - "fmt" - - "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" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" -) - -// nolint:unused -// log is for logging in this package. -var admirallog = logf.Log.WithName("admiral-resource") - -// SetupAdmiralWebhookWithManager registers the webhook for Admiral in the manager. -func SetupAdmiralWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&crewv1.Admiral{}). - WithDefaulter(&AdmiralCustomDefaulter{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -// +kubebuilder:webhook:path=/mutate-crew-testproject-org-v1-admiral,mutating=true,failurePolicy=fail,sideEffects=None,groups=crew.testproject.org,resources=admirales,verbs=create;update,versions=v1,name=madmiral-v1.kb.io,admissionReviewVersions=v1 - -// AdmiralCustomDefaulter struct is responsible for setting default values on the custom resource of the -// Kind Admiral when those are created or updated. -// -// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, -// as it is used only for temporary operations and does not need to be deeply copied. -type AdmiralCustomDefaulter struct { - // TODO(user): Add more fields as needed for defaulting -} - -var _ webhook.CustomDefaulter = &AdmiralCustomDefaulter{} - -// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind Admiral. -func (d *AdmiralCustomDefaulter) Default(ctx context.Context, obj runtime.Object) error { - admiral, ok := obj.(*crewv1.Admiral) - - if !ok { - return fmt.Errorf("expected an Admiral object but got %T", obj) - } - admirallog.Info("Defaulting for Admiral", "name", admiral.GetName()) - - // TODO(user): fill in your defaulting logic. - - return nil -} diff --git a/testdata/project-v4/internal/webhook/v1/admiral_webhook_test.go b/testdata/project-v4/internal/webhook/v1/admiral_webhook_test.go deleted file mode 100644 index 1f85a130bfd..00000000000 --- a/testdata/project-v4/internal/webhook/v1/admiral_webhook_test.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2024 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 ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("Admiral Webhook", func() { - var ( - obj *crewv1.Admiral - oldObj *crewv1.Admiral - defaulter AdmiralCustomDefaulter - ) - - BeforeEach(func() { - obj = &crewv1.Admiral{} - oldObj = &crewv1.Admiral{} - defaulter = AdmiralCustomDefaulter{} - Expect(defaulter).NotTo(BeNil(), "Expected defaulter to be initialized") - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating Admiral under Defaulting Webhook", func() { - // TODO (user): Add logic for defaulting webhooks - // Example: - // It("Should apply defaults when a required field is empty", func() { - // By("simulating a scenario where defaults should be applied") - // obj.SomeFieldWithDefault = "" - // By("calling the Default method to apply defaults") - // defaulter.Default(ctx, obj) - // By("checking that the default values are set") - // Expect(obj.SomeFieldWithDefault).To(Equal("default_value")) - // }) - }) - -}) diff --git a/testdata/project-v4/internal/webhook/v1/firstmate_webhook.go b/testdata/project-v4/internal/webhook/v1/firstmate_webhook.go deleted file mode 100644 index 8b009e57c05..00000000000 --- a/testdata/project-v4/internal/webhook/v1/firstmate_webhook.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2024 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" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" -) - -// nolint:unused -// log is for logging in this package. -var firstmatelog = logf.Log.WithName("firstmate-resource") - -// SetupFirstMateWebhookWithManager registers the webhook for FirstMate in the manager. -func SetupFirstMateWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&crewv1.FirstMate{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! diff --git a/testdata/project-v4/internal/webhook/v1/firstmate_webhook_test.go b/testdata/project-v4/internal/webhook/v1/firstmate_webhook_test.go deleted file mode 100644 index 35bb8b670f7..00000000000 --- a/testdata/project-v4/internal/webhook/v1/firstmate_webhook_test.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2024 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 ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("FirstMate Webhook", func() { - var ( - obj *crewv1.FirstMate - oldObj *crewv1.FirstMate - ) - - BeforeEach(func() { - obj = &crewv1.FirstMate{} - oldObj = &crewv1.FirstMate{} - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating FirstMate under Conversion Webhook", func() { - // TODO (user): Add logic to convert the object to the desired version and verify the conversion - // Example: - // It("Should convert the object correctly", func() { - // convertedObj := &crewv1.FirstMate{} - // Expect(obj.ConvertTo(convertedObj)).To(Succeed()) - // Expect(convertedObj).ToNot(BeNil()) - // }) - }) - -}) diff --git a/testdata/project-v4/internal/webhook/v1/issuer_webhook.go b/testdata/project-v4/internal/webhook/v1/issuer_webhook.go deleted file mode 100644 index 9160e4e89f5..00000000000 --- a/testdata/project-v4/internal/webhook/v1/issuer_webhook.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 2024 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" - "fmt" - - certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - "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" -) - -// nolint:unused -// log is for logging in this package. -var issuerlog = logf.Log.WithName("issuer-resource") - -// SetupIssuerWebhookWithManager registers the webhook for Issuer in the manager. -func SetupIssuerWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&certmanagerv1.Issuer{}). - WithDefaulter(&IssuerCustomDefaulter{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -// +kubebuilder:webhook:path=/mutate-cert-manager-io-v1-issuer,mutating=true,failurePolicy=fail,sideEffects=None,groups=cert-manager.io,resources=issuers,verbs=create;update,versions=v1,name=missuer-v1.kb.io,admissionReviewVersions=v1 - -// IssuerCustomDefaulter struct is responsible for setting default values on the custom resource of the -// Kind Issuer when those are created or updated. -// -// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, -// as it is used only for temporary operations and does not need to be deeply copied. -type IssuerCustomDefaulter struct { - // TODO(user): Add more fields as needed for defaulting -} - -var _ webhook.CustomDefaulter = &IssuerCustomDefaulter{} - -// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind Issuer. -func (d *IssuerCustomDefaulter) Default(ctx context.Context, obj runtime.Object) error { - issuer, ok := obj.(*certmanagerv1.Issuer) - - if !ok { - return fmt.Errorf("expected an Issuer object but got %T", obj) - } - issuerlog.Info("Defaulting for Issuer", "name", issuer.GetName()) - - // TODO(user): fill in your defaulting logic. - - return nil -} diff --git a/testdata/project-v4/internal/webhook/v1/issuer_webhook_test.go b/testdata/project-v4/internal/webhook/v1/issuer_webhook_test.go deleted file mode 100644 index b9d0dfeeb23..00000000000 --- a/testdata/project-v4/internal/webhook/v1/issuer_webhook_test.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2024 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 ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("Issuer Webhook", func() { - var ( - obj *certmanagerv1.Issuer - oldObj *certmanagerv1.Issuer - defaulter IssuerCustomDefaulter - ) - - BeforeEach(func() { - obj = &certmanagerv1.Issuer{} - oldObj = &certmanagerv1.Issuer{} - defaulter = IssuerCustomDefaulter{} - Expect(defaulter).NotTo(BeNil(), "Expected defaulter to be initialized") - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating Issuer under Defaulting Webhook", func() { - // TODO (user): Add logic for defaulting webhooks - // Example: - // It("Should apply defaults when a required field is empty", func() { - // By("simulating a scenario where defaults should be applied") - // obj.SomeFieldWithDefault = "" - // By("calling the Default method to apply defaults") - // defaulter.Default(ctx, obj) - // By("checking that the default values are set") - // Expect(obj.SomeFieldWithDefault).To(Equal("default_value")) - // }) - }) - -}) diff --git a/testdata/project-v4/internal/webhook/v1/pod_webhook.go b/testdata/project-v4/internal/webhook/v1/pod_webhook.go deleted file mode 100644 index 3671dde49f6..00000000000 --- a/testdata/project-v4/internal/webhook/v1/pod_webhook.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 2024 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" - "fmt" - - corev1 "k8s.io/api/core/v1" - "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" -) - -// nolint:unused -// log is for logging in this package. -var podlog = logf.Log.WithName("pod-resource") - -// SetupPodWebhookWithManager registers the webhook for Pod in the manager. -func SetupPodWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&corev1.Pod{}). - WithDefaulter(&PodCustomDefaulter{}). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -// +kubebuilder:webhook:path=/mutate--v1-pod,mutating=true,failurePolicy=fail,sideEffects=None,groups="",resources=pods,verbs=create;update,versions=v1,name=mpod-v1.kb.io,admissionReviewVersions=v1 - -// PodCustomDefaulter struct is responsible for setting default values on the custom resource of the -// Kind Pod when those are created or updated. -// -// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, -// as it is used only for temporary operations and does not need to be deeply copied. -type PodCustomDefaulter struct { - // TODO(user): Add more fields as needed for defaulting -} - -var _ webhook.CustomDefaulter = &PodCustomDefaulter{} - -// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind Pod. -func (d *PodCustomDefaulter) Default(ctx context.Context, obj runtime.Object) error { - pod, ok := obj.(*corev1.Pod) - - if !ok { - return fmt.Errorf("expected an Pod object but got %T", obj) - } - podlog.Info("Defaulting for Pod", "name", pod.GetName()) - - // TODO(user): fill in your defaulting logic. - - return nil -} diff --git a/testdata/project-v4/internal/webhook/v1/pod_webhook_test.go b/testdata/project-v4/internal/webhook/v1/pod_webhook_test.go deleted file mode 100644 index 1d7c3191c5a..00000000000 --- a/testdata/project-v4/internal/webhook/v1/pod_webhook_test.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2024 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 ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - corev1 "k8s.io/api/core/v1" - // TODO (user): Add any additional imports if needed -) - -var _ = Describe("Pod Webhook", func() { - var ( - obj *corev1.Pod - oldObj *corev1.Pod - defaulter PodCustomDefaulter - ) - - BeforeEach(func() { - obj = &corev1.Pod{} - oldObj = &corev1.Pod{} - defaulter = PodCustomDefaulter{} - Expect(defaulter).NotTo(BeNil(), "Expected defaulter to be initialized") - Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") - Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") - // TODO (user): Add any setup logic common to all tests - }) - - AfterEach(func() { - // TODO (user): Add any teardown logic common to all tests - }) - - Context("When creating Pod under Defaulting Webhook", func() { - // TODO (user): Add logic for defaulting webhooks - // Example: - // It("Should apply defaults when a required field is empty", func() { - // By("simulating a scenario where defaults should be applied") - // obj.SomeFieldWithDefault = "" - // By("calling the Default method to apply defaults") - // defaulter.Default(ctx, obj) - // By("checking that the default values are set") - // Expect(obj.SomeFieldWithDefault).To(Equal("default_value")) - // }) - }) - -}) diff --git a/testdata/project-v4/internal/webhook/v1/webhook_suite_test.go b/testdata/project-v4/internal/webhook/v1/webhook_suite_test.go index 56342e75c66..6ced1d85119 100644 --- a/testdata/project-v4/internal/webhook/v1/webhook_suite_test.go +++ b/testdata/project-v4/internal/webhook/v1/webhook_suite_test.go @@ -121,15 +121,6 @@ var _ = BeforeSuite(func() { err = SetupCaptainWebhookWithManager(mgr) Expect(err).NotTo(HaveOccurred()) - err = SetupAdmiralWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - err = SetupIssuerWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - err = SetupPodWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - // +kubebuilder:scaffold:webhook go func() {