From 60b0e1863ccc0a1accdd182dc066f4c943d937de Mon Sep 17 00:00:00 2001 From: Yuedong Wu <57584831+lunarwhite@users.noreply.github.com> Date: Fri, 1 Mar 2024 13:09:57 +0000 Subject: [PATCH] Add CRD viewer and editor roles in rbac/kustomization.yaml --- .../project/config/rbac/kustomization.yaml | 3 + .../project/config/rbac/kustomization.yaml | 3 + docs/book/src/getting-started.md | 13 +- .../project/config/rbac/kustomization.yaml | 3 + pkg/plugin/util/util.go | 17 ++ .../common/kustomize/v2/scaffolds/api.go | 11 ++ .../templates/config/rbac/kustomization.go | 1 + test/e2e/v4/plugin_cluster_test.go | 15 -- .../config/rbac/kustomization.yaml | 19 ++ .../config/rbac/kustomization.yaml | 19 ++ .../config/rbac/kustomization.yaml | 5 + .../dist/install.yaml | 116 ++++++++++++ .../config/rbac/kustomization.yaml | 1 + .../project-v4/config/rbac/kustomization.yaml | 7 + testdata/project-v4/dist/install.yaml | 174 ++++++++++++++++++ 15 files changed, 385 insertions(+), 22 deletions(-) diff --git a/docs/book/src/component-config-tutorial/testdata/project/config/rbac/kustomization.yaml b/docs/book/src/component-config-tutorial/testdata/project/config/rbac/kustomization.yaml index 731832a6ac3..23d33a801a6 100644 --- a/docs/book/src/component-config-tutorial/testdata/project/config/rbac/kustomization.yaml +++ b/docs/book/src/component-config-tutorial/testdata/project/config/rbac/kustomization.yaml @@ -16,3 +16,6 @@ resources: - auth_proxy_role.yaml - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml +# Editor and Viewer roles for each CRD to be used by end users. +- projectconfig_editor_role.yaml +- projectconfig_viewer_role.yaml 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 731832a6ac3..3a8b45dd8c0 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 @@ -16,3 +16,6 @@ resources: - auth_proxy_role.yaml - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml +# Editor and Viewer roles for each CRD to be used by end users. +- cronjob_editor_role.yaml +- cronjob_viewer_role.yaml diff --git a/docs/book/src/getting-started.md b/docs/book/src/getting-started.md index 22bfcec5cbc..c894af48c80 100644 --- a/docs/book/src/getting-started.md +++ b/docs/book/src/getting-started.md @@ -2,8 +2,8 @@ ## Overview -By following the [Operator Pattern][k8s-operator-pattern], it’s possible not only to provide all expected resources -but also to manage them dynamically, programmatically, and at execution time. To illustrate this idea, imagine if +By following the [Operator Pattern][k8s-operator-pattern], it’s possible not only to provide all expected resources +but also to manage them dynamically, programmatically, and at execution time. To illustrate this idea, imagine if someone accidentally changed a configuration or removed a resource by mistake; in this case, the operator could fix it without any human intervention. @@ -146,13 +146,13 @@ reconcile App { return reconcile.Result{}, err } - // Check if a Service for the app exists, if not, create one + // Check if a Service for the app exists, if not, create one // If there's an error, then restart from the beginning of the reconcile if err != nil { return reconcile.Result{}, err } - // Look for Database CR/CRD + // Look for Database CR/CRD // Check the Database Deployment's replicas size // If deployment.replicas size doesn't match cr.size, then update it // Then, restart from the beginning of the reconcile. For example, by returning `reconcile.Result{Requeue: true}, nil`. @@ -162,7 +162,7 @@ reconcile App { ... // If at the end of the loop: - // Everything was executed successfully, and the reconcile can stop + // Everything was executed successfully, and the reconcile can stop return reconcile.Result{}, nil } @@ -181,7 +181,7 @@ return ctrl.Result{}, err ```go return ctrl.Result{Requeue: true}, nil -``` +``` - Therefore, to stop the Reconcile, use: @@ -464,7 +464,6 @@ After making the necessary changes, run the `make generate` command. This will p

RBAC generate under config/rbac

