...
1
16
17 package fieldpath
18
19 import (
20 "fmt"
21 "strings"
22
23 "k8s.io/apimachinery/pkg/api/meta"
24 "k8s.io/apimachinery/pkg/util/sets"
25 "k8s.io/apimachinery/pkg/util/validation"
26 )
27
28
29
30
31 func FormatMap(m map[string]string) (fmtStr string) {
32
33 keys := sets.NewString()
34 for key := range m {
35 keys.Insert(key)
36 }
37 for _, key := range keys.List() {
38 fmtStr += fmt.Sprintf("%v=%q\n", key, m[key])
39 }
40 fmtStr = strings.TrimSuffix(fmtStr, "\n")
41
42 return
43 }
44
45
46
47
48 func ExtractFieldPathAsString(obj interface{}, fieldPath string) (string, error) {
49 accessor, err := meta.Accessor(obj)
50 if err != nil {
51 return "", nil
52 }
53
54 if path, subscript, ok := SplitMaybeSubscriptedPath(fieldPath); ok {
55 switch path {
56 case "metadata.annotations":
57 if errs := validation.IsQualifiedName(strings.ToLower(subscript)); len(errs) != 0 {
58 return "", fmt.Errorf("invalid key subscript in %s: %s", fieldPath, strings.Join(errs, ";"))
59 }
60 return accessor.GetAnnotations()[subscript], nil
61 case "metadata.labels":
62 if errs := validation.IsQualifiedName(subscript); len(errs) != 0 {
63 return "", fmt.Errorf("invalid key subscript in %s: %s", fieldPath, strings.Join(errs, ";"))
64 }
65 return accessor.GetLabels()[subscript], nil
66 default:
67 return "", fmt.Errorf("fieldPath %q does not support subscript", fieldPath)
68 }
69 }
70
71 switch fieldPath {
72 case "metadata.annotations":
73 return FormatMap(accessor.GetAnnotations()), nil
74 case "metadata.labels":
75 return FormatMap(accessor.GetLabels()), nil
76 case "metadata.name":
77 return accessor.GetName(), nil
78 case "metadata.namespace":
79 return accessor.GetNamespace(), nil
80 case "metadata.uid":
81 return string(accessor.GetUID()), nil
82 }
83
84 return "", fmt.Errorf("unsupported fieldPath: %v", fieldPath)
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98
99 func SplitMaybeSubscriptedPath(fieldPath string) (string, string, bool) {
100 if !strings.HasSuffix(fieldPath, "']") {
101 return fieldPath, "", false
102 }
103 s := strings.TrimSuffix(fieldPath, "']")
104 parts := strings.SplitN(s, "['", 2)
105 if len(parts) < 2 {
106 return fieldPath, "", false
107 }
108 if len(parts[0]) == 0 {
109 return fieldPath, "", false
110 }
111 return parts[0], parts[1], true
112 }
113
View as plain text