expose: --dry-run should dump the object
Also make some tests use --dry-run and compare generated objects against expected
This commit is contained in:
@@ -228,12 +228,6 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
|
||||
ClientConfig: func() (*client.Config, error) {
|
||||
return t.ClientConfig, t.Err
|
||||
},
|
||||
CanBeExposed: func(kind string) error {
|
||||
if kind != "ReplicationController" && kind != "Service" && kind != "Pod" {
|
||||
return fmt.Errorf("invalid resource provided: %v, only a replication controller, service or pod is accepted", kind)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Generator: func(name string) (kubectl.Generator, bool) {
|
||||
generator, ok := generators[name]
|
||||
return generator, ok
|
||||
@@ -241,6 +235,7 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
|
||||
}
|
||||
rf := cmdutil.NewFactory(nil)
|
||||
f.PodSelectorForObject = rf.PodSelectorForObject
|
||||
f.CanBeExposed = rf.CanBeExposed
|
||||
return f, t, testapi.Default.Codec()
|
||||
}
|
||||
|
||||
|
@@ -212,26 +212,24 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
||||
}
|
||||
// TODO: extract this flag to a central location, when such a location exists.
|
||||
if cmdutil.GetFlagBool(cmd, "dry-run") {
|
||||
fmt.Fprintln(out, "running in dry-run mode...")
|
||||
} else {
|
||||
// Serialize the configuration into an annotation.
|
||||
if err := kubectl.UpdateApplyAnnotation(info); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Serialize the object with the annotation applied.
|
||||
data, err := info.Mapping.Codec.Encode(info.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
object, err = resource.NewHelper(info.Client, info.Mapping).Create(namespace, false, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return f.PrintObject(cmd, object, out)
|
||||
}
|
||||
outputFormat := cmdutil.GetFlagString(cmd, "output")
|
||||
if outputFormat != "" {
|
||||
// Serialize the configuration into an annotation.
|
||||
if err := kubectl.UpdateApplyAnnotation(info); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Serialize the object with the annotation applied.
|
||||
data, err := info.Mapping.Codec.Encode(object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
object, err = resource.NewHelper(info.Client, info.Mapping).Create(namespace, false, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
|
||||
return f.PrintObject(cmd, object, out)
|
||||
}
|
||||
cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, "exposed")
|
||||
|
@@ -23,8 +23,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/fake"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
)
|
||||
@@ -149,7 +149,7 @@ func TestRunExposeService(t *testing.T) {
|
||||
Selector: map[string]string{"app": "go"},
|
||||
},
|
||||
},
|
||||
flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "create-external-load-balancer": "true"},
|
||||
flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "type": "LoadBalancer", "dry-run": "true"},
|
||||
output: &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "", Labels: map[string]string{"svc": "test"}},
|
||||
Spec: api.ServiceSpec{
|
||||
@@ -164,8 +164,7 @@ func TestRunExposeService(t *testing.T) {
|
||||
Type: api.ServiceTypeLoadBalancer,
|
||||
},
|
||||
},
|
||||
expected: "service \"foo\" exposed",
|
||||
status: 200,
|
||||
status: 200,
|
||||
},
|
||||
{
|
||||
name: "expose-affinity-service",
|
||||
@@ -181,7 +180,7 @@ func TestRunExposeService(t *testing.T) {
|
||||
Selector: map[string]string{"app": "go"},
|
||||
},
|
||||
},
|
||||
flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "create-external-load-balancer": "true", "session-affinity": "ClientIP"},
|
||||
flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "type": "LoadBalancer", "session-affinity": "ClientIP", "dry-run": "true"},
|
||||
output: &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "", Labels: map[string]string{"svc": "test"}},
|
||||
Spec: api.ServiceSpec{
|
||||
@@ -197,8 +196,7 @@ func TestRunExposeService(t *testing.T) {
|
||||
SessionAffinity: api.ServiceAffinityClientIP,
|
||||
},
|
||||
},
|
||||
expected: "service \"foo\" exposed",
|
||||
status: 200,
|
||||
status: 200,
|
||||
},
|
||||
{
|
||||
name: "expose-external-service",
|
||||
@@ -215,7 +213,7 @@ func TestRunExposeService(t *testing.T) {
|
||||
},
|
||||
},
|
||||
// Even if we specify --selector, since service/test doesn't need one it will ignore it
|
||||
flags: map[string]string{"selector": "svc=fromexternal", "port": "90", "labels": "svc=fromexternal", "name": "frombaz", "generator": "service/test"},
|
||||
flags: map[string]string{"selector": "svc=fromexternal", "port": "90", "labels": "svc=fromexternal", "name": "frombaz", "generator": "service/test", "dry-run": "true"},
|
||||
output: &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "frombaz", Namespace: "", Labels: map[string]string{"svc": "fromexternal"}},
|
||||
Spec: api.ServiceSpec{
|
||||
@@ -226,11 +224,39 @@ func TestRunExposeService(t *testing.T) {
|
||||
TargetPort: util.NewIntOrStringFromInt(90),
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{"svc": "fromexternal"},
|
||||
},
|
||||
},
|
||||
expected: "service \"frombaz\" exposed",
|
||||
status: 200,
|
||||
status: 200,
|
||||
},
|
||||
{
|
||||
name: "expose-from-file",
|
||||
args: []string{},
|
||||
ns: "test",
|
||||
calls: map[string]string{
|
||||
"GET": "/namespaces/test/services/redis-master",
|
||||
"POST": "/namespaces/test/services",
|
||||
},
|
||||
input: &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "redis-master", Namespace: "test", ResourceVersion: "12"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"app": "go"},
|
||||
},
|
||||
},
|
||||
flags: map[string]string{"filename": "../../../examples/guestbook/redis-master-service.yaml", "selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "dry-run": "true"},
|
||||
output: &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Labels: map[string]string{"svc": "test"}},
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Protocol: api.ProtocolUDP,
|
||||
Port: 14,
|
||||
TargetPort: util.NewIntOrStringFromInt(14),
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{"func": "stream"},
|
||||
},
|
||||
},
|
||||
status: 200,
|
||||
},
|
||||
{
|
||||
name: "truncate-name",
|
||||
@@ -264,7 +290,7 @@ func TestRunExposeService(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
f, tf, codec := NewAPIFactory()
|
||||
tf.Printer = &testPrinter{}
|
||||
tf.Printer = &kubectl.JSONPrinter{}
|
||||
tf.Client = &fake.RESTClient{
|
||||
Codec: codec,
|
||||
Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
|
||||
@@ -289,82 +315,19 @@ func TestRunExposeService(t *testing.T) {
|
||||
}
|
||||
cmd.Run(cmd, test.args)
|
||||
|
||||
out, expectedOut := buf.String(), test.expected
|
||||
if !strings.Contains(out, expectedOut) {
|
||||
t.Errorf("%s: Unexpected output! Expected\n%s\ngot\n%s", test.name, expectedOut, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunExposeServiceFromFile(t *testing.T) {
|
||||
test := struct {
|
||||
calls map[string]string
|
||||
input runtime.Object
|
||||
flags map[string]string
|
||||
output runtime.Object
|
||||
expected string
|
||||
status int
|
||||
}{
|
||||
calls: map[string]string{
|
||||
"GET": "/namespaces/test/services/redis-master",
|
||||
"POST": "/namespaces/test/services",
|
||||
},
|
||||
input: &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
|
||||
TypeMeta: unversioned.TypeMeta{Kind: "Service", APIVersion: "v1"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"app": "go"},
|
||||
},
|
||||
},
|
||||
flags: map[string]string{"selector": "func=stream", "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: unversioned.TypeMeta{Kind: "Service", APIVersion: "v1"},
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Name: "default",
|
||||
Protocol: api.Protocol("UDP"),
|
||||
Port: 14,
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{"func": "stream"},
|
||||
},
|
||||
},
|
||||
status: 200,
|
||||
}
|
||||
|
||||
f, tf, codec := NewAPIFactory()
|
||||
tf.Printer = &testPrinter{}
|
||||
tf.Client = &fake.RESTClient{
|
||||
Codec: codec,
|
||||
Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
|
||||
switch p, m := req.URL.Path, req.Method; {
|
||||
case p == test.calls[m] && m == "GET":
|
||||
return &http.Response{StatusCode: test.status, Body: objBody(codec, test.input)}, nil
|
||||
case p == test.calls[m] && m == "POST":
|
||||
return &http.Response{StatusCode: test.status, Body: objBody(codec, test.output)}, nil
|
||||
default:
|
||||
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
|
||||
return nil, nil
|
||||
}
|
||||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
|
||||
cmd := NewCmdExposeService(f, buf)
|
||||
cmd.SetOutput(buf)
|
||||
|
||||
for flag, value := range test.flags {
|
||||
cmd.Flags().Set(flag, value)
|
||||
}
|
||||
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-service.yaml")
|
||||
cmd.Run(cmd, []string{})
|
||||
if len(test.expected) > 0 {
|
||||
out := buf.String()
|
||||
if _, ok := test.flags["dry-run"]; ok {
|
||||
buf.Reset()
|
||||
if err := tf.Printer.PrintObj(test.output, buf); err != nil {
|
||||
t.Errorf("%s: Unexpected error: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
test.expected = buf.String()
|
||||
}
|
||||
|
||||
if !strings.Contains(out, test.expected) {
|
||||
t.Errorf("unexpected output: %s", out)
|
||||
t.Errorf("%s: Unexpected output! Expected\n%s\ngot\n%s", test.name, test.expected, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user