...
1
16
17 package printers
18
19 import (
20 "encoding/base64"
21 "fmt"
22 "io"
23 "reflect"
24 "text/template"
25
26 "k8s.io/apimachinery/pkg/runtime"
27 "k8s.io/apimachinery/pkg/util/json"
28 )
29
30
31 type GoTemplatePrinter struct {
32 rawTemplate string
33 template *template.Template
34 }
35
36 func NewGoTemplatePrinter(tmpl []byte) (*GoTemplatePrinter, error) {
37 t, err := template.New("output").
38 Funcs(template.FuncMap{
39 "exists": exists,
40 "base64decode": base64decode,
41 }).
42 Parse(string(tmpl))
43 if err != nil {
44 return nil, err
45 }
46 return &GoTemplatePrinter{
47 rawTemplate: string(tmpl),
48 template: t,
49 }, nil
50 }
51
52
53 func (p *GoTemplatePrinter) AllowMissingKeys(allow bool) {
54 if allow {
55 p.template.Option("missingkey=default")
56 } else {
57 p.template.Option("missingkey=error")
58 }
59 }
60
61
62 func (p *GoTemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
63 if InternalObjectPreventer.IsForbidden(reflect.Indirect(reflect.ValueOf(obj)).Type().PkgPath()) {
64 return fmt.Errorf(InternalObjectPrinterErr)
65 }
66
67 var data []byte
68 var err error
69 data, err = json.Marshal(obj)
70 if err != nil {
71 return err
72 }
73
74 out := map[string]interface{}{}
75 if err := json.Unmarshal(data, &out); err != nil {
76 return err
77 }
78 if err = p.safeExecute(w, out); err != nil {
79
80
81
82 fmt.Fprintf(w, "Error executing template: %v. Printing more information for debugging the template:\n", err)
83 fmt.Fprintf(w, "\ttemplate was:\n\t\t%v\n", p.rawTemplate)
84 fmt.Fprintf(w, "\traw data was:\n\t\t%v\n", string(data))
85 fmt.Fprintf(w, "\tobject given to template engine was:\n\t\t%+v\n\n", out)
86 return fmt.Errorf("error executing template %q: %v", p.rawTemplate, err)
87 }
88 return nil
89 }
90
91
92
93 func (p *GoTemplatePrinter) safeExecute(w io.Writer, obj interface{}) error {
94 var panicErr error
95
96
97
98 retErr := func() error {
99 defer func() {
100 if x := recover(); x != nil {
101 panicErr = fmt.Errorf("caught panic: %+v", x)
102 }
103 }()
104 return p.template.Execute(w, obj)
105 }()
106 if panicErr != nil {
107 return panicErr
108 }
109 return retErr
110 }
111
112 func base64decode(v string) (string, error) {
113 data, err := base64.StdEncoding.DecodeString(v)
114 if err != nil {
115 return "", fmt.Errorf("base64 decode failed: %v", err)
116 }
117 return string(data), nil
118 }
119
View as plain text