From b4511e3cf9aa028e09818863c6d6315f5bfd7e7c Mon Sep 17 00:00:00 2001 From: Anatolii Bazko Date: Mon, 6 Dec 2021 15:25:57 +0200 Subject: [PATCH] fix: delegate permissions to `get, list, watch` `pods/log` resources (#1212) * fix: delegate permissions to get, list, watch pods/log resources Signed-off-by: Anatolii Bazko --- .../che-operator.clusterserviceversion.yaml | 12 +++- .../che-operator.clusterserviceversion.yaml | 12 +++- .../che-operator.clusterserviceversion.yaml | 12 +++- config/rbac/cluster_role.yaml | 8 +++ controllers/che/checluster_controller_test.go | 59 ++++++------------- .../che/workspace_namespace_permission.go | 5 ++ helmcharts/next/templates/cluster_role.yaml | 8 +++ pkg/deploy/role.go | 52 ---------------- 8 files changed, 68 insertions(+), 100 deletions(-) diff --git a/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml b/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml index ec75a36cd..ccc2aeae0 100644 --- a/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml @@ -126,7 +126,7 @@ metadata: operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/eclipse-che/che-operator support: Eclipse Foundation - name: eclipse-che-preview-openshift.v7.40.0-382.next-all-namespaces + name: eclipse-che-preview-openshift.v7.40.0-383.next-all-namespaces namespace: placeholder spec: apiservicedefinitions: {} @@ -768,6 +768,14 @@ spec: - consoles verbs: - get + - apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - list + - watch - apiGroups: - workspace.devfile.io resources: @@ -1450,4 +1458,4 @@ spec: maturity: stable provider: name: Eclipse Foundation - version: 7.40.0-382.next-all-namespaces + version: 7.40.0-383.next-all-namespaces diff --git a/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml b/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml index 6214506d2..6974ea039 100644 --- a/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml @@ -133,7 +133,7 @@ metadata: operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/eclipse-che/che-operator support: Eclipse Foundation - name: eclipse-che-preview-kubernetes.v7.40.0-382.next + name: eclipse-che-preview-kubernetes.v7.40.0-383.next namespace: placeholder spec: apiservicedefinitions: {} @@ -755,6 +755,14 @@ spec: - kubernetesimagepullers verbs: - '*' + - apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - list + - watch - apiGroups: - workspace.devfile.io resources: @@ -1417,4 +1425,4 @@ spec: maturity: stable provider: name: Eclipse Foundation - version: 7.40.0-382.next + version: 7.40.0-383.next diff --git a/bundle/next/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml b/bundle/next/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml index d30064a20..070a954a4 100644 --- a/bundle/next/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/next/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml @@ -126,7 +126,7 @@ metadata: operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/eclipse-che/che-operator support: Eclipse Foundation - name: eclipse-che-preview-openshift.v7.40.0-382.next + name: eclipse-che-preview-openshift.v7.40.0-383.next namespace: placeholder spec: apiservicedefinitions: {} @@ -768,6 +768,14 @@ spec: - consoles verbs: - get + - apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - list + - watch - apiGroups: - workspace.devfile.io resources: @@ -1450,4 +1458,4 @@ spec: maturity: stable provider: name: Eclipse Foundation - version: 7.40.0-382.next + version: 7.40.0-383.next diff --git a/config/rbac/cluster_role.yaml b/config/rbac/cluster_role.yaml index 943dabe17..46f050a2f 100644 --- a/config/rbac/cluster_role.yaml +++ b/config/rbac/cluster_role.yaml @@ -365,6 +365,14 @@ rules: - cluster verbs: - get + - apiGroups: + - '' + resources: + - pods/log + verbs: + - get + - list + - watch ### CHE-OPERATOR ROLES ONLY: END # devworkspace-controller-view-workspaces.ClusterRole.yaml - apiGroups: diff --git a/controllers/che/checluster_controller_test.go b/controllers/che/checluster_controller_test.go index aa27fb37f..8e37751cf 100644 --- a/controllers/che/checluster_controller_test.go +++ b/controllers/che/checluster_controller_test.go @@ -799,49 +799,24 @@ func TestShouldDelegatePermissionsForCheWorkspaces(t *testing.T) { t.Fatalf("Error reconciling: %v", err) } - if !testCase.clusterRole { - viewRole := &rbac.Role{} - if err := r.client.Get(context.TODO(), types.NamespacedName{Name: deploy.ViewRoleName, Namespace: namespace}, viewRole); err != nil { - t.Errorf("role '%s' not found", deploy.ViewRoleName) - } - viewRoleBinding := &rbac.RoleBinding{} - if err := r.client.Get(context.TODO(), types.NamespacedName{Name: ViewRoleBindingName, Namespace: namespace}, viewRoleBinding); err != nil { - t.Errorf("rolebinding '%s' not found", ViewRoleBindingName) - } + manageNamespacesClusterRoleName := fmt.Sprintf(CheNamespaceEditorClusterRoleNameTemplate, namespace) + cheManageNamespaceClusterRole := &rbac.ClusterRole{} + if err := r.nonCachedClient.Get(context.TODO(), types.NamespacedName{Name: manageNamespacesClusterRoleName}, cheManageNamespaceClusterRole); err != nil { + t.Errorf("role '%s' not found", manageNamespacesClusterRoleName) + } + cheManageNamespaceClusterRoleBinding := &rbac.ClusterRoleBinding{} + if err := r.nonCachedClient.Get(context.TODO(), types.NamespacedName{Name: manageNamespacesClusterRoleName}, cheManageNamespaceClusterRoleBinding); err != nil { + t.Errorf("rolebinding '%s' not found", manageNamespacesClusterRoleName) + } - execRole := &rbac.Role{} - if err := r.client.Get(context.TODO(), types.NamespacedName{Name: deploy.ExecRoleName, Namespace: namespace}, execRole); err != nil { - t.Errorf("role '%s' not found", deploy.ExecRoleName) - } - execRoleBinding := &rbac.RoleBinding{} - if err := r.client.Get(context.TODO(), types.NamespacedName{Name: ExecRoleBindingName, Namespace: namespace}, execRoleBinding); err != nil { - t.Errorf("rolebinding '%s' not found", ExecRoleBindingName) - } - - editRoleBinding := &rbac.RoleBinding{} - if err := r.client.Get(context.TODO(), types.NamespacedName{Name: EditRoleBindingName, Namespace: namespace}, editRoleBinding); err != nil { - t.Errorf("rolebinding '%s' not found", EditRoleBindingName) - } - } else { - manageNamespacesClusterRoleName := fmt.Sprintf(CheNamespaceEditorClusterRoleNameTemplate, namespace) - cheManageNamespaceClusterRole := &rbac.ClusterRole{} - if err := r.nonCachedClient.Get(context.TODO(), types.NamespacedName{Name: manageNamespacesClusterRoleName}, cheManageNamespaceClusterRole); err != nil { - t.Errorf("role '%s' not found", manageNamespacesClusterRoleName) - } - cheManageNamespaceClusterRoleBinding := &rbac.ClusterRoleBinding{} - if err := r.nonCachedClient.Get(context.TODO(), types.NamespacedName{Name: manageNamespacesClusterRoleName}, cheManageNamespaceClusterRoleBinding); err != nil { - t.Errorf("rolebinding '%s' not found", manageNamespacesClusterRoleName) - } - - cheWorkspacesClusterRoleName := fmt.Sprintf(CheWorkspacesClusterRoleNameTemplate, namespace) - cheWorkspacesClusterRole := &rbac.ClusterRole{} - if err := r.nonCachedClient.Get(context.TODO(), types.NamespacedName{Name: cheWorkspacesClusterRoleName}, cheWorkspacesClusterRole); err != nil { - t.Errorf("role '%s' not found", cheWorkspacesClusterRole) - } - cheWorkspacesClusterRoleBinding := &rbac.ClusterRoleBinding{} - if err := r.nonCachedClient.Get(context.TODO(), types.NamespacedName{Name: cheWorkspacesClusterRoleName}, cheWorkspacesClusterRoleBinding); err != nil { - t.Errorf("rolebinding '%s' not found", cheWorkspacesClusterRole) - } + cheWorkspacesClusterRoleName := fmt.Sprintf(CheWorkspacesClusterRoleNameTemplate, namespace) + cheWorkspacesClusterRole := &rbac.ClusterRole{} + if err := r.nonCachedClient.Get(context.TODO(), types.NamespacedName{Name: cheWorkspacesClusterRoleName}, cheWorkspacesClusterRole); err != nil { + t.Errorf("role '%s' not found", cheWorkspacesClusterRole) + } + cheWorkspacesClusterRoleBinding := &rbac.ClusterRoleBinding{} + if err := r.nonCachedClient.Get(context.TODO(), types.NamespacedName{Name: cheWorkspacesClusterRoleName}, cheWorkspacesClusterRoleBinding); err != nil { + t.Errorf("rolebinding '%s' not found", cheWorkspacesClusterRole) } }) } diff --git a/controllers/che/workspace_namespace_permission.go b/controllers/che/workspace_namespace_permission.go index ee1da7de1..3196517a7 100644 --- a/controllers/che/workspace_namespace_permission.go +++ b/controllers/che/workspace_namespace_permission.go @@ -253,6 +253,11 @@ func getWorkspacesPolicies() []rbac.PolicyRule { Resources: []string{"pods/exec"}, Verbs: []string{"create"}, }, + { + APIGroups: []string{""}, + Resources: []string{"pods/log"}, + Verbs: []string{"get", "list", "watch"}, + }, { APIGroups: []string{""}, Resources: []string{"persistentvolumeclaims", "configmaps"}, diff --git a/helmcharts/next/templates/cluster_role.yaml b/helmcharts/next/templates/cluster_role.yaml index 943dabe17..46f050a2f 100644 --- a/helmcharts/next/templates/cluster_role.yaml +++ b/helmcharts/next/templates/cluster_role.yaml @@ -365,6 +365,14 @@ rules: - cluster verbs: - get + - apiGroups: + - '' + resources: + - pods/log + verbs: + - get + - list + - watch ### CHE-OPERATOR ROLES ONLY: END # devworkspace-controller-view-workspaces.ClusterRole.yaml - apiGroups: diff --git a/pkg/deploy/role.go b/pkg/deploy/role.go index 2e6273733..855a2a505 100644 --- a/pkg/deploy/role.go +++ b/pkg/deploy/role.go @@ -18,63 +18,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const ( - // ViewRoleName role to get k8s object needed for Workspace components(metrics plugin, Che terminals, tasks etc.) - ViewRoleName = "view" - // ExecRoleName - role name to create Che terminals and tasks in the workspace. - ExecRoleName = "exec" -) - var roleDiffOpts = cmp.Options{ cmpopts.IgnoreFields(rbac.Role{}, "TypeMeta", "ObjectMeta"), cmpopts.IgnoreFields(rbac.PolicyRule{}, "ResourceNames", "NonResourceURLs"), } -func SyncExecRoleToCluster(deployContext *DeployContext) (bool, error) { - execPolicyRule := []rbac.PolicyRule{ - { - APIGroups: []string{ - "", - }, - Resources: []string{ - "pods/exec", - }, - Verbs: []string{ - "*", - }, - }, - } - return SyncRoleToCluster(deployContext, ExecRoleName, execPolicyRule) -} - -func SyncViewRoleToCluster(deployContext *DeployContext) (bool, error) { - viewPolicyRule := []rbac.PolicyRule{ - { - APIGroups: []string{ - "", - }, - Resources: []string{ - "pods", - }, - Verbs: []string{ - "list", "get", - }, - }, - { - APIGroups: []string{ - "metrics.k8s.io", - }, - Resources: []string{ - "pods", - }, - Verbs: []string{ - "list", "get", "watch", - }, - }, - } - return SyncRoleToCluster(deployContext, ViewRoleName, viewPolicyRule) -} - func SyncRoleToCluster( deployContext *DeployContext, name string,