...
1
16
17 package printers
18
19 import (
20 "bytes"
21 "encoding/json"
22 "fmt"
23 "io"
24 "reflect"
25
26 "k8s.io/apimachinery/pkg/runtime"
27 "k8s.io/client-go/util/jsonpath"
28 )
29
30
31
32
33
34
35
36
37
38 func exists(item interface{}, indices ...interface{}) bool {
39 v := reflect.ValueOf(item)
40 for _, i := range indices {
41 index := reflect.ValueOf(i)
42 var isNil bool
43 if v, isNil = indirect(v); isNil {
44 return false
45 }
46 switch v.Kind() {
47 case reflect.Array, reflect.Slice, reflect.String:
48 var x int64
49 switch index.Kind() {
50 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
51 x = index.Int()
52 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
53 x = int64(index.Uint())
54 default:
55 return false
56 }
57 if x < 0 || x >= int64(v.Len()) {
58 return false
59 }
60 v = v.Index(int(x))
61 case reflect.Map:
62 if !index.IsValid() {
63 index = reflect.Zero(v.Type().Key())
64 }
65 if !index.Type().AssignableTo(v.Type().Key()) {
66 return false
67 }
68 if x := v.MapIndex(index); x.IsValid() {
69 v = x
70 } else {
71 v = reflect.Zero(v.Type().Elem())
72 }
73 default:
74 return false
75 }
76 }
77 if _, isNil := indirect(v); isNil {
78 return false
79 }
80 return true
81 }
82
83
84
85
86
87 func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
88 for ; v.Kind() == reflect.Pointer || v.Kind() == reflect.Interface; v = v.Elem() {
89 if v.IsNil() {
90 return v, true
91 }
92 if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
93 break
94 }
95 }
96 return v, false
97 }
98
99
100 type JSONPathPrinter struct {
101 rawTemplate string
102 *jsonpath.JSONPath
103 }
104
105 func NewJSONPathPrinter(tmpl string) (*JSONPathPrinter, error) {
106 j := jsonpath.New("out")
107 if err := j.Parse(tmpl); err != nil {
108 return nil, err
109 }
110 return &JSONPathPrinter{
111 rawTemplate: tmpl,
112 JSONPath: j,
113 }, nil
114 }
115
116
117 func (j *JSONPathPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
118
119
120
121 if InternalObjectPreventer.IsForbidden(reflect.Indirect(reflect.ValueOf(obj)).Type().PkgPath()) {
122 return fmt.Errorf(InternalObjectPrinterErr)
123 }
124
125 var queryObj interface{} = obj
126 if unstructured, ok := obj.(runtime.Unstructured); ok {
127 queryObj = unstructured.UnstructuredContent()
128 } else {
129 data, err := json.Marshal(obj)
130 if err != nil {
131 return err
132 }
133 queryObj = map[string]interface{}{}
134 if err := json.Unmarshal(data, &queryObj); err != nil {
135 return err
136 }
137 }
138
139 if err := j.JSONPath.Execute(w, queryObj); err != nil {
140 buf := bytes.NewBuffer(nil)
141 fmt.Fprintf(buf, "Error executing template: %v. Printing more information for debugging the template:\n", err)
142 fmt.Fprintf(buf, "\ttemplate was:\n\t\t%v\n", j.rawTemplate)
143 fmt.Fprintf(buf, "\tobject given to jsonpath engine was:\n\t\t%#v\n\n", queryObj)
144 return fmt.Errorf("error executing jsonpath %q: %v\n", j.rawTemplate, buf.String())
145 }
146 return nil
147 }
148
View as plain text