Merge pull request #65074 from wgliang/master.describe-pv

Automatic merge from submit-queue (batch tested with PRs 65074, 67469). If you want to cherry-pick this change to another branch, please follow the instructions here: https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md.

Add CSI volume attributes for kubectl describe pv

**What this PR does / why we need it**:
/king feature

kubectl describe pv doesn't show the volume attributes.

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #65021

**Special notes for your reviewer**:
/cc @saad-ali 

**Release note**:

```release-note
Add CSI volume attributes for kubectl describe pv.
```
pull/8/head
Kubernetes Submit Queue 2018-09-04 08:03:35 -07:00 committed by GitHub
commit 789c361eb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 118 additions and 2 deletions

View File

@ -1129,6 +1129,48 @@ func printCSIPersistentVolumeSource(csi *api.CSIPersistentVolumeSource, w Prefix
" VolumeHandle:\t%v\n"+
" ReadOnly:\t%v\n",
csi.Driver, csi.VolumeHandle, csi.ReadOnly)
printCSIPersistentVolumeAttributesMultiline(w, "VolumeAttributes", csi.VolumeAttributes)
}
func printCSIPersistentVolumeAttributesMultiline(w PrefixWriter, title string, annotations map[string]string) {
printCSIPersistentVolumeAttributesMultilineIndent(w, "", title, "\t", annotations, sets.NewString())
}
func printCSIPersistentVolumeAttributesMultilineIndent(w PrefixWriter, initialIndent, title, innerIndent string, attributes map[string]string, skip sets.String) {
w.Write(LEVEL_2, "%s%s:%s", initialIndent, title, innerIndent)
if len(attributes) == 0 {
w.WriteLine("<none>")
return
}
// to print labels in the sorted order
keys := make([]string, 0, len(attributes))
for key := range attributes {
if skip.Has(key) {
continue
}
keys = append(keys, key)
}
if len(attributes) == 0 {
w.WriteLine("<none>")
return
}
sort.Strings(keys)
for i, key := range keys {
if i != 0 {
w.Write(LEVEL_2, initialIndent)
w.Write(LEVEL_2, innerIndent)
}
line := fmt.Sprintf("%s=%s", key, attributes[key])
if len(line) > maxAnnotationLen {
w.Write(LEVEL_2, "%s...\n", line[:maxAnnotationLen])
} else {
w.Write(LEVEL_2, "%s\n", line)
}
i++
}
}
type PersistentVolumeDescriber struct {
@ -1197,8 +1239,8 @@ func describePersistentVolume(pv *api.PersistentVolume, events *api.EventList) (
return tabbedString(func(out io.Writer) error {
w := NewPrefixWriter(out)
w.Write(LEVEL_0, "Name:\t%s\n", pv.Name)
printLabelsMultiline(w, "Labels", pv.Labels)
printAnnotationsMultiline(w, "Annotations", pv.Annotations)
printLabelsMultiline(w, "Labels", pv.ObjectMeta.Labels)
printAnnotationsMultiline(w, "Annotations", pv.ObjectMeta.Annotations)
w.Write(LEVEL_0, "Finalizers:\t%v\n", pv.ObjectMeta.Finalizers)
w.Write(LEVEL_0, "StorageClass:\t%s\n", helper.GetPersistentVolumeClass(pv))
if pv.ObjectMeta.DeletionTimestamp != nil {

View File

@ -1163,6 +1163,80 @@ func TestPersistentVolumeDescriber(t *testing.T) {
},
expectedElements: []string{"Terminating (lasts 10y)"},
},
{
name: "test16",
plugin: "local",
pv: &api.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
GenerateName: "test-GenerateName",
UID: "test-UID",
CreationTimestamp: metav1.Time{Time: time.Now()},
DeletionTimestamp: &metav1.Time{Time: time.Now()},
DeletionGracePeriodSeconds: new(int64),
Labels: map[string]string{"label1": "label1", "label2": "label2", "label3": "label3"},
Annotations: map[string]string{"annotation1": "annotation1", "annotation2": "annotation2", "annotation3": "annotation3"},
},
Spec: api.PersistentVolumeSpec{
PersistentVolumeSource: api.PersistentVolumeSource{
Local: &api.LocalVolumeSource{},
},
NodeAffinity: &api.VolumeNodeAffinity{
Required: &api.NodeSelector{
NodeSelectorTerms: []api.NodeSelectorTerm{
{
MatchExpressions: []api.NodeSelectorRequirement{
{
Key: "foo",
Operator: "In",
Values: []string{"val1", "val2"},
},
{
Key: "foo",
Operator: "Exists",
},
},
},
},
},
},
},
},
expectedElements: []string{"Node Affinity", "Required Terms", "Term 0",
"foo in [val1, val2]",
"foo exists"},
},
{
name: "test17",
plugin: "local",
pv: &api.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
GenerateName: "test-GenerateName",
UID: "test-UID",
CreationTimestamp: metav1.Time{Time: time.Now()},
DeletionTimestamp: &metav1.Time{Time: time.Now()},
DeletionGracePeriodSeconds: new(int64),
Labels: map[string]string{"label1": "label1", "label2": "label2", "label3": "label3"},
Annotations: map[string]string{"annotation1": "annotation1", "annotation2": "annotation2", "annotation3": "annotation3"},
},
Spec: api.PersistentVolumeSpec{
PersistentVolumeSource: api.PersistentVolumeSource{
CSI: &api.CSIPersistentVolumeSource{
Driver: "drive",
VolumeHandle: "handler",
ReadOnly: true,
VolumeAttributes: map[string]string{
"Attribute1": "Value1",
"Attribute2": "Value2",
"Attribute3": "Value3",
},
},
},
},
},
expectedElements: []string{"Driver", "VolumeHandle", "ReadOnly", "VolumeAttributes"},
},
}
for _, test := range testCases {