diff --git a/api/http/models/kubernetes/cluster_role_bindings.go b/api/http/models/kubernetes/cluster_role_bindings.go index 5a709dcac..549c1e1b6 100644 --- a/api/http/models/kubernetes/cluster_role_bindings.go +++ b/api/http/models/kubernetes/cluster_role_bindings.go @@ -1,16 +1,32 @@ package kubernetes import ( + "errors" + "net/http" "time" rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/types" ) type ( K8sClusterRoleBinding struct { Name string `json:"name"` + UID types.UID `json:"uid"` RoleRef rbacv1.RoleRef `json:"roleRef"` Subjects []rbacv1.Subject `json:"subjects"` CreationDate time.Time `json:"creationDate"` + IsSystem bool `json:"isSystem"` } + + // K8sRoleBindingDeleteRequests slice of cluster role cluster bindings. + K8sClusterRoleBindingDeleteRequests []string ) + +func (r K8sClusterRoleBindingDeleteRequests) Validate(request *http.Request) error { + if len(r) == 0 { + return errors.New("missing deletion request list in payload") + } + + return nil +} diff --git a/api/kubernetes/cli/cluster_role_binding.go b/api/kubernetes/cli/cluster_role_binding.go index 070ef1c50..7be781cbc 100644 --- a/api/kubernetes/cli/cluster_role_binding.go +++ b/api/kubernetes/cli/cluster_role_binding.go @@ -3,6 +3,7 @@ package cli import ( "context" "fmt" + "strings" models "github.com/portainer/portainer/api/http/models/kubernetes" rbacv1 "k8s.io/api/rbac/v1" @@ -38,8 +39,37 @@ func (kcl *KubeClient) fetchClusterRoleBindings() ([]models.K8sClusterRoleBindin func parseClusterRoleBinding(clusterRoleBinding rbacv1.ClusterRoleBinding) models.K8sClusterRoleBinding { return models.K8sClusterRoleBinding{ Name: clusterRoleBinding.Name, + UID: clusterRoleBinding.UID, RoleRef: clusterRoleBinding.RoleRef, Subjects: clusterRoleBinding.Subjects, CreationDate: clusterRoleBinding.CreationTimestamp.Time, + IsSystem: isSystemClusterRoleBinding(&clusterRoleBinding), } } + +func isSystemClusterRoleBinding(binding *rbacv1.ClusterRoleBinding) bool { + if strings.HasPrefix(binding.Name, "system:") { + return true + } + + if binding.Labels != nil { + if binding.Labels["kubernetes.io/bootstrapping"] == "rbac-defaults" { + return true + } + } + + for _, sub := range binding.Subjects { + if strings.HasPrefix(sub.Name, "system:") { + return true + } + + if sub.Namespace == "kube-system" || + sub.Namespace == "kube-public" || + sub.Namespace == "kube-node-lease" || + sub.Namespace == "portainer" { + return true + } + } + + return false +} diff --git a/app/react/kubernetes/more-resources/ClusterRolesView/ClusterRoleBindingsDatatable/types.ts b/app/react/kubernetes/more-resources/ClusterRolesView/ClusterRoleBindingsDatatable/types.ts index dcc4ff107..e56bfac36 100644 --- a/app/react/kubernetes/more-resources/ClusterRolesView/ClusterRoleBindingsDatatable/types.ts +++ b/app/react/kubernetes/more-resources/ClusterRolesView/ClusterRoleBindingsDatatable/types.ts @@ -14,13 +14,8 @@ export type ClusterRoleSubject = { export type ClusterRoleBinding = { name: string; uid: string; - namespace: string; - resourceVersion: string; - creationDate: string; - annotations: Record | null; - roleRef: ClusterRoleRef; subjects: ClusterRoleSubject[] | null; - + creationDate: string; isSystem: boolean; };