diff --git a/internal/dao/cronjob.go b/internal/dao/cronjob.go index 9d84e09a..867d1cbc 100644 --- a/internal/dao/cronjob.go +++ b/internal/dao/cronjob.go @@ -179,6 +179,14 @@ func (c *CronJob) Scan(ctx context.Context, gvr, fqn string, wait bool) (Refs, e GVR: c.GVR(), FQN: client.FQN(cj.Namespace, cj.Name), }) + case "scheduling.k8s.io/v1/priorityclasses": + if !hasPC(&cj.Spec.JobTemplate.Spec.Template.Spec, n) { + continue + } + refs = append(refs, Ref{ + GVR: c.GVR(), + FQN: client.FQN(cj.Namespace, cj.Name), + }) } } diff --git a/internal/dao/dp.go b/internal/dao/dp.go index 106a5851..f59be35a 100644 --- a/internal/dao/dp.go +++ b/internal/dao/dp.go @@ -223,7 +223,16 @@ func (d *Deployment) Scan(ctx context.Context, gvr, fqn string, wait bool) (Refs GVR: d.GVR(), FQN: client.FQN(dp.Namespace, dp.Name), }) + case "scheduling.k8s.io/v1/priorityclasses": + if !hasPC(&dp.Spec.Template.Spec, n) { + continue + } + refs = append(refs, Ref{ + GVR: d.GVR(), + FQN: client.FQN(dp.Namespace, dp.Name), + }) } + } return refs, nil @@ -276,6 +285,10 @@ func hasPVC(spec *v1.PodSpec, name string) bool { return false } +func hasPC(spec *v1.PodSpec, name string) bool { + return spec.PriorityClassName == name +} + func hasConfigMap(spec *v1.PodSpec, name string) bool { for _, c := range spec.InitContainers { if containerHasConfigMap(c, name) { diff --git a/internal/dao/ds.go b/internal/dao/ds.go index 90757fe2..e1b04633 100644 --- a/internal/dao/ds.go +++ b/internal/dao/ds.go @@ -243,6 +243,14 @@ func (d *DaemonSet) Scan(ctx context.Context, gvr, fqn string, wait bool) (Refs, GVR: d.GVR(), FQN: client.FQN(ds.Namespace, ds.Name), }) + case "scheduling.k8s.io/v1/priorityclasses": + if !hasPC(&ds.Spec.Template.Spec, n) { + continue + } + refs = append(refs, Ref{ + GVR: d.GVR(), + FQN: client.FQN(ds.Namespace, ds.Name), + }) } } diff --git a/internal/dao/job.go b/internal/dao/job.go index 09a8c2a8..dfc35c8e 100644 --- a/internal/dao/job.go +++ b/internal/dao/job.go @@ -139,6 +139,14 @@ func (j *Job) Scan(ctx context.Context, gvr, fqn string, wait bool) (Refs, error GVR: j.GVR(), FQN: client.FQN(job.Namespace, job.Name), }) + case "scheduling.k8s.io/v1/priorityclasses": + if !hasPC(&job.Spec.Template.Spec, n) { + continue + } + refs = append(refs, Ref{ + GVR: j.GVR(), + FQN: client.FQN(job.Namespace, job.Name), + }) } } diff --git a/internal/dao/pod.go b/internal/dao/pod.go index 2237383c..4e5658b6 100644 --- a/internal/dao/pod.go +++ b/internal/dao/pod.go @@ -302,6 +302,14 @@ func (p *Pod) Scan(ctx context.Context, gvr, fqn string, wait bool) (Refs, error GVR: p.GVR(), FQN: client.FQN(pod.Namespace, pod.Name), }) + case "scheduling.k8s.io/v1/priorityclasses": + if !hasPC(&pod.Spec, n) { + continue + } + refs = append(refs, Ref{ + GVR: p.GVR(), + FQN: client.FQN(pod.Namespace, pod.Name), + }) } } diff --git a/internal/dao/sts.go b/internal/dao/sts.go index 958ab9c3..d51e7de3 100644 --- a/internal/dao/sts.go +++ b/internal/dao/sts.go @@ -249,6 +249,15 @@ func (s *StatefulSet) Scan(ctx context.Context, gvr, fqn string, wait bool) (Ref GVR: s.GVR(), FQN: client.FQN(sts.Namespace, sts.Name), }) + case "scheduling.k8s.io/v1/priorityclasses": + if !hasPC(&sts.Spec.Template.Spec, n) { + continue + } + refs = append(refs, Ref{ + GVR: s.GVR(), + FQN: client.FQN(sts.Namespace, sts.Name), + }) + } } diff --git a/internal/view/priorityclass.go b/internal/view/priorityclass.go new file mode 100644 index 00000000..611ed0d5 --- /dev/null +++ b/internal/view/priorityclass.go @@ -0,0 +1,32 @@ +package view + +import ( + "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/ui" + "github.com/gdamore/tcell/v2" +) + +// PriorityClass presents a priority class viewer. +type PriorityClass struct { + ResourceViewer +} + +// NewPriorityClass returns a new viewer. +func NewPriorityClass(gvr client.GVR) ResourceViewer { + s := PriorityClass{ + ResourceViewer: NewBrowser(gvr), + } + s.AddBindKeysFn(s.bindKeys) + + return &s +} + +func (s *PriorityClass) bindKeys(aa ui.KeyActions) { + aa.Add(ui.KeyActions{ + ui.KeyU: ui.NewKeyAction("UsedBy", s.refCmd, true), + }) +} + +func (s *PriorityClass) refCmd(evt *tcell.EventKey) *tcell.EventKey { + return scanRefs(evt, s.App(), s.GetTable(), "scheduling.k8s.io/v1/priorityclasses") +} diff --git a/internal/view/priorityclass_test.go b/internal/view/priorityclass_test.go new file mode 100644 index 00000000..1c258fb9 --- /dev/null +++ b/internal/view/priorityclass_test.go @@ -0,0 +1,17 @@ +package view_test + +import ( + "testing" + + "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/view" + "github.com/stretchr/testify/assert" +) + +func TestPriorityClassNew(t *testing.T) { + s := view.NewPriorityClass(client.NewGVR("scheduling.k8s.io/v1/priorityclasses")) + + assert.Nil(t, s.Init(makeCtx())) + assert.Equal(t, "PriorityClass", s.Name()) + assert.Equal(t, 6, len(s.Hints())) +} diff --git a/internal/view/registrar.go b/internal/view/registrar.go index e35f32cf..62e6f40b 100644 --- a/internal/view/registrar.go +++ b/internal/view/registrar.go @@ -45,6 +45,9 @@ func coreViewers(vv MetaViewers) { vv[client.NewGVR("v1/secrets")] = MetaViewer{ viewerFn: NewSecret, } + vv[client.NewGVR("scheduling.k8s.io/v1/priorityclasses")] = MetaViewer{ + viewerFn: NewPriorityClass, + } vv[client.NewGVR("v1/configmaps")] = MetaViewer{ viewerFn: NewConfigMap, } diff --git a/internal/view/svc_test.go b/internal/view/svc_test.go index 32fd6a2c..fef2e960 100644 --- a/internal/view/svc_test.go +++ b/internal/view/svc_test.go @@ -49,6 +49,14 @@ func init() { Verbs: []string{"get", "list", "watch", "delete"}, Categories: []string{"k9s"}, }) + dao.MetaAccess.RegisterMeta("scheduling.k8s.io/v1/priorityclasses", metav1.APIResource{ + Name: "priorityclasses", + SingularName: "priorityclass", + Namespaced: false, + Kind: "PriorityClass", + Verbs: []string{"get", "list", "watch", "delete"}, + Categories: []string{"k9s"}, + }) dao.MetaAccess.RegisterMeta("v1/configmaps", metav1.APIResource{ Name: "configmaps", SingularName: "configmap",