From 9bb0d33a3f3e53cfc3516aa715eb48e3f1efd1e2 Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Fri, 7 Nov 2014 14:41:59 -0800 Subject: [PATCH] Fix kubectl -template to be versioned --- pkg/kubectl/resource_printer.go | 49 ++++++++++++++++------------ pkg/kubectl/resource_printer_test.go | 25 ++++++++++++-- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/pkg/kubectl/resource_printer.go b/pkg/kubectl/resource_printer.go index ab95e5adb72..1fa60a51dd2 100644 --- a/pkg/kubectl/resource_printer.go +++ b/pkg/kubectl/resource_printer.go @@ -28,6 +28,7 @@ import ( "text/template" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/golang/glog" @@ -45,35 +46,26 @@ func GetPrinter(format, templateFile string, defaultPrinter ResourcePrinter) (Re case "yaml": printer = &YAMLPrinter{} case "template": - var data []byte if len(templateFile) == 0 { return nil, false, fmt.Errorf("template format specified but no template given") } - tmpl, err := template.New("output").Parse(templateFile) + var err error + printer, err = NewTemplatePrinter([]byte(templateFile)) if err != nil { - return nil, false, fmt.Errorf("error parsing template %s, %v\n", string(data), err) - } - printer = &TemplatePrinter{ - Template: tmpl, + return nil, false, fmt.Errorf("error parsing template %s, %v\n", templateFile, err) } case "templatefile": - var data []byte - if len(templateFile) > 0 { - var err error - data, err = ioutil.ReadFile(templateFile) - if err != nil { - return nil, false, fmt.Errorf("error reading template %s, %v\n", templateFile, err) - } - } else { + if len(templateFile) == 0 { return nil, false, fmt.Errorf("templatefile format specified but no template file given") } - tmpl, err := template.New("output").Parse(string(data)) + data, err := ioutil.ReadFile(templateFile) + if err != nil { + return nil, false, fmt.Errorf("error reading template %s, %v\n", templateFile, err) + } + printer, err = NewTemplatePrinter(data) if err != nil { return nil, false, fmt.Errorf("error parsing template %s, %v\n", string(data), err) } - printer = &TemplatePrinter{ - Template: tmpl, - } case "": printer = defaultPrinter versioned = false @@ -323,12 +315,29 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er // TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template. type TemplatePrinter struct { - Template *template.Template + template *template.Template +} + +func NewTemplatePrinter(tmpl []byte) (*TemplatePrinter, error) { + t, err := template.New("output").Parse(string(tmpl)) + if err != nil { + return nil, err + } + return &TemplatePrinter{t}, nil } // PrintObj formats the obj with the Go Template. func (t *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error { - return t.Template.Execute(w, obj) + data, err := latest.Codec.Encode(obj) + if err != nil { + return err + } + outObj := map[string]interface{}{} + err = json.Unmarshal(data, &outObj) + if err != nil { + return err + } + return t.template.Execute(w, outObj) } func tabbedString(f func(*tabwriter.Writer) error) (string, error) { diff --git a/pkg/kubectl/resource_printer_test.go b/pkg/kubectl/resource_printer_test.go index 5cf4aacee00..fc7c6b6bd8d 100644 --- a/pkg/kubectl/resource_printer_test.go +++ b/pkg/kubectl/resource_printer_test.go @@ -86,14 +86,17 @@ func TestPrintYAML(t *testing.T) { func TestPrintTemplate(t *testing.T) { buf := bytes.NewBuffer([]byte{}) - printer, versioned, err := GetPrinter("template", "{{ .Name }}", nil) + printer, versioned, err := GetPrinter("template", "{{.id}}", nil) if err != nil { - t.Errorf("unexpected error: %#v", err) + t.Fatalf("unexpected error: %#v", err) } if !versioned { t.Errorf("printer should be versioned") } - printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf) + err = printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf) + if err != nil { + t.Fatalf("unexpected error: %#v", err) + } if buf.String() != "foo" { t.Errorf("unexpected output: %s", buf.String()) } @@ -204,3 +207,19 @@ func TestUnknownTypePrinting(t *testing.T) { t.Errorf("An error was expected from printing unknown type") } } + +func TestTemplateEmitsVersionedObjects(t *testing.T) { + // kind is always blank in memory and set on the wire + printer, err := NewTemplatePrinter([]byte(`{{.kind}}`)) + if err != nil { + t.Fatalf("tmpl fail: %v", err) + } + buffer := &bytes.Buffer{} + err = printer.PrintObj(&api.Pod{}, buffer) + if err != nil { + t.Fatalf("print fail: %v", err) + } + if e, a := "Pod", string(buffer.Bytes()); e != a { + t.Errorf("Expected %v, got %v", e, a) + } +}