Merge pull request #4147 from jlowdermilk/kubeconfig-view

Allow output formatting for kubectl config view
This commit is contained in:
Brendan Burns 2015-02-05 14:48:02 -08:00
commit f153a27235
22 changed files with 219 additions and 209 deletions

View File

@ -338,7 +338,7 @@ Usage:
kubectl config [command]
Available Commands:
view displays the specified .kubeconfig file or a merged result
view displays merged .kubeconfig settings or a specified .kubeconfig file.
set-cluster name [--server=server] [--certificate-authority=path/to/certficate/authority] [--api-version=apiversion] [--insecure-skip-tls-verify=true] Sets a cluster entry in .kubeconfig
set-credentials name [--auth-path=path/to/auth/file] [--client-certificate=path/to/certficate/file] [--client-key=path/to/key/file] [--token=bearer_token_string] Sets a user entry in .kubeconfig
set-context name [--cluster=cluster-nickname] [--user=user-nickname] [--namespace=namespace] Sets a context entry in .kubeconfig
@ -395,7 +395,13 @@ Use "kubectl help [command]" for more information about that command.
```
#### config view
displays the specified .kubeconfig file or a merged result
displays merged .kubeconfig settings or a specified .kubeconfig file.
Examples:
// Show merged .kubeconfig settings.
$ kubectl config view
// Show only local ./.kubeconfig settings
$ kubectl config view --local
Usage:
```
@ -421,10 +427,14 @@ Usage:
--log_flush_frequency=5s: Maximum number of seconds between log flushes
--logtostderr=true: log to standard error instead of files
--match-server-version=false: Require server version to match client version
--merge=false: merge together the full hierarchy of .kubeconfig files
--merge=true: merge together the full hierarchy of .kubeconfig files
--namespace="": If present, the namespace scope for this CLI request.
--no-headers=false: When using the default output, don't print headers
-o, --output="": Output format: json|yaml|template|templatefile
--output-version="": Output the formatted object with the given version (default api-version)
-s, --server="": The address of the Kubernetes API server
--stderrthreshold=2: logs at or above this threshold go to stderr
-t, --template="": Template string or path to template file to use when -o=template or -o=templatefile.
--token="": Bearer token for authentication to the API server.
--user="": The name of the kubeconfig user to use
--v=0: log level for V logs

View File

