diff --git a/internal/render/helpers.go b/internal/render/helpers.go index 422c6d8f57..95ed2cf6ef 100644 --- a/internal/render/helpers.go +++ b/internal/render/helpers.go @@ -304,6 +304,13 @@ func boolPtrToStr(b *bool) string { return boolToStr(*b) } +func strPtrToStr(s *string) string { + if s == nil { + return "" + } + return *s +} + // Check if string is in a string list. func in(ll []string, s string) bool { for _, l := range ll { diff --git a/internal/render/sc.go b/internal/render/sc.go index dc6de66c7c..a2995eab7e 100644 --- a/internal/render/sc.go +++ b/internal/render/sc.go @@ -5,8 +5,10 @@ import ( "github.com/derailed/k9s/internal/client" storagev1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/kubectl/pkg/util/storage" ) // StorageClass renders a K8s StorageClass to screen. @@ -19,6 +21,9 @@ func (StorageClass) Header(ns string) Header { return Header{ HeaderColumn{Name: "NAME"}, HeaderColumn{Name: "PROVISIONER"}, + HeaderColumn{Name: "RECLAIMPOLICY"}, + HeaderColumn{Name: "VOLUMEBINDINGMODE"}, + HeaderColumn{Name: "ALLOWVOLUMEEXPANSION"}, HeaderColumn{Name: "LABELS", Wide: true}, HeaderColumn{Name: "VALID", Wide: true}, HeaderColumn{Name: "AGE", Time: true}, @@ -26,7 +31,7 @@ func (StorageClass) Header(ns string) Header { } // Render renders a K8s resource to screen. -func (StorageClass) Render(o interface{}, ns string, r *Row) error { +func (s StorageClass) Render(o interface{}, ns string, r *Row) error { raw, ok := o.(*unstructured.Unstructured) if !ok { return fmt.Errorf("Expected StorageClass, but got %T", o) @@ -39,8 +44,11 @@ func (StorageClass) Render(o interface{}, ns string, r *Row) error { r.ID = client.FQN(client.ClusterScope, sc.ObjectMeta.Name) r.Fields = Fields{ - sc.Name, - string(sc.Provisioner), + s.nameWithDefault(sc.ObjectMeta), + sc.Provisioner, + strPtrToStr((*string)(sc.ReclaimPolicy)), + strPtrToStr((*string)(sc.VolumeBindingMode)), + boolPtrToStr(sc.AllowVolumeExpansion), mapToStr(sc.Labels), "", toAge(sc.GetCreationTimestamp()), @@ -48,3 +56,10 @@ func (StorageClass) Render(o interface{}, ns string, r *Row) error { return nil } + +func (StorageClass) nameWithDefault(meta metav1.ObjectMeta) string { + if storage.IsDefaultAnnotationText(meta) == "Yes" { + return meta.Name + " (default)" + } + return meta.Name +} diff --git a/internal/render/sc_test.go b/internal/render/sc_test.go index 80e13393d0..60cd56f242 100644 --- a/internal/render/sc_test.go +++ b/internal/render/sc_test.go @@ -13,5 +13,5 @@ func TestStorageClassRender(t *testing.T) { assert.NoError(t, c.Render(load(t, "sc"), "", &r)) assert.Equal(t, "-/standard", r.ID) - assert.Equal(t, render.Fields{"standard", "kubernetes.io/gce-pd"}, r.Fields[:2]) + assert.Equal(t, render.Fields{"standard (default)", "kubernetes.io/gce-pd", "Delete", "Immediate", "true"}, r.Fields[:5]) } diff --git a/internal/render/testdata/sc.json b/internal/render/testdata/sc.json index afd1d892c3..c8ad58efe6 100644 --- a/internal/render/testdata/sc.json +++ b/internal/render/testdata/sc.json @@ -20,5 +20,6 @@ }, "provisioner": "kubernetes.io/gce-pd", "reclaimPolicy": "Delete", - "volumeBindingMode": "Immediate" + "volumeBindingMode": "Immediate", + "allowVolumeExpansion": true } \ No newline at end of file