mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 05:27:21 +00:00
Display an external version of the object for --output
Use the version of the API the RESTMapper prefers (currently)
This commit is contained in:
parent
179213f61c
commit
a8ccb0f99f
@ -84,7 +84,7 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
|
|||||||
cmds.PersistentFlags().StringP("server", "s", "", "Kubernetes apiserver to connect to")
|
cmds.PersistentFlags().StringP("server", "s", "", "Kubernetes apiserver to connect to")
|
||||||
cmds.PersistentFlags().StringP("auth-path", "a", os.Getenv("HOME")+"/.kubernetes_auth", "Path to the auth info file. If missing, prompt the user. Only used if using https.")
|
cmds.PersistentFlags().StringP("auth-path", "a", os.Getenv("HOME")+"/.kubernetes_auth", "Path to the auth info file. If missing, prompt the user. Only used if using https.")
|
||||||
cmds.PersistentFlags().Bool("match-server-version", false, "Require server version to match client version")
|
cmds.PersistentFlags().Bool("match-server-version", false, "Require server version to match client version")
|
||||||
cmds.PersistentFlags().String("api-version", latest.Version, "The version of the API to use against the server (used for viewing resources only)")
|
cmds.PersistentFlags().String("api-version", latest.Version, "The version of the API to use against the server")
|
||||||
cmds.PersistentFlags().String("certificate-authority", "", "Path to a certificate file for the certificate authority")
|
cmds.PersistentFlags().String("certificate-authority", "", "Path to a certificate file for the certificate authority")
|
||||||
cmds.PersistentFlags().String("client-certificate", "", "Path to a client certificate for TLS.")
|
cmds.PersistentFlags().String("client-certificate", "", "Path to a client certificate for TLS.")
|
||||||
cmds.PersistentFlags().String("client-key", "", "Path to a client key file for TLS.")
|
cmds.PersistentFlags().String("client-key", "", "Path to a client key file for TLS.")
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
|
||||||
@ -33,7 +34,8 @@ func (f *Factory) NewCmdGet(out io.Writer) *cobra.Command {
|
|||||||
Possible resources include pods (po), replication controllers (rc), services
|
Possible resources include pods (po), replication controllers (rc), services
|
||||||
(se) or minions (mi).
|
(se) or minions (mi).
|
||||||
|
|
||||||
If you specify a Go template, you can use any field defined in pkg/api/types.go.
|
If you specify a Go template, you can use any fields defined for the API version
|
||||||
|
you are connecting to the server with.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
$ kubectl get pods
|
$ kubectl get pods
|
||||||
@ -54,16 +56,27 @@ Examples:
|
|||||||
client, err := f.Client(cmd, mapping)
|
client, err := f.Client(cmd, mapping)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
|
|
||||||
obj, err := kubectl.NewRESTHelper(client, mapping).Get(namespace, name, labels)
|
|
||||||
checkErr(err)
|
|
||||||
|
|
||||||
outputFormat := getFlagString(cmd, "output")
|
outputFormat := getFlagString(cmd, "output")
|
||||||
templateFile := getFlagString(cmd, "template")
|
templateFile := getFlagString(cmd, "template")
|
||||||
defaultPrinter, err := f.Printer(cmd, mapping, getFlagBool(cmd, "no-headers"))
|
defaultPrinter, err := f.Printer(cmd, mapping, getFlagBool(cmd, "no-headers"))
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
|
|
||||||
err = kubectl.Print(out, obj, outputFormat, templateFile, defaultPrinter)
|
printer, versioned, err := kubectl.GetPrinter(outputFormat, templateFile, defaultPrinter)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
|
|
||||||
|
obj, err := kubectl.NewRESTHelper(client, mapping).Get(namespace, name, labels)
|
||||||
|
checkErr(err)
|
||||||
|
|
||||||
|
if versioned {
|
||||||
|
// TODO Add an --output-version lock which can ensure that regardless of the
|
||||||
|
// server version, the client output stays the same.
|
||||||
|
obj, err = mapping.ObjectConvertor.ConvertToVersion(obj, mapping.APIVersion)
|
||||||
|
checkErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := printer.PrintObj(obj, out); err != nil {
|
||||||
|
checkErr(fmt.Errorf("Unable to output the provided object: %v", err))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmd.Flags().StringP("output", "o", "", "Output format: json|yaml|template|templatefile")
|
cmd.Flags().StringP("output", "o", "", "Output format: json|yaml|template|templatefile")
|
||||||
|
@ -34,20 +34,10 @@ import (
|
|||||||
"gopkg.in/v1/yaml"
|
"gopkg.in/v1/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Print outputs a runtime.Object to an io.Writer in the given format
|
// GetPrinter returns a resource printer and a bool indicating whether the object must be
|
||||||
func Print(w io.Writer, obj runtime.Object, format string, templateFile string, defaultPrinter ResourcePrinter) error {
|
// versioned for the given format.
|
||||||
printer, err := getPrinter(format, templateFile, defaultPrinter)
|
func GetPrinter(format, templateFile string, defaultPrinter ResourcePrinter) (ResourcePrinter, bool, error) {
|
||||||
if err != nil {
|
versioned := true
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := printer.PrintObj(obj, w); err != nil {
|
|
||||||
return fmt.Errorf("Failed to print: %v\nRaw received object:\n%#v", err, obj)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPrinter(format, templateFile string, defaultPrinter ResourcePrinter) (ResourcePrinter, error) {
|
|
||||||
var printer ResourcePrinter
|
var printer ResourcePrinter
|
||||||
switch format {
|
switch format {
|
||||||
case "json":
|
case "json":
|
||||||
@ -57,11 +47,11 @@ func getPrinter(format, templateFile string, defaultPrinter ResourcePrinter) (Re
|
|||||||
case "template":
|
case "template":
|
||||||
var data []byte
|
var data []byte
|
||||||
if len(templateFile) == 0 {
|
if len(templateFile) == 0 {
|
||||||
return printer, fmt.Errorf("template format specified but no template given")
|
return nil, false, fmt.Errorf("template format specified but no template given")
|
||||||
}
|
}
|
||||||
tmpl, err := template.New("output").Parse(templateFile)
|
tmpl, err := template.New("output").Parse(templateFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return printer, fmt.Errorf("Error parsing template %s, %v\n", string(data), err)
|
return nil, false, fmt.Errorf("Error parsing template %s, %v\n", string(data), err)
|
||||||
}
|
}
|
||||||
printer = &TemplatePrinter{
|
printer = &TemplatePrinter{
|
||||||
Template: tmpl,
|
Template: tmpl,
|
||||||
@ -72,27 +62,30 @@ func getPrinter(format, templateFile string, defaultPrinter ResourcePrinter) (Re
|
|||||||
var err error
|
var err error
|
||||||
data, err = ioutil.ReadFile(templateFile)
|
data, err = ioutil.ReadFile(templateFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return printer, fmt.Errorf("Error reading template %s, %v\n", templateFile, err)
|
return nil, false, fmt.Errorf("Error reading template %s, %v\n", templateFile, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return printer, fmt.Errorf("templatefile format specified but no template file given")
|
return nil, false, fmt.Errorf("templatefile format specified but no template file given")
|
||||||
}
|
}
|
||||||
tmpl, err := template.New("output").Parse(string(data))
|
tmpl, err := template.New("output").Parse(string(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return printer, fmt.Errorf("Error parsing template %s, %v\n", string(data), err)
|
return nil, false, fmt.Errorf("Error parsing template %s, %v\n", string(data), err)
|
||||||
}
|
}
|
||||||
printer = &TemplatePrinter{
|
printer = &TemplatePrinter{
|
||||||
Template: tmpl,
|
Template: tmpl,
|
||||||
}
|
}
|
||||||
default:
|
case "":
|
||||||
printer = defaultPrinter
|
printer = defaultPrinter
|
||||||
|
versioned = false
|
||||||
|
default:
|
||||||
|
return nil, false, fmt.Errorf("output format %q not recognized", format)
|
||||||
}
|
}
|
||||||
return printer, nil
|
return printer, versioned, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourcePrinter is an interface that knows how to print API resources.
|
// ResourcePrinter is an interface that knows how to print API resources.
|
||||||
type ResourcePrinter interface {
|
type ResourcePrinter interface {
|
||||||
// Print receives an arbitrary JSON body, formats it and prints it to a writer.
|
// Print receives an arbitrary object, formats it and prints it to a writer.
|
||||||
PrintObj(runtime.Object, io.Writer) error
|
PrintObj(runtime.Object, io.Writer) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,9 +54,14 @@ func TestJSONPrinter(t *testing.T) {
|
|||||||
|
|
||||||
func TestPrintJSON(t *testing.T) {
|
func TestPrintJSON(t *testing.T) {
|
||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
if err := Print(buf, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, "json", "", nil); err != nil {
|
printer, versioned, err := GetPrinter("json", "", nil)
|
||||||
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %#v", err)
|
t.Errorf("unexpected error: %#v", err)
|
||||||
}
|
}
|
||||||
|
if !versioned {
|
||||||
|
t.Errorf("printer should be versioned")
|
||||||
|
}
|
||||||
|
printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf)
|
||||||
obj := map[string]interface{}{}
|
obj := map[string]interface{}{}
|
||||||
if err := json.Unmarshal(buf.Bytes(), &obj); err != nil {
|
if err := json.Unmarshal(buf.Bytes(), &obj); err != nil {
|
||||||
t.Errorf("unexpected error: %#v\n%s", err, buf.String())
|
t.Errorf("unexpected error: %#v\n%s", err, buf.String())
|
||||||
@ -65,9 +70,14 @@ func TestPrintJSON(t *testing.T) {
|
|||||||
|
|
||||||
func TestPrintYAML(t *testing.T) {
|
func TestPrintYAML(t *testing.T) {
|
||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
if err := Print(buf, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, "yaml", "", nil); err != nil {
|
printer, versioned, err := GetPrinter("yaml", "", nil)
|
||||||
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %#v", err)
|
t.Errorf("unexpected error: %#v", err)
|
||||||
}
|
}
|
||||||
|
if !versioned {
|
||||||
|
t.Errorf("printer should be versioned")
|
||||||
|
}
|
||||||
|
printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf)
|
||||||
obj := map[string]interface{}{}
|
obj := map[string]interface{}{}
|
||||||
if err := yaml.Unmarshal(buf.Bytes(), &obj); err != nil {
|
if err := yaml.Unmarshal(buf.Bytes(), &obj); err != nil {
|
||||||
t.Errorf("unexpected error: %#v\n%s", err, buf.String())
|
t.Errorf("unexpected error: %#v\n%s", err, buf.String())
|
||||||
@ -76,31 +86,33 @@ func TestPrintYAML(t *testing.T) {
|
|||||||
|
|
||||||
func TestPrintTemplate(t *testing.T) {
|
func TestPrintTemplate(t *testing.T) {
|
||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
if err := Print(buf, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, "template", "{{ .Name }}", nil); err != nil {
|
printer, versioned, err := GetPrinter("template", "{{ .Name }}", nil)
|
||||||
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %#v", err)
|
t.Errorf("unexpected error: %#v", err)
|
||||||
}
|
}
|
||||||
|
if !versioned {
|
||||||
|
t.Errorf("printer should be versioned")
|
||||||
|
}
|
||||||
|
printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf)
|
||||||
if buf.String() != "foo" {
|
if buf.String() != "foo" {
|
||||||
t.Errorf("unexpected output: %s", buf.String())
|
t.Errorf("unexpected output: %s", buf.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPrintEmptyTemplate(t *testing.T) {
|
func TestPrintEmptyTemplate(t *testing.T) {
|
||||||
buf := bytes.NewBuffer([]byte{})
|
if _, _, err := GetPrinter("template", "", nil); err == nil {
|
||||||
if err := Print(buf, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, "template", "", nil); err == nil {
|
|
||||||
t.Errorf("unexpected non-error")
|
t.Errorf("unexpected non-error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPrintBadTemplate(t *testing.T) {
|
func TestPrintBadTemplate(t *testing.T) {
|
||||||
buf := bytes.NewBuffer([]byte{})
|
if _, _, err := GetPrinter("template", "{{ .Name", nil); err == nil {
|
||||||
if err := Print(buf, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, "template", "{{ .Name", nil); err == nil {
|
|
||||||
t.Errorf("unexpected non-error")
|
t.Errorf("unexpected non-error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPrintBadTemplateFile(t *testing.T) {
|
func TestPrintBadTemplateFile(t *testing.T) {
|
||||||
buf := bytes.NewBuffer([]byte{})
|
if _, _, err := GetPrinter("templatefile", "", nil); err == nil {
|
||||||
if err := Print(buf, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, "templatefile", "", nil); err == nil {
|
|
||||||
t.Errorf("unexpected non-error")
|
t.Errorf("unexpected non-error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user