change -o template to -o go-template=...
This commit is contained in:
@@ -79,7 +79,7 @@ func NewCmdGet(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
options := &GetOptions{}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "get [(-o|--output=)json|yaml|template|templatefile|wide|jsonpath|...] (TYPE [NAME | -l label] | TYPE/NAME ...) [flags]",
|
||||
Use: "get [(-o|--output=)json|yaml|wide|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...] (TYPE [NAME | -l label] | TYPE/NAME ...) [flags]",
|
||||
Short: "Display one or many resources",
|
||||
Long: get_long,
|
||||
Example: get_example,
|
||||
|
||||
@@ -19,6 +19,7 @@ package util
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
@@ -28,12 +29,12 @@ import (
|
||||
|
||||
// AddPrinterFlags adds printing related flags to a command (e.g. output format, no headers, template path)
|
||||
func AddPrinterFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml|template|templatefile|wide|jsonpath|name.")
|
||||
cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml|wide|name|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=... See golang template [http://golang.org/pkg/text/template/#pkg-overview] and jsonpath template [http://releases.k8s.io/HEAD/docs/user-guide/jsonpath.md].")
|
||||
cmd.Flags().String("output-version", "", "Output the formatted object with the given version (default api-version).")
|
||||
cmd.Flags().Bool("no-headers", false, "When using the default output, don't print headers.")
|
||||
// template shorthand -t is deprecated to support -t for --tty
|
||||
// TODO: remove template flag shorthand -t
|
||||
cmd.Flags().StringP("template", "t", "", "Template string or path to template file to use when -o=template, -o=templatefile or -o=jsonpath. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. The jsonpath template is composed of jsonpath expressions enclosed by {} [http://releases.k8s.io/HEAD/docs/user-guide/jsonpath.md]")
|
||||
cmd.Flags().StringP("template", "t", "", "Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].")
|
||||
cmd.Flags().MarkShorthandDeprecated("template", "please use --template instead")
|
||||
cmd.Flags().String("sort-by", "", "If non-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. 'ObjectMeta.Name'). The field in the API resource specified by this JSONPath expression must be an integer or a string.")
|
||||
cmd.Flags().BoolP("show-all", "a", false, "When printing, show all resources (default hide terminated pods.)")
|
||||
@@ -94,6 +95,14 @@ func PrinterForCommand(cmd *cobra.Command) (kubectl.ResourcePrinter, bool, error
|
||||
outputFormat = "template"
|
||||
}
|
||||
|
||||
templateFormat := []string{"go-template=", "go-template-file=", "jsonpath=", "jsonpath-file="}
|
||||
for _, format := range templateFormat {
|
||||
if strings.HasPrefix(outputFormat, format) {
|
||||
templateFile = outputFormat[len(format):]
|
||||
outputFormat = format[:len(format)-1]
|
||||
}
|
||||
}
|
||||
|
||||
printer, generic, err := kubectl.GetPrinter(outputFormat, templateFile)
|
||||
if err != nil {
|
||||
return nil, generic, err
|
||||
|
||||
@@ -57,7 +57,7 @@ func GetPrinter(format, formatArgument string) (ResourcePrinter, bool, error) {
|
||||
printer = &YAMLPrinter{}
|
||||
case "name":
|
||||
printer = &NamePrinter{}
|
||||
case "template":
|
||||
case "template", "go-template":
|
||||
if len(formatArgument) == 0 {
|
||||
return nil, false, fmt.Errorf("template format specified but no template given")
|
||||
}
|
||||
@@ -66,7 +66,7 @@ func GetPrinter(format, formatArgument string) (ResourcePrinter, bool, error) {
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error parsing template %s, %v\n", formatArgument, err)
|
||||
}
|
||||
case "templatefile":
|
||||
case "templatefile", "go-template-file":
|
||||
if len(formatArgument) == 0 {
|
||||
return nil, false, fmt.Errorf("templatefile format specified but no template file given")
|
||||
}
|
||||
@@ -80,13 +80,25 @@ func GetPrinter(format, formatArgument string) (ResourcePrinter, bool, error) {
|
||||
}
|
||||
case "jsonpath":
|
||||
if len(formatArgument) == 0 {
|
||||
return nil, false, fmt.Errorf("jsonpath format specified but no jsonpath template given")
|
||||
return nil, false, fmt.Errorf("jsonpath template format specified but no template given")
|
||||
}
|
||||
var err error
|
||||
printer, err = NewJSONPathPrinter(formatArgument)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error parsing jsonpath %s, %v\n", formatArgument, err)
|
||||
}
|
||||
case "jsonpath-file":
|
||||
if len(formatArgument) == 0 {
|
||||
return nil, false, fmt.Errorf("jsonpath file format specified but no template file file given")
|
||||
}
|
||||
data, err := ioutil.ReadFile(formatArgument)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error reading template %s, %v\n", formatArgument, err)
|
||||
}
|
||||
printer, err = NewJSONPathPrinter(string(data))
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error parsing template %s, %v\n", string(data), err)
|
||||
}
|
||||
case "wide":
|
||||
fallthrough
|
||||
case "":
|
||||
|
||||
@@ -34,6 +34,26 @@ type jsonpathTest struct {
|
||||
}
|
||||
|
||||
func testJSONPath(tests []jsonpathTest, t *testing.T) {
|
||||
for _, test := range tests {
|
||||
j := New(test.name)
|
||||
err := j.Parse(test.template)
|
||||
if err != nil {
|
||||
t.Errorf("in %s, parse %s error %v", test.name, test.template, err)
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
err = j.Execute(buf, test.input)
|
||||
if err != nil {
|
||||
t.Errorf("in %s, execute error %v", test.name, err)
|
||||
}
|
||||
out := buf.String()
|
||||
if out != test.expect {
|
||||
t.Errorf(`in %s, expect to get "%s", got "%s"`, test.name, test.expect, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// testJSONPathSortOutput test testcases related to map, the results may print in random order
|
||||
func testJSONPathSortOutput(tests []jsonpathTest, t *testing.T) {
|
||||
for _, test := range tests {
|
||||
j := New(test.name)
|
||||
err := j.Parse(test.template)
|
||||
@@ -218,8 +238,6 @@ func TestKubenates(t *testing.T) {
|
||||
`127.0.0.1 127.0.0.2 127.0.0.3`},
|
||||
{"double range", "{range .items[*]}{range .status.addresses[*]}{.address}, {end}{end}", nodesData,
|
||||
`127.0.0.1, 127.0.0.2, 127.0.0.3, `},
|
||||
// TODO: fix & uncomment the case bellow (#13024)
|
||||
// {"recursive name", "{..name}", nodesData, `127.0.0.1 127.0.0.2 myself e2e`},
|
||||
{"item name", "{.items[*].metadata.name}", nodesData, `127.0.0.1 127.0.0.2`},
|
||||
{"union nodes capacity", "{.items[*]['metadata.name', 'status.capacity']}", nodesData,
|
||||
`127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8]`},
|
||||
@@ -228,4 +246,9 @@ func TestKubenates(t *testing.T) {
|
||||
{"user password", `{.users[?(@.name=="e2e")].user.password}`, &nodesData, "secret"},
|
||||
}
|
||||
testJSONPath(nodesTests, t)
|
||||
|
||||
randomPrintOrderTests := []jsonpathTest{
|
||||
{"recursive name", "{..name}", nodesData, `127.0.0.1 127.0.0.2 myself e2e`},
|
||||
}
|
||||
testJSONPathSortOutput(randomPrintOrderTests, t)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user