k9s/internal/model/rbac.go

155 lines
4.1 KiB
Go

package model
import (
"context"
"fmt"
"github.com/derailed/k9s/internal"
"github.com/derailed/k9s/internal/client"
"github.com/derailed/k9s/internal/render"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
)
const (
crbGVR = "rbac.authorization.k8s.io/v1/clusterrolebindings"
crGVR = "rbac.authorization.k8s.io/v1/clusterroles"
rbGVR = "rbac.authorization.k8s.io/v1/rolebindings"
rGVR = "rbac.authorization.k8s.io/v1/roles"
)
// Rbac represents a model for listing rbac resources.
type Rbac struct {
Resource
}
// List lists out rbac resources.
func (r *Rbac) List(ctx context.Context) ([]runtime.Object, error) {
gvr, ok := ctx.Value(internal.KeyGVR).(string)
if !ok {
return nil, fmt.Errorf("expecting a context gvr")
}
r.gvr = gvr
path, ok := ctx.Value(internal.KeyPath).(string)
if !ok || path == "" {
return r.Resource.List(ctx)
}
switch client.GVR(r.gvr).ToR() {
case "clusterrolebindings":
return r.loadClusterRoleBinding(path)
case "rolebindings":
return r.loadRoleBinding(path)
case "clusterroles":
return r.loadClusterRole(path)
case "roles":
return r.loadRole(path)
default:
return nil, fmt.Errorf("expecting clusterrole/role but found %s", client.GVR(r.gvr).ToR())
}
}
// BOZO!!Refact gvr as const
func (r *Rbac) loadClusterRoleBinding(path string) ([]runtime.Object, error) {
o, err := r.factory.Get(crbGVR, path, labels.Everything())
if err != nil {
return nil, err
}
var crb rbacv1.ClusterRoleBinding
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &crb)
if err != nil {
return nil, err
}
crbo, err := r.factory.Get(crGVR, client.FQN("-", crb.RoleRef.Name), labels.Everything())
if err != nil {
return nil, err
}
var cr rbacv1.ClusterRole
err = runtime.DefaultUnstructuredConverter.FromUnstructured(crbo.(*unstructured.Unstructured).Object, &cr)
if err != nil {
return nil, err
}
return asRuntimeObjects(parseRules(render.ClusterScope, "-", cr.Rules)), nil
}
func (r *Rbac) loadRoleBinding(path string) ([]runtime.Object, error) {
o, err := r.factory.Get(rbGVR, path, labels.Everything())
if err != nil {
return nil, err
}
var rb rbacv1.RoleBinding
if err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &rb); err != nil {
return nil, err
}
if rb.RoleRef.Kind == "ClusterRole" {
o, e := r.factory.Get(crGVR, client.FQN("-", rb.RoleRef.Name), labels.Everything())
if e != nil {
return nil, e
}
var cr rbacv1.ClusterRole
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &cr)
if err != nil {
return nil, err
}
return asRuntimeObjects(parseRules(render.ClusterScope, "-", cr.Rules)), nil
}
ro, err := r.factory.Get(rGVR, client.FQN(rb.Namespace, rb.RoleRef.Name), labels.Everything())
if err != nil {
return nil, err
}
var role rbacv1.Role
err = runtime.DefaultUnstructuredConverter.FromUnstructured(ro.(*unstructured.Unstructured).Object, &role)
if err != nil {
return nil, err
}
return asRuntimeObjects(parseRules(render.ClusterScope, "-", role.Rules)), nil
}
func (r *Rbac) loadClusterRole(path string) ([]runtime.Object, error) {
o, err := r.factory.Get(crGVR, path, labels.Everything())
if err != nil {
return nil, err
}
var cr rbacv1.ClusterRole
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &cr)
if err != nil {
return nil, err
}
return asRuntimeObjects(parseRules(render.ClusterScope, "-", cr.Rules)), nil
}
func (r *Rbac) loadRole(path string) ([]runtime.Object, error) {
o, err := r.factory.Get(rGVR, path, labels.Everything())
if err != nil {
return nil, err
}
var ro rbacv1.Role
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &ro)
if err != nil {
return nil, err
}
return asRuntimeObjects(parseRules(render.ClusterScope, "-", ro.Rules)), nil
}
func asRuntimeObjects(rr render.Policies) []runtime.Object {
oo := make([]runtime.Object, len(rr))
for i, r := range rr {
oo[i] = r
}
return oo
}