@ -29,6 +29,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
cmdconfig "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config"
cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -143,7 +144,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
return kubectl.ReaperFor(mapping.Kind, client)
},
Validator: func(cmd *cobra.Command) (validation.Schema, error) {
if GetFlagBool(cmd, "validate") {
if cmdutil.GetFlagBool(cmd, "validate") {
client, err := clients.ClientForVersion("")
if err != nil {
return nil, err
@ -217,6 +218,62 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
return cmds
}
// PrintObject prints an api object given command line flags to modify the output format
func (f *Factory) PrintObject(cmd *cobra.Command, obj runtime.Object, out io.Writer) error {
mapper, _ := f.Object(cmd)
_, kind, err := api.Scheme.ObjectVersionAndKind(obj)
if err != nil {
return err
}
mapping, err := mapper.RESTMapping(kind)
if err != nil {
return err
}
printer, err := f.PrinterForMapping(cmd, mapping)
if err != nil {
return err
}
return printer.PrintObj(obj, out)
}
// PrinterForMapping returns a printer suitable for displaying the provided resource type.
// Requires that printer flags have been added to cmd (see AddPrinterFlags).
func (f *Factory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.ResourcePrinter, error) {
printer, ok, err := cmdutil.PrinterForCommand(cmd)
if err != nil {
return nil, err
}
if ok {
clientConfig, err := f.ClientConfig(cmd)
checkErr(err)
defaultVersion := clientConfig.Version
version := cmdutil.OutputVersion(cmd, defaultVersion)
if len(version) == 0 {
version = mapping.APIVersion
}
if len(version) == 0 {
return nil, fmt.Errorf("you must specify an output-version when using this output format")
}
printer = kubectl.NewVersionedPrinter(printer, mapping.ObjectConvertor, version)
} else {
printer, err = f.Printer(cmd, mapping, cmdutil.GetFlagBool(cmd, "no-headers"))
if err != nil {
return nil, err
}
}
return printer, nil
}
// ClientMapperForCommand returns a ClientMapper for the given command and factory.
func (f *Factory) ClientMapperForCommand(cmd *cobra.Command) resource.ClientMapper {
return resource.ClientMapperFunc(func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
return f.RESTClient(cmd, mapping)
})
}
// DefaultClientConfig creates a clientcmd.ClientConfig with the following hierarchy:
// 1. Use the kubeconfig builder. The number of merges and overrides here gets a little crazy. Stay with me.
// 1. Merge together the kubeconfig itself. This is done with the following hierarchy and merge rules:
@ -266,13 +323,6 @@ func DefaultClientConfig(flags *pflag.FlagSet) clientcmd.ClientConfig {
return clientConfig
}
// ClientMapperForCommand returns a ClientMapper for the given command and factory.
func ClientMapperForCommand(cmd *cobra.Command, f *Factory) resource.ClientMapper {
return resource.ClientMapperFunc(func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
return f.RESTClient(cmd, mapping)
})
}
func checkErr(err error) {
if err != nil {
glog.FatalDepth(1, err)

View File

@ -21,6 +21,7 @@ import (
"fmt"
"io"
"io/ioutil"
"os"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
@ -203,3 +204,43 @@ func TestClientVersions(t *testing.T) {
}
}
}
func ExamplePrintReplicationController() {
f, tf, codec := NewAPIFactory()
tf.Printer = kubectl.NewHumanReadablePrinter(false)
tf.Client = &client.FakeRESTClient{
Codec: codec,
Client: nil,
}
cmd := f.NewCmdRunContainer(os.Stdout)
ctrl := &api.ReplicationController{
ObjectMeta: api.ObjectMeta{
Name: "foo",
Labels: map[string]string{"foo": "bar"},
},
Spec: api.ReplicationControllerSpec{
Replicas: 1,
Selector: map[string]string{"foo": "bar"},
Template: &api.PodTemplateSpec{
ObjectMeta: api.ObjectMeta{
Labels: map[string]string{"foo": "bar"},
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "foo",
Image: "someimage",
},
},
},
},
},
}
err := f.PrintObject(cmd, ctrl, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
// Output:
// CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
// foo foo someimage foo=bar 1
}

View File

@ -21,11 +21,12 @@ import (
"io"
"os"
"github.com/ghodss/yaml"
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
)
type viewOptions struct {
@ -38,40 +39,45 @@ func NewCmdConfigView(out io.Writer, pathOptions *pathOptions) *cobra.Command {
cmd := &cobra.Command{
Use: "view",
Short: "displays the specified .kubeconfig file or a merged result",
Long: `displays the specified .kubeconfig file or a merged result`,
Short: "displays merged .kubeconfig settings or a specified .kubeconfig file.",
Long: `displays merged .kubeconfig settings or a specified .kubeconfig file.
Examples:
// Show merged .kubeconfig settings.
$ kubectl config view
// Show only local ./.kubeconfig settings
$ kubectl config view --local`,
Run: func(cmd *cobra.Command, args []string) {
err := options.run()
printer, _, err := util.PrinterForCommand(cmd)
if err != nil {
fmt.Printf("%v\n", err)
glog.FatalDepth(1, err)
}
config, err := options.loadConfig()
if err != nil {
glog.FatalDepth(1, err)
}
err = printer.PrintObj(config, out)
if err != nil {
glog.FatalDepth(1, err)
}
},
}
cmd.Flags().BoolVar(&options.merge, "merge", false, "merge together the full hierarchy of .kubeconfig files")
util.AddPrinterFlags(cmd)
// Default to yaml
cmd.Flags().Set("output", "yaml")
cmd.Flags().BoolVar(&options.merge, "merge", true, "merge together the full hierarchy of .kubeconfig files")
return cmd
}
func (o viewOptions) run() error {
func (o viewOptions) loadConfig() (*clientcmdapi.Config, error) {
err := o.validate()
if err != nil {
return err
return nil, err
}
config, _, err := o.getStartingConfig()
if err != nil {
return err
}
content, err := yaml.Marshal(config)
if err != nil {
return err
}
fmt.Printf("%v", string(content))
return nil
return config, err
}
func (o viewOptions) validate() error {

View File

@ -51,7 +51,7 @@ Examples:
checkErr(err)
mapper, typer := f.Object(cmd)
r := resource.NewBuilder(mapper, typer, ClientMapperForCommand(cmd, f)).
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand(cmd)).
ContinueOnError().
NamespaceParam(cmdNamespace).RequireNamespace().
FilenameParam(flags.Filenames...).

View File

@ -23,6 +23,7 @@ import (
"github.com/spf13/cobra"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
@ -62,11 +63,11 @@ Examples:
checkErr(err)
mapper, typer := f.Object(cmd)
r := resource.NewBuilder(mapper, typer, ClientMapperForCommand(cmd, f)).
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand(cmd)).
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(flags.Filenames...).
SelectorParam(GetFlagString(cmd, "selector")).
SelectorParam(cmdutil.GetFlagString(cmd, "selector")).
ResourceTypeOrNameArgs(args...).
Flatten().
Do()

View File

@ -20,6 +20,7 @@ import (
"fmt"
"io"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
@ -36,7 +37,7 @@ given resource.`,
checkErr(err)
mapper, _ := f.Object(cmd)
mapping, namespace, name := ResourceFromArgs(cmd, args, mapper, cmdNamespace)
mapping, namespace, name := util.ResourceFromArgs(cmd, args, mapper, cmdNamespace)
describer, err := f.Describer(cmd, mapping)
checkErr(err)

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
@ -51,27 +52,28 @@ $ kubectl expose streamer --port=4100 --protocol=udp --service-name=video-stream
client, err := f.Client(cmd)
checkErr(err)
generatorName := GetFlagString(cmd, "generator")
generatorName := util.GetFlagString(cmd, "generator")
generator, found := kubectl.Generators[generatorName]
if !found {
usageError(cmd, fmt.Sprintf("Generator: %s not found.", generator))
}
if GetFlagInt(cmd, "port") < 1 {
if util.GetFlagInt(cmd, "port") < 1 {
usageError(cmd, "--port is required and must be a positive integer.")
}
names := generator.ParamNames()
params := kubectl.MakeParams(cmd, names)
if len(GetFlagString(cmd, "service-name")) == 0 {
if len(util.GetFlagString(cmd, "service-name")) == 0 {
params["name"] = args[0]
} else {
params["name"] = GetFlagString(cmd, "service-name")
params["name"] = util.GetFlagString(cmd, "service-name")
}
if _, found := params["selector"]; !found {
rc, err := client.ReplicationControllers(namespace).Get(args[0])
checkErr(err)
params["selector"] = kubectl.MakeLabels(rc.Spec.Selector)
}
if GetFlagBool(cmd, "create-external-load-balancer") {
if util.GetFlagBool(cmd, "create-external-load-balancer") {
params["create-external-load-balancer"] = "true"
}
@ -81,22 +83,22 @@ $ kubectl expose streamer --port=4100 --protocol=udp --service-name=video-stream
service, err := generator.Generate(params)
checkErr(err)
inline := GetFlagString(cmd, "overrides")
inline := util.GetFlagString(cmd, "overrides")
if len(inline) > 0 {
Merge(service, inline, "Service")
util.Merge(service, inline, "Service")
}
// TODO: extract this flag to a central location, when such a location exists.
if !GetFlagBool(cmd, "dry-run") {
if !util.GetFlagBool(cmd, "dry-run") {
service, err = client.Services(namespace).Create(service.(*api.Service))
checkErr(err)
}
err = PrintObject(cmd, service, f, out)
err = f.PrintObject(cmd, service, out)
checkErr(err)
},
}
AddPrinterFlags(cmd)
util.AddPrinterFlags(cmd)
cmd.Flags().String("generator", "service/v1", "The name of the api generator that you want to use. Default 'service/v1'")
cmd.Flags().String("protocol", "TCP", "The network protocol for the service you want to be created. Default 'tcp'")
cmd.Flags().Int("port", -1, "The port that the service should serve on. Required.")

View File

@ -23,6 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@ -59,7 +60,7 @@ Examples:
RunGet(f, out, cmd, args)
},
}
AddPrinterFlags(cmd)
util.AddPrinterFlags(cmd)
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on")
cmd.Flags().BoolP("watch", "w", false, "After listing/getting the requested object, watch for changes.")
cmd.Flags().Bool("watch-only", false, "Watch for changes to the requested object(s), without listing/getting first.")
@ -70,16 +71,16 @@ Examples:
// TODO: convert all direct flag accessors to a struct and pass that instead of cmd
// TODO: return an error instead of using glog.Fatal and checkErr
func RunGet(f *Factory, out io.Writer, cmd *cobra.Command, args []string) {
selector := GetFlagString(cmd, "selector")
selector := util.GetFlagString(cmd, "selector")
mapper, typer := f.Object(cmd)
cmdNamespace, err := f.DefaultNamespace(cmd)
checkErr(err)
// handle watch separately since we cannot watch multiple resource types
isWatch, isWatchOnly := GetFlagBool(cmd, "watch"), GetFlagBool(cmd, "watch-only")
isWatch, isWatchOnly := util.GetFlagBool(cmd, "watch"), util.GetFlagBool(cmd, "watch-only")
if isWatch || isWatchOnly {
r := resource.NewBuilder(mapper, typer, ClientMapperForCommand(cmd, f)).
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand(cmd)).
NamespaceParam(cmdNamespace).DefaultNamespace().
SelectorParam(selector).
ResourceTypeOrNameArgs(args...).
@ -89,7 +90,7 @@ func RunGet(f *Factory, out io.Writer, cmd *cobra.Command, args []string) {
mapping, err := r.ResourceMapping()
checkErr(err)
printer, err := PrinterForMapping(f, cmd, mapping)
printer, err := f.PrinterForMapping(cmd, mapping)
checkErr(err)
obj, err := r.Object()
@ -115,12 +116,12 @@ func RunGet(f *Factory, out io.Writer, cmd *cobra.Command, args []string) {
return
}
b := resource.NewBuilder(mapper, typer, ClientMapperForCommand(cmd, f)).
b := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand(cmd)).
NamespaceParam(cmdNamespace).DefaultNamespace().
SelectorParam(selector).
ResourceTypeOrNameArgs(args...).
Latest()
printer, generic, err := PrinterForCommand(cmd)
printer, generic, err := util.PrinterForCommand(cmd)
checkErr(err)
if generic {
@ -129,7 +130,7 @@ func RunGet(f *Factory, out io.Writer, cmd *cobra.Command, args []string) {
defaultVersion := clientConfig.Version
// the outermost object will be converted to the output-version
version := outputVersion(cmd, defaultVersion)
version := util.OutputVersion(cmd, defaultVersion)
if len(version) == 0 {
// TODO: add a new ResourceBuilder mode for Object() that attempts to ensure the objects
// are in the appropriate version if one exists (and if not, use the best effort).
@ -149,7 +150,7 @@ func RunGet(f *Factory, out io.Writer, cmd *cobra.Command, args []string) {
// use the default printer for each object
err = b.Do().Visit(func(r *resource.Info) error {
printer, err := PrinterForMapping(f, cmd, r.Mapping)
printer, err := f.PrinterForMapping(cmd, r.Mapping)
if err != nil {
return err
}

View File

@ -20,6 +20,7 @@ import (
"io"
"strconv"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
@ -66,7 +67,7 @@ Examples:
}
follow := false
if GetFlagBool(cmd, "follow") {
if util.GetFlagBool(cmd, "follow") {
follow = true
}

View File

@ -1,67 +0,0 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd_test
import (
"fmt"
"os"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
. "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd"
)
func ExamplePrintReplicationController() {
f, tf, codec := NewAPIFactory()
tf.Printer = kubectl.NewHumanReadablePrinter(false)
tf.Client = &client.FakeRESTClient{
Codec: codec,
Client: nil,
}
cmd := f.NewCmdRunContainer(os.Stdout)
ctrl := &api.ReplicationController{
ObjectMeta: api.ObjectMeta{
Name: "foo",
Labels: map[string]string{"foo": "bar"},
},
Spec: api.ReplicationControllerSpec{
Replicas: 1,
Selector: map[string]string{"foo": "bar"},
Template: &api.PodTemplateSpec{
ObjectMeta: api.ObjectMeta{
Labels: map[string]string{"foo": "bar"},
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "foo",
Image: "someimage",
},
},
},
},
},
}
err := PrintObject(cmd, ctrl, f, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
// Output:
// CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
// foo foo someimage foo=bar 1
}

View File

@ -21,6 +21,7 @@ import (
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/golang/glog"
"github.com/spf13/cobra"
)
@ -31,17 +32,17 @@ func (f *Factory) NewCmdProxy(out io.Writer) *cobra.Command {
Short: "Run a proxy to the Kubernetes API server",
Long: `Run a proxy to the Kubernetes API server.`,
Run: func(cmd *cobra.Command, args []string) {
port := GetFlagInt(cmd, "port")
port := util.GetFlagInt(cmd, "port")
glog.Infof("Starting to serve on localhost:%d", port)
clientConfig, err := f.ClientConfig(cmd)
checkErr(err)
staticPrefix := GetFlagString(cmd, "www-prefix")
staticPrefix := util.GetFlagString(cmd, "www-prefix")
if !strings.HasSuffix(staticPrefix, "/") {
staticPrefix += "/"
}
server, err := kubectl.NewProxyServer(GetFlagString(cmd, "www"), staticPrefix, clientConfig)
server, err := kubectl.NewProxyServer(util.GetFlagString(cmd, "www"), staticPrefix, clientConfig)
checkErr(err)
glog.Fatal(server.Serve(port))
},

View File

@ -21,6 +21,7 @@ import (
"io"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
@ -44,7 +45,7 @@ Examples:
$ kubectl resize --current-replicas=2 --replicas=3 replicationcontrollers foo
`,
Run: func(cmd *cobra.Command, args []string) {
count := GetFlagInt(cmd, "replicas")
count := util.GetFlagInt(cmd, "replicas")
if len(args) != 2 || count < 0 {
usageError(cmd, "--replicas=<count> <resource> <id>")
}
@ -53,13 +54,13 @@ Examples:
checkErr(err)
mapper, _ := f.Object(cmd)
mapping, namespace, name := ResourceFromArgs(cmd, args, mapper, cmdNamespace)
mapping, namespace, name := util.ResourceFromArgs(cmd, args, mapper, cmdNamespace)
resizer, err := f.Resizer(cmd, mapping)
checkErr(err)
resourceVersion := GetFlagString(cmd, "resource-version")
currentSize := GetFlagInt(cmd, "current-replicas")
resourceVersion := util.GetFlagString(cmd, "resource-version")
currentSize := util.GetFlagInt(cmd, "current-replicas")
s, err := resizer.Resize(namespace, name, &kubectl.ResizePrecondition{currentSize, resourceVersion}, uint(count))
checkErr(err)
fmt.Fprintf(out, "%s\n", s)

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
@ -48,13 +49,13 @@ $ kubectl rollingupdate frontend-v1 -f frontend-v2.json
$ cat frontend-v2.json | kubectl rollingupdate frontend-v1 -f -
<update pods of frontend-v1 using json data passed into stdin>`,
Run: func(cmd *cobra.Command, args []string) {
filename := GetFlagString(cmd, "filename")
filename := util.GetFlagString(cmd, "filename")
if len(filename) == 0 {
usageError(cmd, "Must specify filename for new controller")
}
period := GetFlagDuration(cmd, "update-period")
interval := GetFlagDuration(cmd, "poll-interval")
timeout := GetFlagDuration(cmd, "timeout")
period := util.GetFlagDuration(cmd, "update-period")
interval := util.GetFlagDuration(cmd, "poll-interval")
timeout := util.GetFlagDuration(cmd, "timeout")
if len(args) != 1 {
usageError(cmd, "Must specify the controller to update")
}
@ -67,7 +68,7 @@ $ cat frontend-v2.json | kubectl rollingupdate frontend-v1 -f -
cmdApiVersion := clientConfig.Version
mapper, typer := f.Object(cmd)
mapping, namespace, newName, data := ResourceFromFile(filename, typer, mapper, schema, cmdApiVersion)
mapping, namespace, newName, data := util.ResourceFromFile(filename, typer, mapper, schema, cmdApiVersion)
if mapping.Kind != "ReplicationController" {
usageError(cmd, "%s does not specify a valid ReplicationController", filename)
}
@ -78,7 +79,7 @@ $ cat frontend-v2.json | kubectl rollingupdate frontend-v1 -f -
cmdNamespace, err := f.DefaultNamespace(cmd)
checkErr(err)
err = CompareNamespace(cmdNamespace, namespace)
err = util.CompareNamespace(cmdNamespace, namespace)
checkErr(err)
client, err := f.Client(cmd)

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
@ -55,7 +56,7 @@ Examples:
client, err := f.Client(cmd)
checkErr(err)
generatorName := GetFlagString(cmd, "generator")
generatorName := util.GetFlagString(cmd, "generator")
generator, found := kubectl.Generators[generatorName]
if !found {
usageError(cmd, fmt.Sprintf("Generator: %s not found.", generator))
@ -70,22 +71,22 @@ Examples:
controller, err := generator.Generate(params)
checkErr(err)
inline := GetFlagString(cmd, "overrides")
inline := util.GetFlagString(cmd, "overrides")
if len(inline) > 0 {
Merge(controller, inline, "ReplicationController")
util.Merge(controller, inline, "ReplicationController")
}
// TODO: extract this flag to a central location, when such a location exists.
if !GetFlagBool(cmd, "dry-run") {
if !util.GetFlagBool(cmd, "dry-run") {
controller, err = client.ReplicationControllers(namespace).Create(controller.(*api.ReplicationController))
checkErr(err)
}
err = PrintObject(cmd, controller, f, out)
err = f.PrintObject(cmd, controller, out)
checkErr(err)
},
}
AddPrinterFlags(cmd)
util.AddPrinterFlags(cmd)
cmd.Flags().String("generator", "run-container/v1", "The name of the api generator that you want to use. Default 'run-container-controller/v1'")
cmd.Flags().String("image", "", "The image for the container you wish to run.")
cmd.Flags().IntP("replicas", "r", 1, "Number of replicas to create for this container. Default 1")

View File

@ -20,6 +20,7 @@ import (
"fmt"
"io"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
@ -42,7 +43,7 @@ Examples:
}
cmdNamespace, err := f.DefaultNamespace(cmd)
mapper, _ := f.Object(cmd)
mapping, namespace, name := ResourceFromArgs(cmd, args, mapper, cmdNamespace)
mapping, namespace, name := util.ResourceFromArgs(cmd, args, mapper, cmdNamespace)
reaper, err := f.Reaper(cmd, mapping)
checkErr(err)

View File

@ -20,6 +20,7 @@ import (
"fmt"
"io"
cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/spf13/cobra"
@ -53,14 +54,14 @@ Examples:
checkErr(err)
mapper, typer := f.Object(cmd)
r := resource.NewBuilder(mapper, typer, ClientMapperForCommand(cmd, f)).
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand(cmd)).
ContinueOnError().
NamespaceParam(cmdNamespace).RequireNamespace().
FilenameParam(flags.Filenames...).
Flatten().
Do()
patch := GetFlagString(cmd, "patch")
patch := cmdutil.GetFlagString(cmd, "patch")
if len(flags.Filenames) == 0 && len(patch) == 0 {
usageError(cmd, "Must specify --filename or --patch to update")
}
@ -102,7 +103,7 @@ func updateWithPatch(cmd *cobra.Command, args []string, f *Factory, patch string
checkErr(err)
mapper, _ := f.Object(cmd)
mapping, namespace, name := ResourceFromArgs(cmd, args, mapper, cmdNamespace)
mapping, namespace, name := cmdutil.ResourceFromArgs(cmd, args, mapper, cmdNamespace)
client, err := f.RESTClient(cmd, mapping)
checkErr(err)
@ -110,7 +111,7 @@ func updateWithPatch(cmd *cobra.Command, args []string, f *Factory, patch string
obj, err := helper.Get(namespace, name)
checkErr(err)
Merge(obj, patch, mapping.Kind)
cmdutil.Merge(obj, patch, mapping.Kind)
data, err := helper.Codec.Encode(obj)
checkErr(err)

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
package util
import (
"encoding/json"
@ -34,6 +34,18 @@ import (
"github.com/spf13/cobra"
)
func checkErr(err error) {
if err != nil {
glog.FatalDepth(1, err)
}
}
func usageError(cmd *cobra.Command, format string, args ...interface{}) {
glog.Errorf(format, args...)
glog.Errorf("See '%s -h' for help.", cmd.CommandPath())
os.Exit(1)
}
func GetFlagString(cmd *cobra.Command, flag string) string {
f := cmd.Flags().Lookup(flag)
if f == nil {

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
package util
import (
"reflect"

View File

@ -14,16 +14,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
package util
import (
"fmt"
"io"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/spf13/cobra"
)
@ -35,28 +29,8 @@ func AddPrinterFlags(cmd *cobra.Command) {
cmd.Flags().StringP("template", "t", "", "Template string or path to template file to use when -o=template or -o=templatefile.")
}
// PrintObject prints an api object given command line flags to modify the output format
func PrintObject(cmd *cobra.Command, obj runtime.Object, f *Factory, out io.Writer) error {
mapper, _ := f.Object(cmd)
_, kind, err := api.Scheme.ObjectVersionAndKind(obj)
if err != nil {
return err
}
mapping, err := mapper.RESTMapping(kind)
if err != nil {
return err
}
printer, err := PrinterForMapping(f, cmd, mapping)
if err != nil {
return err
}
return printer.PrintObj(obj, out)
}
// outputVersion returns the preferred output version for generic content (JSON, YAML, or templates)
func outputVersion(cmd *cobra.Command, defaultVersion string) string {
// OutputVersion returns the preferred output version for generic content (JSON, YAML, or templates)
func OutputVersion(cmd *cobra.Command, defaultVersion string) string {
outputVersion := GetFlagString(cmd, "output-version")
if len(outputVersion) == 0 {
outputVersion = defaultVersion
@ -75,32 +49,3 @@ func PrinterForCommand(cmd *cobra.Command) (kubectl.ResourcePrinter, bool, error
return kubectl.GetPrinter(outputFormat, templateFile)
}
// PrinterForMapping returns a printer suitable for displaying the provided resource type.
// Requires that printer flags have been added to cmd (see AddPrinterFlags).
func PrinterForMapping(f *Factory, cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.ResourcePrinter, error) {
printer, ok, err := PrinterForCommand(cmd)
if err != nil {
return nil, err
}
if ok {
clientConfig, err := f.ClientConfig(cmd)
checkErr(err)
defaultVersion := clientConfig.Version
version := outputVersion(cmd, defaultVersion)
if len(version) == 0 {
version = mapping.APIVersion
}
if len(version) == 0 {
return nil, fmt.Errorf("you must specify an output-version when using this output format")
}
printer = kubectl.NewVersionedPrinter(printer, mapping.ObjectConvertor, version)
} else {
printer, err = f.Printer(cmd, mapping, GetFlagBool(cmd, "no-headers"))
if err != nil {
return nil, err
}
}
return printer, nil
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
package util
import (
"fmt"

View File

@ -22,6 +22,7 @@ import (
"github.com/spf13/cobra"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
)
func (f *Factory) NewCmdVersion(out io.Writer) *cobra.Command {
@ -29,7 +30,7 @@ func (f *Factory) NewCmdVersion(out io.Writer) *cobra.Command {
Use: "version",
Short: "Print version of client and server",
Run: func(cmd *cobra.Command, args []string) {
if GetFlagBool(cmd, "client") {
if util.GetFlagBool(cmd, "client") {
kubectl.GetClientVersion(out)
return
}