k9s/internal/render/rbac.go

146 lines
2.5 KiB
Go

package render
import (
"fmt"
"strings"
"github.com/gdamore/tcell"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
const allVerbs = "*"
var (
k8sVerbs = []string{
"get",
"list",
"watch",
"create",
"patch",
"update",
"delete",
"deletecollection",
}
httpTok8sVerbs = map[string]string{
"post": "create",
"put": "update",
}
)
// Rbac renders a rbac to screen.
type Rbac struct{}
// ColorerFunc colors a resource row.
func (Rbac) ColorerFunc() ColorerFunc {
return func(ns string, re RowEvent) tcell.Color {
return tcell.ColorMediumSpringGreen
}
}
// Header returns a header row.
func (Rbac) Header(ns string) HeaderRow {
h := HeaderRow{
Header{Name: "NAME"},
Header{Name: "API GROUP"},
}
return append(h, rbacVerbHeader()...)
}
// Render renders a K8s resource to screen.
func (Rbac) Render(o interface{}, gvr string, r *Row) error {
p, ok := o.(*PolicyRes)
if !ok {
return fmt.Errorf("expecting policyres in renderer for %q", gvr)
}
if p.Group != "" {
p.Group = toGroup(p.Group)
} else {
p.Group = "core"
}
r.Fields = append(r.Fields, p.Resource, p.Group)
r.Fields = append(r.Fields, asVerbs(p.Verbs)...)
r.ID = p.Resource
return nil
}
// Helpers...
func asVerbs(verbs []string) []string {
const (
verbLen = 4
unknownLen = 30
)
r := make([]string, 0, len(k8sVerbs)+1)
for _, v := range k8sVerbs {
r = append(r, toVerbIcon(hasVerb(verbs, v)))
}
var unknowns []string
for _, v := range verbs {
if hv, ok := httpTok8sVerbs[v]; ok {
v = hv
}
if !hasVerb(k8sVerbs, v) && v != allVerbs {
unknowns = append(unknowns, v)
}
}
return append(r, Truncate(strings.Join(unknowns, ","), unknownLen))
}
func toVerbIcon(ok bool) string {
if ok {
return "[green::b] ✓ [::]"
}
return "[orangered::b] 𐄂 [::]"
}
func hasVerb(verbs []string, verb string) bool {
if len(verbs) == 1 && verbs[0] == allVerbs {
return true
}
for _, v := range verbs {
if hv, ok := httpTok8sVerbs[v]; ok {
if hv == verb {
return true
}
}
if v == verb {
return true
}
}
return false
}
func toGroup(g string) string {
if g == "" {
return "v1"
}
return g
}
type PolicyRes struct {
Resource, Group string
ResourceName string
NonResourceURL string
Verbs []string
}
// GetObjectKind returns a schema object.
func (p PolicyRes) GetObjectKind() schema.ObjectKind {
return nil
}
// DeepCopyObject returns a container copy.
func (p PolicyRes) DeepCopyObject() runtime.Object {
return p
}