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: