Change:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . --Is this a BUG REPORT or FEATURE REQUEST?: /assign What happened: Now that it's a field, it needs a separate entry in 'kubectl describe'

Discussion:
return describePersistentVolume(pv, events) } <ins> func printVolumeNodeAffinity(w PrefixWriter, affinity *api.VolumeNodeAffinity) { w.Write(LEVEL_0, "Node Affinity:t") if affinity == nil || affinity.Required == nil { w.WriteLine("<none>") return } w.WriteLine("") if affinity.Required != nil { w.Write(LEVEL_1, "Required Terms:t") if len(affinity.Required.NodeSelectorTerms) == 0 { w.WriteLine("<none>") } else { w.WriteLine("") for i, term := range affinity.Required.NodeSelectorTerms { printNodeSelectorTermsMultilineWithIndent(w, LEVEL_2, fmt.Sprintf("Term %v", i), "t", term.MatchExpressions) } } } } // printLabelsMultiline prints multiple labels with a user-defined alignment. func printNodeSelectorTermsMultilineWithIndent(w PrefixWriter, indentLevel int, title, innerIndent string, reqs []api.NodeSelectorRequirement) { w.Write(indentLevel, "%s:%s", title, innerIndent) if len(reqs) == 0 { w.WriteLine("<none>") return } for i, req := range reqs { if i != 0 { w.Write(indentLevel, "%s", innerIndent) } exprStr := fmt.Sprintf("%s %s", req.Key, strings.ToLower(string(req.Operator))) if len(req.Values) > 0 { exprStr = fmt.Sprintf("%s [%s]", exprStr, strings.Join(req.Values, ", ")) } w.Write(LEVEL_0, "%sn", exprStr) } } </ins> func describePersistentVolume(pv *api.PersistentVolume, events *api.EventList) (string, error) { return tabbedString(func(out io.Writer) error { w := NewPrefixWriter(out)

} storage := pv.Spec.Capacity[api.ResourceStorage] w.Write(LEVEL_0, "Capacity:t%sn", storage.String()) <ins> printVolumeNodeAffinity(w, pv.Spec.NodeAffinity) </ins> w.Write(LEVEL_0, "Message:t%sn", pv.Status.Message) w.Write(LEVEL_0, "Source:n")

}, expectedElements: []string{"VolumeMode", "Block"}, }, <ins> { plugin: "local", pv: &api.PersistentVolume{ ObjectMeta: metav1.ObjectMeta{Name: "bar"}, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{ Local: &api.LocalVolumeSource{}, }, }, }, expectedElements:   []string{"Node Affinity:   <none>"}, unexpectedElements: []string{"Required Terms", "Term "}, }, { plugin: "local", pv: &api.PersistentVolume{ ObjectMeta: metav1.ObjectMeta{Name: "bar"}, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{ Local: &api.LocalVolumeSource{}, }, NodeAffinity: &api.VolumeNodeAffinity{}, }, }, expectedElements:   []string{"Node Affinity:   <none>"}, unexpectedElements: []string{"Required Terms", "Term "}, }, { plugin: "local", pv: &api.PersistentVolume{ ObjectMeta: metav1.ObjectMeta{Name: "bar"}, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{ Local: &api.LocalVolumeSource{}, }, NodeAffinity: &api.VolumeNodeAffinity{ Required: &api.NodeSelector{}, }, }, }, expectedElements:   []string{"Node Affinity", "Required Terms:  <none>"}, unexpectedElements: []string{"Term "}, }, { plugin: "local", pv: &api.PersistentVolume{ ObjectMeta: metav1.ObjectMeta{Name: "bar"}, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{ Local: &api.LocalVolumeSource{}, }, NodeAffinity: &api.VolumeNodeAffinity{ Required: &api.NodeSelector{ NodeSelectorTerms: []api.NodeSelectorTerm{ { MatchExpressions: []api.NodeSelectorRequirement{}, }, { MatchExpressions: []api.NodeSelectorRequirement{}, }, }, }, }, }, }, expectedElements: []string{"Node Affinity", "Required Terms", "Term 0", "Term 1"}, }, { plugin: "local", pv: &api.PersistentVolume{ ObjectMeta: metav1.ObjectMeta{Name: "bar"}, 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"}, }, </ins> } for _, test := range testCases {