For each Kind, Kubebuilder will generate scaffold rules with view and edit permissions. (i.e. `memcached_editor_role.yaml` and `memcached_viewer_role.yaml`) -Those rules are not applied on the cluster when you deploy your solution with `make deploy IMG=myregistery/example:1.0.0`. Those rules are aimed to help system admins know what to allow when granting permissions to a group of users. 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 731832a6ac3..a141a481f83 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 @@ -16,3 +16,6 @@ resources: - auth_proxy_role.yaml - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml +# Editor and Viewer roles for each CRD to be used by end users. +- memcached_editor_role.yaml +- memcached_viewer_role.yaml diff --git a/pkg/plugin/util/util.go b/pkg/plugin/util/util.go index d4b34d5d616..ebf5418adda 100644 --- a/pkg/plugin/util/util.go +++ b/pkg/plugin/util/util.go @@ -80,6 +80,23 @@ func InsertCode(filename, target, code string) error { return os.WriteFile(filename, []byte(out), 0644) } +// InsertCodeIfNotExist insert code if it does not already exists +func InsertCodeIfNotExist(filename, target, code string) error { + // false positive + // nolint:gosec + contents, err := os.ReadFile(filename) + if err != nil { + return err + } + + idx := strings.Index(string(contents), code) + if idx != -1 { + return nil + } + + return InsertCode(filename, target, code) +} + // UncommentCode searches for target in the file and remove the comment prefix // of the target content. The target content may span multiple lines. func UncommentCode(filename, target, prefix string) error { diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/api.go b/pkg/plugins/common/kustomize/v2/scaffolds/api.go index 21afda71155..d846ef28b4b 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/api.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/api.go @@ -18,6 +18,7 @@ package scaffolds import ( "fmt" + "strings" pluginutil "sigs.k8s.io/kubebuilder/v3/pkg/plugin/util" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/crd" @@ -98,6 +99,16 @@ func (s *apiScaffolder) Scaffold() error { "%s.", kustomizeFilePath) } } + + rbacKustomizeFilePath := "config/rbac/kustomization.yaml" + crdKind := strings.ToLower(s.resource.Kind) + err = pluginutil.InsertCodeIfNotExist(rbacKustomizeFilePath, + "# Editor and Viewer roles for each CRD to be used by end users.", + fmt.Sprintf("\n- %[1]s_editor_role.yaml\n- %[1]s_viewer_role.yaml", crdKind)) + if err != nil { + log.Errorf("Unable to add Editor and Viewer roles in the file "+ + "%s.", rbacKustomizeFilePath) + } } return nil diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/kustomization.go index d3ea9b22fd9..a4015d97ab4 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/kustomization.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac/kustomization.go @@ -60,4 +60,5 @@ const kustomizeRBACTemplate = `resources: - auth_proxy_role.yaml - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml +# Editor and Viewer roles for each CRD to be used by end users. ` diff --git a/test/e2e/v4/plugin_cluster_test.go b/test/e2e/v4/plugin_cluster_test.go index fad1ee7b495..324e95b78f9 100644 --- a/test/e2e/v4/plugin_cluster_test.go +++ b/test/e2e/v4/plugin_cluster_test.go @@ -284,21 +284,6 @@ func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller bool) { return err }, time.Minute, time.Second).Should(Succeed()) - By("applying the CRD Editor Role") - crdEditorRole := filepath.Join("config", "rbac", - fmt.Sprintf("%s_editor_role.yaml", strings.ToLower(kbc.Kind))) - EventuallyWithOffset(1, func() error { - _, err = kbc.Kubectl.Apply(true, "-f", crdEditorRole) - return err - }, time.Minute, time.Second).Should(Succeed()) - - By("applying the CRD Viewer Role") - crdViewerRole := filepath.Join("config", "rbac", fmt.Sprintf("%s_viewer_role.yaml", strings.ToLower(kbc.Kind))) - EventuallyWithOffset(1, func() error { - _, err = kbc.Kubectl.Apply(true, "-f", crdViewerRole) - return err - }, time.Minute, time.Second).Should(Succeed()) - By("validating that the created resource object gets reconciled in the controller") metricsOutput := curlMetrics(kbc) ExpectWithOffset(1, metricsOutput).To(ContainSubstring(fmt.Sprintf( diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/kustomization.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/kustomization.yaml index 731832a6ac3..0a4a47efdd4 100644 --- a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/kustomization.yaml +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/kustomization.yaml @@ -16,3 +16,22 @@ resources: - auth_proxy_role.yaml - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml +# Editor and Viewer roles for each CRD to be used by end users. +- lakers_editor_role.yaml +- lakers_viewer_role.yaml +- bar_editor_role.yaml +- bar_viewer_role.yaml +- healthcheckpolicy_editor_role.yaml +- healthcheckpolicy_viewer_role.yaml +- leviathan_editor_role.yaml +- leviathan_viewer_role.yaml +- kraken_editor_role.yaml +- kraken_viewer_role.yaml +- cruiser_editor_role.yaml +- cruiser_viewer_role.yaml +- destroyer_editor_role.yaml +- destroyer_viewer_role.yaml +- frigate_editor_role.yaml +- frigate_viewer_role.yaml +- captain_editor_role.yaml +- captain_viewer_role.yaml diff --git a/testdata/project-v4-multigroup/config/rbac/kustomization.yaml b/testdata/project-v4-multigroup/config/rbac/kustomization.yaml index 731832a6ac3..0a4a47efdd4 100644 --- a/testdata/project-v4-multigroup/config/rbac/kustomization.yaml +++ b/testdata/project-v4-multigroup/config/rbac/kustomization.yaml @@ -16,3 +16,22 @@ resources: - auth_proxy_role.yaml - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml +# Editor and Viewer roles for each CRD to be used by end users. +- lakers_editor_role.yaml +- lakers_viewer_role.yaml +- bar_editor_role.yaml +- bar_viewer_role.yaml +- healthcheckpolicy_editor_role.yaml +- healthcheckpolicy_viewer_role.yaml +- leviathan_editor_role.yaml +- leviathan_viewer_role.yaml +- kraken_editor_role.yaml +- kraken_viewer_role.yaml +- cruiser_editor_role.yaml +- cruiser_viewer_role.yaml +- destroyer_editor_role.yaml +- destroyer_viewer_role.yaml +- frigate_editor_role.yaml +- frigate_viewer_role.yaml +- captain_editor_role.yaml +- captain_viewer_role.yaml diff --git a/testdata/project-v4-with-deploy-image/config/rbac/kustomization.yaml b/testdata/project-v4-with-deploy-image/config/rbac/kustomization.yaml index 731832a6ac3..25b981b5056 100644 --- a/testdata/project-v4-with-deploy-image/config/rbac/kustomization.yaml +++ b/testdata/project-v4-with-deploy-image/config/rbac/kustomization.yaml @@ -16,3 +16,8 @@ resources: - auth_proxy_role.yaml - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml +# Editor and Viewer roles for each CRD to be used by end users. +- busybox_editor_role.yaml +- busybox_viewer_role.yaml +- memcached_editor_role.yaml +- memcached_viewer_role.yaml diff --git a/testdata/project-v4-with-deploy-image/dist/install.yaml b/testdata/project-v4-with-deploy-image/dist/install.yaml index b0be01a0443..a26e1498f8b 100644 --- a/testdata/project-v4-with-deploy-image/dist/install.yaml +++ b/testdata/project-v4-with-deploy-image/dist/install.yaml @@ -617,6 +617,64 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-with-deploy-image + app.kubernetes.io/instance: busybox-editor-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: project-v4-with-deploy-image + name: project-v4-with-deploy-image-busybox-editor-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-with-deploy-image + app.kubernetes.io/instance: busybox-viewer-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: project-v4-with-deploy-image + name: project-v4-with-deploy-image-busybox-viewer-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - get + - list + - watch +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: name: project-v4-with-deploy-image-manager-role rules: @@ -702,6 +760,64 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-with-deploy-image + app.kubernetes.io/instance: memcached-editor-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: project-v4-with-deploy-image + name: project-v4-with-deploy-image-memcached-editor-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-with-deploy-image + app.kubernetes.io/instance: memcached-viewer-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: project-v4-with-deploy-image + name: project-v4-with-deploy-image-memcached-viewer-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - get + - list + - watch +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: labels: app.kubernetes.io/component: kube-rbac-proxy diff --git a/testdata/project-v4-with-grafana/config/rbac/kustomization.yaml b/testdata/project-v4-with-grafana/config/rbac/kustomization.yaml index 731832a6ac3..0b75e8f7717 100644 --- a/testdata/project-v4-with-grafana/config/rbac/kustomization.yaml +++ b/testdata/project-v4-with-grafana/config/rbac/kustomization.yaml @@ -16,3 +16,4 @@ resources: - auth_proxy_role.yaml - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml +# Editor and Viewer roles for each CRD to be used by end users. diff --git a/testdata/project-v4/config/rbac/kustomization.yaml b/testdata/project-v4/config/rbac/kustomization.yaml index 731832a6ac3..a094f146418 100644 --- a/testdata/project-v4/config/rbac/kustomization.yaml +++ b/testdata/project-v4/config/rbac/kustomization.yaml @@ -16,3 +16,10 @@ resources: - auth_proxy_role.yaml - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml +# Editor and Viewer roles for each CRD to be used by end users. +- admiral_editor_role.yaml +- admiral_viewer_role.yaml +- firstmate_editor_role.yaml +- firstmate_viewer_role.yaml +- captain_editor_role.yaml +- captain_viewer_role.yaml diff --git a/testdata/project-v4/dist/install.yaml b/testdata/project-v4/dist/install.yaml index cedf2b137b6..92d85753ece 100644 --- a/testdata/project-v4/dist/install.yaml +++ b/testdata/project-v4/dist/install.yaml @@ -455,6 +455,180 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4 + app.kubernetes.io/instance: admiral-editor-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: project-v4 + name: project-v4-admiral-editor-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirales + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - admirales/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4 + app.kubernetes.io/instance: admiral-viewer-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: project-v4 + name: project-v4-admiral-viewer-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirales + verbs: + - get + - list + - watch +- apiGroups: + - crew.testproject.org + resources: + - admirales/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4 + app.kubernetes.io/instance: captain-editor-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: project-v4 + name: project-v4-captain-editor-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - captains + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - captains/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4 + app.kubernetes.io/instance: captain-viewer-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: project-v4 + name: project-v4-captain-viewer-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - captains + verbs: + - get + - list + - watch +- apiGroups: + - crew.testproject.org + resources: + - captains/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4 + app.kubernetes.io/instance: firstmate-editor-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: project-v4 + name: project-v4-firstmate-editor-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - firstmates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - firstmates/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4 + app.kubernetes.io/instance: firstmate-viewer-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: project-v4 + name: project-v4-firstmate-viewer-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - firstmates + verbs: + - get + - list + - watch +- apiGroups: + - crew.testproject.org + resources: + - firstmates/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: name: project-v4-manager-role rules: