mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Add optional arguments to kubectl run ...
This commit is contained in:
		@@ -630,6 +630,7 @@ _kubectl_run()
 | 
			
		||||
    flags_completion=()
 | 
			
		||||
 | 
			
		||||
    flags+=("--attach")
 | 
			
		||||
    flags+=("--command")
 | 
			
		||||
    flags+=("--dry-run")
 | 
			
		||||
    flags+=("--generator=")
 | 
			
		||||
    flags+=("--help")
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,10 @@ Creates a replication controller to manage the created container(s).
 | 
			
		||||
\fB\-\-attach\fP=false
 | 
			
		||||
    If true, wait for the Pod to start running, and then attach to the Pod as if 'kubectl attach ...' were called.  Default false, unless '\-i/\-\-interactive' is set, in which case the default is true.
 | 
			
		||||
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-\-command\fP=false
 | 
			
		||||
    If true and extra arguments are present, use them as the 'command' field in the container, rather than the 'args' field which is the default.
 | 
			
		||||
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-\-dry\-run\fP=false
 | 
			
		||||
    If true, only print the object that would be sent, without sending it.
 | 
			
		||||
@@ -207,6 +211,15 @@ $ kubectl run nginx \-\-image=nginx \-\-dry\-run
 | 
			
		||||
# Start a single instance of nginx, but overload the spec of the replication controller with a partial set of values parsed from JSON.
 | 
			
		||||
$ kubectl run nginx \-\-image=nginx \-\-overrides='{ "apiVersion": "v1", "spec": { ... } }'
 | 
			
		||||
 | 
			
		||||
# Start a single instance of nginx and keep it in the foreground, don't restart it if it exits.
 | 
			
		||||
$ kubectl run \-i \-tty nginx \-\-image=nginx \-\-restart=Never
 | 
			
		||||
 | 
			
		||||
# Start the nginx container using the default command, but use custom arguments (arg1 .. argN) for that command.
 | 
			
		||||
$ kubectl run nginx \-\-image=nginx \-\- <arg1> <arg2> ... <argN>
 | 
			
		||||
 | 
			
		||||
# Start the nginx container using a different command and custom arguments
 | 
			
		||||
$ kubectl run nginx \-\-image=nginx \-\-command \-\- <cmd> <arg1> ... <argN>
 | 
			
		||||
 | 
			
		||||
.fi
 | 
			
		||||
.RE
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -59,12 +59,22 @@ $ kubectl run nginx --image=nginx --dry-run
 | 
			
		||||
 | 
			
		||||
# Start a single instance of nginx, but overload the spec of the replication controller with a partial set of values parsed from JSON.
 | 
			
		||||
$ kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { ... } }'
 | 
			
		||||
 | 
			
		||||
# Start a single instance of nginx and keep it in the foreground, don't restart it if it exits.
 | 
			
		||||
$ kubectl run -i -tty nginx --image=nginx --restart=Never
 | 
			
		||||
 | 
			
		||||
# Start the nginx container using the default command, but use custom arguments (arg1 .. argN) for that command.
 | 
			
		||||
$ kubectl run nginx --image=nginx -- <arg1> <arg2> ... <argN>
 | 
			
		||||
 | 
			
		||||
# Start the nginx container using a different command and custom arguments
 | 
			
		||||
$ kubectl run nginx --image=nginx --command -- <cmd> <arg1> ... <argN>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Options
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
      --attach[=false]: If true, wait for the Pod to start running, and then attach to the Pod as if 'kubectl attach ...' were called.  Default false, unless '-i/--interactive' is set, in which case the default is true.
 | 
			
		||||
      --command[=false]: If true and extra arguments are present, use them as the 'command' field in the container, rather than the 'args' field which is the default.
 | 
			
		||||
      --dry-run[=false]: If true, only print the object that would be sent, without sending it.
 | 
			
		||||
      --generator="": The name of the API generator to use.  Default is 'run/v1' if --restart=Always, otherwise the default is 'run-pod/v1'.
 | 
			
		||||
  -h, --help[=false]: help for run
 | 
			
		||||
@@ -117,7 +127,7 @@ $ kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { .
 | 
			
		||||
 | 
			
		||||
* [kubectl](kubectl.md)	 - kubectl controls the Kubernetes cluster manager
 | 
			
		||||
 | 
			
		||||
###### Auto generated by spf13/cobra at 2015-08-12 23:41:01.307766241 +0000 UTC
 | 
			
		||||
###### Auto generated by spf13/cobra at 2015-08-13 16:41:44.465440991 +0000 UTC
 | 
			
		||||
 | 
			
		||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
 | 
			
		||||
[]()
 | 
			
		||||
 
 | 
			
		||||
@@ -127,8 +127,8 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
 | 
			
		||||
	names := generator.ParamNames()
 | 
			
		||||
	params := kubectl.MakeParams(cmd, names)
 | 
			
		||||
	params["default-name"] = info.Name
 | 
			
		||||
	if s, found := params["selector"]; !found || len(s) == 0 || cmdutil.GetFlagInt(cmd, "port") < 1 {
 | 
			
		||||
		if len(s) == 0 {
 | 
			
		||||
	if s, found := params["selector"]; !found || kubectl.IsZero(s) || cmdutil.GetFlagInt(cmd, "port") < 1 {
 | 
			
		||||
		if kubectl.IsZero(s) {
 | 
			
		||||
			s, err := f.PodSelectorForObject(inputObject)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return cmdutil.UsageError(cmd, fmt.Sprintf("couldn't find selectors via --selector flag or introspection: %s", err))
 | 
			
		||||
@@ -160,7 +160,7 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
 | 
			
		||||
	if cmdutil.GetFlagBool(cmd, "create-external-load-balancer") {
 | 
			
		||||
		params["create-external-load-balancer"] = "true"
 | 
			
		||||
	}
 | 
			
		||||
	if len(params["labels"]) == 0 {
 | 
			
		||||
	if kubectl.IsZero(params["labels"]) {
 | 
			
		||||
		labels, err := f.LabelsForObject(inputObject)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
 
 | 
			
		||||
@@ -30,16 +30,50 @@ import (
 | 
			
		||||
 | 
			
		||||
func TestRunExposeService(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name     string
 | 
			
		||||
		args     []string
 | 
			
		||||
		ns       string
 | 
			
		||||
		calls    map[string]string
 | 
			
		||||
		input    runtime.Object
 | 
			
		||||
		flags    map[string]string
 | 
			
		||||
		output   runtime.Object
 | 
			
		||||
		expected string
 | 
			
		||||
		status   int
 | 
			
		||||
		name        string
 | 
			
		||||
		args        []string
 | 
			
		||||
		ns          string
 | 
			
		||||
		calls       map[string]string
 | 
			
		||||
		input       runtime.Object
 | 
			
		||||
		flags       map[string]string
 | 
			
		||||
		output      runtime.Object
 | 
			
		||||
		expected    string
 | 
			
		||||
		status      int
 | 
			
		||||
		podSelector string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "expose-service-from-service-no-selector",
 | 
			
		||||
			args: []string{"service", "baz"},
 | 
			
		||||
			ns:   "test",
 | 
			
		||||
			calls: map[string]string{
 | 
			
		||||
				"GET":  "/namespaces/test/services/baz",
 | 
			
		||||
				"POST": "/namespaces/test/services",
 | 
			
		||||
			},
 | 
			
		||||
			input: &api.Service{
 | 
			
		||||
				ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
 | 
			
		||||
				TypeMeta:   api.TypeMeta{Kind: "Service", APIVersion: "v1"},
 | 
			
		||||
				Spec: api.ServiceSpec{
 | 
			
		||||
					Selector: map[string]string{"app": "go"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			podSelector: "app=go",
 | 
			
		||||
			flags:       map[string]string{"protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test"},
 | 
			
		||||
			output: &api.Service{
 | 
			
		||||
				ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "12", Labels: map[string]string{"svc": "test"}},
 | 
			
		||||
				TypeMeta:   api.TypeMeta{Kind: "Service", APIVersion: "v1"},
 | 
			
		||||
				Spec: api.ServiceSpec{
 | 
			
		||||
					Ports: []api.ServicePort{
 | 
			
		||||
						{
 | 
			
		||||
							Name:     "default",
 | 
			
		||||
							Protocol: api.Protocol("UDP"),
 | 
			
		||||
							Port:     14,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
					Selector: map[string]string{"app": "go"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			status: 200,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "expose-service-from-service",
 | 
			
		||||
			args: []string{"service", "baz"},
 | 
			
		||||
@@ -194,6 +228,8 @@ func TestRunExposeService(t *testing.T) {
 | 
			
		||||
			}),
 | 
			
		||||
		}
 | 
			
		||||
		tf.Namespace = test.ns
 | 
			
		||||
		f.PodSelectorForObject = func(obj runtime.Object) (string, error) { return test.podSelector, nil }
 | 
			
		||||
 | 
			
		||||
		buf := bytes.NewBuffer([]byte{})
 | 
			
		||||
 | 
			
		||||
		cmd := NewCmdExposeService(f, buf)
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,16 @@ $ kubectl run nginx --image=nginx --replicas=5
 | 
			
		||||
$ kubectl run nginx --image=nginx --dry-run
 | 
			
		||||
 | 
			
		||||
# Start a single instance of nginx, but overload the spec of the replication controller with a partial set of values parsed from JSON.
 | 
			
		||||
$ kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { ... } }'`
 | 
			
		||||
$ kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { ... } }'
 | 
			
		||||
 | 
			
		||||
# Start a single instance of nginx and keep it in the foreground, don't restart it if it exits.
 | 
			
		||||
$ kubectl run -i -tty nginx --image=nginx --restart=Never
 | 
			
		||||
 | 
			
		||||
# Start the nginx container using the default command, but use custom arguments (arg1 .. argN) for that command.
 | 
			
		||||
$ kubectl run nginx --image=nginx -- <arg1> <arg2> ... <argN>
 | 
			
		||||
 | 
			
		||||
# Start the nginx container using a different command and custom arguments
 | 
			
		||||
$ kubectl run nginx --image=nginx --command -- <cmd> <arg1> ... <argN>`
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func NewCmdRun(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {
 | 
			
		||||
@@ -74,6 +83,7 @@ func NewCmdRun(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *c
 | 
			
		||||
	cmd.Flags().Bool("tty", false, "Allocated a TTY for each container in the pod.  Because -t is currently shorthand for --template, -t is not supported for --tty. This shorthand is deprecated and we expect to adopt -t for --tty soon.")
 | 
			
		||||
	cmd.Flags().Bool("attach", false, "If true, wait for the Pod to start running, and then attach to the Pod as if 'kubectl attach ...' were called.  Default false, unless '-i/--interactive' is set, in which case the default is true.")
 | 
			
		||||
	cmd.Flags().String("restart", "Always", "The restart policy for this Pod.  Legal values [Always, OnFailure, Never].  If set to 'Always' a replication controller is created for this pod, if set to OnFailure or Never, only the Pod is created and --replicas must be 1.  Default 'Always'")
 | 
			
		||||
	cmd.Flags().Bool("command", false, "If true and extra arguments are present, use them as the 'command' field in the container, rather than the 'args' field which is the default.")
 | 
			
		||||
	return cmd
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -82,7 +92,7 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob
 | 
			
		||||
		printDeprecationWarning("run", "run-container")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(args) != 1 {
 | 
			
		||||
	if len(args) == 0 {
 | 
			
		||||
		return cmdutil.UsageError(cmd, "NAME is required for run")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -128,7 +138,9 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob
 | 
			
		||||
	names := generator.ParamNames()
 | 
			
		||||
	params := kubectl.MakeParams(cmd, names)
 | 
			
		||||
	params["name"] = args[0]
 | 
			
		||||
 | 
			
		||||
	if len(args) > 1 {
 | 
			
		||||
		params["args"] = args[1:]
 | 
			
		||||
	}
 | 
			
		||||
	err = kubectl.ValidateParams(names, params)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ package kubectl
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
@@ -35,17 +36,24 @@ type GeneratorParam struct {
 | 
			
		||||
// Generator is an interface for things that can generate API objects from input parameters.
 | 
			
		||||
type Generator interface {
 | 
			
		||||
	// Generate creates an API object given a set of parameters
 | 
			
		||||
	Generate(params map[string]string) (runtime.Object, error)
 | 
			
		||||
	Generate(params map[string]interface{}) (runtime.Object, error)
 | 
			
		||||
	// ParamNames returns the list of parameters that this generator uses
 | 
			
		||||
	ParamNames() []GeneratorParam
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsZero(i interface{}) bool {
 | 
			
		||||
	if i == nil {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ValidateParams ensures that all required params are present in the params map
 | 
			
		||||
func ValidateParams(paramSpec []GeneratorParam, params map[string]string) error {
 | 
			
		||||
func ValidateParams(paramSpec []GeneratorParam, params map[string]interface{}) error {
 | 
			
		||||
	for ix := range paramSpec {
 | 
			
		||||
		if paramSpec[ix].Required {
 | 
			
		||||
			value, found := params[paramSpec[ix].Name]
 | 
			
		||||
			if !found || len(value) == 0 {
 | 
			
		||||
			if !found || IsZero(value) {
 | 
			
		||||
				return fmt.Errorf("Parameter: %s is required", paramSpec[ix].Name)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -54,8 +62,8 @@ func ValidateParams(paramSpec []GeneratorParam, params map[string]string) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MakeParams is a utility that creates generator parameters from a command line
 | 
			
		||||
func MakeParams(cmd *cobra.Command, params []GeneratorParam) map[string]string {
 | 
			
		||||
	result := map[string]string{}
 | 
			
		||||
func MakeParams(cmd *cobra.Command, params []GeneratorParam) map[string]interface{} {
 | 
			
		||||
	result := map[string]interface{}{}
 | 
			
		||||
	for ix := range params {
 | 
			
		||||
		f := cmd.Flags().Lookup(params[ix].Name)
 | 
			
		||||
		if f != nil {
 | 
			
		||||
@@ -74,7 +82,11 @@ func MakeLabels(labels map[string]string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseLabels turns a string representation of a label set into a map[string]string
 | 
			
		||||
func ParseLabels(labelString string) (map[string]string, error) {
 | 
			
		||||
func ParseLabels(labelSpec interface{}) (map[string]string, error) {
 | 
			
		||||
	labelString, isString := labelSpec.(string)
 | 
			
		||||
	if !isString {
 | 
			
		||||
		return nil, fmt.Errorf("expected string, found %v", labelSpec)
 | 
			
		||||
	}
 | 
			
		||||
	if len(labelString) == 0 {
 | 
			
		||||
		return nil, fmt.Errorf("no label spec passed")
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,29 +23,55 @@ import (
 | 
			
		||||
	"github.com/spf13/cobra"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type TestStruct struct {
 | 
			
		||||
	val int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestIsZero(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		val        interface{}
 | 
			
		||||
		expectZero bool
 | 
			
		||||
	}{
 | 
			
		||||
		{"", true},
 | 
			
		||||
		{nil, true},
 | 
			
		||||
		{0, true},
 | 
			
		||||
		{TestStruct{}, true},
 | 
			
		||||
		{"foo", false},
 | 
			
		||||
		{1, false},
 | 
			
		||||
		{TestStruct{val: 2}, false},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, test := range tests {
 | 
			
		||||
		output := IsZero(test.val)
 | 
			
		||||
		if output != test.expectZero {
 | 
			
		||||
			t.Errorf("expected: %v, saw %v", test.expectZero, output)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestValidateParams(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		paramSpec []GeneratorParam
 | 
			
		||||
		params    map[string]string
 | 
			
		||||
		params    map[string]interface{}
 | 
			
		||||
		valid     bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			paramSpec: []GeneratorParam{},
 | 
			
		||||
			params:    map[string]string{},
 | 
			
		||||
			params:    map[string]interface{}{},
 | 
			
		||||
			valid:     true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			paramSpec: []GeneratorParam{
 | 
			
		||||
				{Name: "foo"},
 | 
			
		||||
			},
 | 
			
		||||
			params: map[string]string{},
 | 
			
		||||
			params: map[string]interface{}{},
 | 
			
		||||
			valid:  true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			paramSpec: []GeneratorParam{
 | 
			
		||||
				{Name: "foo", Required: true},
 | 
			
		||||
			},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"foo": "bar",
 | 
			
		||||
			},
 | 
			
		||||
			valid: true,
 | 
			
		||||
@@ -54,7 +80,7 @@ func TestValidateParams(t *testing.T) {
 | 
			
		||||
			paramSpec: []GeneratorParam{
 | 
			
		||||
				{Name: "foo", Required: true},
 | 
			
		||||
			},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"baz": "blah",
 | 
			
		||||
				"foo": "bar",
 | 
			
		||||
			},
 | 
			
		||||
@@ -65,7 +91,7 @@ func TestValidateParams(t *testing.T) {
 | 
			
		||||
				{Name: "foo", Required: true},
 | 
			
		||||
				{Name: "baz", Required: true},
 | 
			
		||||
			},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"baz": "blah",
 | 
			
		||||
				"foo": "bar",
 | 
			
		||||
			},
 | 
			
		||||
@@ -76,7 +102,7 @@ func TestValidateParams(t *testing.T) {
 | 
			
		||||
				{Name: "foo", Required: true},
 | 
			
		||||
				{Name: "baz", Required: true},
 | 
			
		||||
			},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"foo": "bar",
 | 
			
		||||
			},
 | 
			
		||||
			valid: false,
 | 
			
		||||
@@ -103,7 +129,7 @@ func TestMakeParams(t *testing.T) {
 | 
			
		||||
		{Name: "foo", Required: true},
 | 
			
		||||
		{Name: "baz", Required: true},
 | 
			
		||||
	}
 | 
			
		||||
	expected := map[string]string{
 | 
			
		||||
	expected := map[string]interface{}{
 | 
			
		||||
		"foo": "bar",
 | 
			
		||||
		"baz": "blah",
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,8 @@ func (BasicReplicationController) ParamNames() []GeneratorParam {
 | 
			
		||||
		{"hostport", false},
 | 
			
		||||
		{"stdin", false},
 | 
			
		||||
		{"tty", false},
 | 
			
		||||
		{"command", false},
 | 
			
		||||
		{"args", false},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -64,7 +66,25 @@ func makePodSpec(params map[string]string, name string) (*api.PodSpec, error) {
 | 
			
		||||
	return &spec, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (BasicReplicationController) Generate(params map[string]string) (runtime.Object, error) {
 | 
			
		||||
func (BasicReplicationController) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
 | 
			
		||||
	args := []string{}
 | 
			
		||||
	val, found := genericParams["args"]
 | 
			
		||||
	if found {
 | 
			
		||||
		var isArray bool
 | 
			
		||||
		args, isArray = val.([]string)
 | 
			
		||||
		if !isArray {
 | 
			
		||||
			return nil, fmt.Errorf("expected []string, found: %v", val)
 | 
			
		||||
		}
 | 
			
		||||
		delete(genericParams, "args")
 | 
			
		||||
	}
 | 
			
		||||
	params := map[string]string{}
 | 
			
		||||
	for key, value := range genericParams {
 | 
			
		||||
		strVal, isString := value.(string)
 | 
			
		||||
		if !isString {
 | 
			
		||||
			return nil, fmt.Errorf("expected string, saw %v for '%s'", value, key)
 | 
			
		||||
		}
 | 
			
		||||
		params[key] = strVal
 | 
			
		||||
	}
 | 
			
		||||
	name, found := params["name"]
 | 
			
		||||
	if !found || len(name) == 0 {
 | 
			
		||||
		name, found = params["default-name"]
 | 
			
		||||
@@ -95,6 +115,18 @@ func (BasicReplicationController) Generate(params map[string]string) (runtime.Ob
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if len(args) > 0 {
 | 
			
		||||
		command, err := GetBool(params, "command", false)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		if command {
 | 
			
		||||
			podSpec.Containers[0].Command = args
 | 
			
		||||
		} else {
 | 
			
		||||
			podSpec.Containers[0].Args = args
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	controller := api.ReplicationController{
 | 
			
		||||
		ObjectMeta: api.ObjectMeta{
 | 
			
		||||
			Name:   name,
 | 
			
		||||
@@ -164,10 +196,30 @@ func (BasicPod) ParamNames() []GeneratorParam {
 | 
			
		||||
		{"stdin", false},
 | 
			
		||||
		{"tty", false},
 | 
			
		||||
		{"restart", false},
 | 
			
		||||
		{"command", false},
 | 
			
		||||
		{"args", false},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (BasicPod) Generate(params map[string]string) (runtime.Object, error) {
 | 
			
		||||
func (BasicPod) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
 | 
			
		||||
	args := []string{}
 | 
			
		||||
	val, found := genericParams["args"]
 | 
			
		||||
	if found {
 | 
			
		||||
		var isArray bool
 | 
			
		||||
		args, isArray = val.([]string)
 | 
			
		||||
		if !isArray {
 | 
			
		||||
			return nil, fmt.Errorf("expected []string, found: %v", val)
 | 
			
		||||
		}
 | 
			
		||||
		delete(genericParams, "args")
 | 
			
		||||
	}
 | 
			
		||||
	params := map[string]string{}
 | 
			
		||||
	for key, value := range genericParams {
 | 
			
		||||
		strVal, isString := value.(string)
 | 
			
		||||
		if !isString {
 | 
			
		||||
			return nil, fmt.Errorf("expected string, saw %v for '%s'", value, key)
 | 
			
		||||
		}
 | 
			
		||||
		params[key] = strVal
 | 
			
		||||
	}
 | 
			
		||||
	name, found := params["name"]
 | 
			
		||||
	if !found || len(name) == 0 {
 | 
			
		||||
		name, found = params["default-name"]
 | 
			
		||||
@@ -218,6 +270,17 @@ func (BasicPod) Generate(params map[string]string) (runtime.Object, error) {
 | 
			
		||||
			RestartPolicy: restartPolicy,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	if len(args) > 0 {
 | 
			
		||||
		command, err := GetBool(params, "command", false)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		if command {
 | 
			
		||||
			pod.Spec.Containers[0].Command = args
 | 
			
		||||
		} else {
 | 
			
		||||
			pod.Spec.Containers[0].Args = args
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if err := updatePodPorts(params, &pod.Spec); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,12 +25,12 @@ import (
 | 
			
		||||
 | 
			
		||||
func TestGenerate(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		params    map[string]string
 | 
			
		||||
		params    map[string]interface{}
 | 
			
		||||
		expected  *api.ReplicationController
 | 
			
		||||
		expectErr bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":     "foo",
 | 
			
		||||
				"image":    "someimage",
 | 
			
		||||
				"replicas": "1",
 | 
			
		||||
@@ -61,7 +61,74 @@ func TestGenerate(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":     "foo",
 | 
			
		||||
				"image":    "someimage",
 | 
			
		||||
				"replicas": "1",
 | 
			
		||||
				"port":     "-1",
 | 
			
		||||
				"args":     []string{"bar", "baz", "blah"},
 | 
			
		||||
			},
 | 
			
		||||
			expected: &api.ReplicationController{
 | 
			
		||||
				ObjectMeta: api.ObjectMeta{
 | 
			
		||||
					Name:   "foo",
 | 
			
		||||
					Labels: map[string]string{"run": "foo"},
 | 
			
		||||
				},
 | 
			
		||||
				Spec: api.ReplicationControllerSpec{
 | 
			
		||||
					Replicas: 1,
 | 
			
		||||
					Selector: map[string]string{"run": "foo"},
 | 
			
		||||
					Template: &api.PodTemplateSpec{
 | 
			
		||||
						ObjectMeta: api.ObjectMeta{
 | 
			
		||||
							Labels: map[string]string{"run": "foo"},
 | 
			
		||||
						},
 | 
			
		||||
						Spec: api.PodSpec{
 | 
			
		||||
							Containers: []api.Container{
 | 
			
		||||
								{
 | 
			
		||||
									Name:  "foo",
 | 
			
		||||
									Image: "someimage",
 | 
			
		||||
									Args:  []string{"bar", "baz", "blah"},
 | 
			
		||||
								},
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":     "foo",
 | 
			
		||||
				"image":    "someimage",
 | 
			
		||||
				"replicas": "1",
 | 
			
		||||
				"port":     "-1",
 | 
			
		||||
				"args":     []string{"bar", "baz", "blah"},
 | 
			
		||||
				"command":  "true",
 | 
			
		||||
			},
 | 
			
		||||
			expected: &api.ReplicationController{
 | 
			
		||||
				ObjectMeta: api.ObjectMeta{
 | 
			
		||||
					Name:   "foo",
 | 
			
		||||
					Labels: map[string]string{"run": "foo"},
 | 
			
		||||
				},
 | 
			
		||||
				Spec: api.ReplicationControllerSpec{
 | 
			
		||||
					Replicas: 1,
 | 
			
		||||
					Selector: map[string]string{"run": "foo"},
 | 
			
		||||
					Template: &api.PodTemplateSpec{
 | 
			
		||||
						ObjectMeta: api.ObjectMeta{
 | 
			
		||||
							Labels: map[string]string{"run": "foo"},
 | 
			
		||||
						},
 | 
			
		||||
						Spec: api.PodSpec{
 | 
			
		||||
							Containers: []api.Container{
 | 
			
		||||
								{
 | 
			
		||||
									Name:    "foo",
 | 
			
		||||
									Image:   "someimage",
 | 
			
		||||
									Command: []string{"bar", "baz", "blah"},
 | 
			
		||||
								},
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":     "foo",
 | 
			
		||||
				"image":    "someimage",
 | 
			
		||||
				"replicas": "1",
 | 
			
		||||
@@ -97,7 +164,7 @@ func TestGenerate(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":     "foo",
 | 
			
		||||
				"image":    "someimage",
 | 
			
		||||
				"replicas": "1",
 | 
			
		||||
@@ -135,7 +202,7 @@ func TestGenerate(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":     "foo",
 | 
			
		||||
				"image":    "someimage",
 | 
			
		||||
				"replicas": "1",
 | 
			
		||||
@@ -145,7 +212,7 @@ func TestGenerate(t *testing.T) {
 | 
			
		||||
			expectErr: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":     "foo",
 | 
			
		||||
				"image":    "someimage",
 | 
			
		||||
				"replicas": "1",
 | 
			
		||||
@@ -193,12 +260,12 @@ func TestGenerate(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
func TestGeneratePod(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		params    map[string]string
 | 
			
		||||
		params    map[string]interface{}
 | 
			
		||||
		expected  *api.Pod
 | 
			
		||||
		expectErr bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":  "foo",
 | 
			
		||||
				"image": "someimage",
 | 
			
		||||
				"port":  "-1",
 | 
			
		||||
@@ -221,7 +288,7 @@ func TestGeneratePod(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":  "foo",
 | 
			
		||||
				"image": "someimage",
 | 
			
		||||
				"port":  "80",
 | 
			
		||||
@@ -249,7 +316,7 @@ func TestGeneratePod(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":     "foo",
 | 
			
		||||
				"image":    "someimage",
 | 
			
		||||
				"port":     "80",
 | 
			
		||||
@@ -279,7 +346,7 @@ func TestGeneratePod(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":     "foo",
 | 
			
		||||
				"image":    "someimage",
 | 
			
		||||
				"hostport": "80",
 | 
			
		||||
@@ -288,7 +355,7 @@ func TestGeneratePod(t *testing.T) {
 | 
			
		||||
			expectErr: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"name":     "foo",
 | 
			
		||||
				"image":    "someimage",
 | 
			
		||||
				"replicas": "1",
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ func (ServiceGeneratorV1) ParamNames() []GeneratorParam {
 | 
			
		||||
	return paramNames()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ServiceGeneratorV1) Generate(params map[string]string) (runtime.Object, error) {
 | 
			
		||||
func (ServiceGeneratorV1) Generate(params map[string]interface{}) (runtime.Object, error) {
 | 
			
		||||
	params["port-name"] = "default"
 | 
			
		||||
	return generate(params)
 | 
			
		||||
}
 | 
			
		||||
@@ -43,7 +43,7 @@ func (ServiceGeneratorV2) ParamNames() []GeneratorParam {
 | 
			
		||||
	return paramNames()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ServiceGeneratorV2) Generate(params map[string]string) (runtime.Object, error) {
 | 
			
		||||
func (ServiceGeneratorV2) Generate(params map[string]interface{}) (runtime.Object, error) {
 | 
			
		||||
	return generate(params)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -65,7 +65,15 @@ func paramNames() []GeneratorParam {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func generate(params map[string]string) (runtime.Object, error) {
 | 
			
		||||
func generate(genericParams map[string]interface{}) (runtime.Object, error) {
 | 
			
		||||
	params := map[string]string{}
 | 
			
		||||
	for key, value := range genericParams {
 | 
			
		||||
		strVal, isString := value.(string)
 | 
			
		||||
		if !isString {
 | 
			
		||||
			return nil, fmt.Errorf("expected string, saw %v for '%s'", value, key)
 | 
			
		||||
		}
 | 
			
		||||
		params[key] = strVal
 | 
			
		||||
	}
 | 
			
		||||
	selectorString, found := params["selector"]
 | 
			
		||||
	if !found || len(selectorString) == 0 {
 | 
			
		||||
		return nil, fmt.Errorf("'selector' is a required parameter.")
 | 
			
		||||
 
 | 
			
		||||
@@ -27,12 +27,12 @@ import (
 | 
			
		||||
func TestGenerateService(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		generator Generator
 | 
			
		||||
		params    map[string]string
 | 
			
		||||
		params    map[string]interface{}
 | 
			
		||||
		expected  api.Service
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			generator: ServiceGeneratorV2{},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"selector":       "foo=bar,baz=blah",
 | 
			
		||||
				"name":           "test",
 | 
			
		||||
				"port":           "80",
 | 
			
		||||
@@ -61,7 +61,7 @@ func TestGenerateService(t *testing.T) {
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
			generator: ServiceGeneratorV2{},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"selector":       "foo=bar,baz=blah",
 | 
			
		||||
				"name":           "test",
 | 
			
		||||
				"port":           "80",
 | 
			
		||||
@@ -89,7 +89,7 @@ func TestGenerateService(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			generator: ServiceGeneratorV2{},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"selector":       "foo=bar,baz=blah",
 | 
			
		||||
				"labels":         "key1=value1,key2=value2",
 | 
			
		||||
				"name":           "test",
 | 
			
		||||
@@ -122,7 +122,7 @@ func TestGenerateService(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			generator: ServiceGeneratorV2{},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"selector":       "foo=bar,baz=blah",
 | 
			
		||||
				"name":           "test",
 | 
			
		||||
				"port":           "80",
 | 
			
		||||
@@ -152,7 +152,7 @@ func TestGenerateService(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			generator: ServiceGeneratorV2{},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"selector":                      "foo=bar,baz=blah",
 | 
			
		||||
				"name":                          "test",
 | 
			
		||||
				"port":                          "80",
 | 
			
		||||
@@ -184,7 +184,7 @@ func TestGenerateService(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			generator: ServiceGeneratorV2{},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"selector":       "foo=bar,baz=blah",
 | 
			
		||||
				"name":           "test",
 | 
			
		||||
				"port":           "80",
 | 
			
		||||
@@ -214,7 +214,7 @@ func TestGenerateService(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			generator: ServiceGeneratorV2{},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"selector":                      "foo=bar,baz=blah",
 | 
			
		||||
				"name":                          "test",
 | 
			
		||||
				"port":                          "80",
 | 
			
		||||
@@ -245,7 +245,7 @@ func TestGenerateService(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			generator: ServiceGeneratorV1{},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"selector":       "foo=bar,baz=blah",
 | 
			
		||||
				"name":           "test",
 | 
			
		||||
				"port":           "80",
 | 
			
		||||
@@ -274,7 +274,7 @@ func TestGenerateService(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			generator: ServiceGeneratorV1{},
 | 
			
		||||
			params: map[string]string{
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"selector":         "foo=bar,baz=blah",
 | 
			
		||||
				"name":             "test",
 | 
			
		||||
				"port":             "80",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user