mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Kubectl expose command accepts a filename param
This commit is contained in:
parent
0ded91c521
commit
c0b2098844
@ -700,6 +700,12 @@ _kubectl_expose()
|
||||
flags+=("--container-port=")
|
||||
flags+=("--create-external-load-balancer")
|
||||
flags+=("--dry-run")
|
||||
flags+=("--filename=")
|
||||
flags_with_completion+=("--filename")
|
||||
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
|
||||
two_word_flags+=("-f")
|
||||
flags_with_completion+=("-f")
|
||||
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
|
||||
flags+=("--generator=")
|
||||
flags+=("--help")
|
||||
flags+=("-h")
|
||||
|
@ -34,6 +34,10 @@ re\-use the labels from the resource it exposes.
|
||||
\fB\-\-dry\-run\fP=false
|
||||
If true, only print the object that would be sent, without creating it.
|
||||
|
||||
.PP
|
||||
\fB\-f\fP, \fB\-\-filename\fP=[]
|
||||
Filename, directory, or URL to a file identifying the resource to expose a service
|
||||
|
||||
.PP
|
||||
\fB\-\-generator\fP="service/v2"
|
||||
The name of the API generator to use. There are 2 generators: 'service/v1' and 'service/v2'. The only difference between them is that service port in v1 is named 'default', while it is left unnamed in v2. Default is 'service/v2'.
|
||||
@ -206,6 +210,9 @@ re\-use the labels from the resource it exposes.
|
||||
// Creates a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000.
|
||||
$ kubectl expose rc nginx \-\-port=80 \-\-target\-port=8000
|
||||
|
||||
# Creates a service for a replication controller identified by type and name specified in "nginx\-controller.yaml", which serves on port 80 and connects to the containers on port 8000.
|
||||
$ kubectl expose \-f nginx\-controller.yaml \-\-port=80 \-\-target\-port=8000
|
||||
|
||||
// Creates a second service based on the above service, exposing the container port 8443 as port 443 with the name "nginx\-https"
|
||||
$ kubectl expose service nginx \-\-port=443 \-\-target\-port=8443 \-\-name=nginx\-https
|
||||
|
||||
|
@ -45,7 +45,7 @@ selector for a new Service on the specified port. If no labels are specified, th
|
||||
re-use the labels from the resource it exposes.
|
||||
|
||||
```
|
||||
kubectl expose TYPE NAME --port=port [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [--public-ip=ip] [--type=type]
|
||||
kubectl expose (-f FILENAME | TYPE NAME) --port=port [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [--public-ip=ip] [--type=type]
|
||||
```
|
||||
|
||||
### Examples
|
||||
@ -54,6 +54,9 @@ kubectl expose TYPE NAME --port=port [--protocol=TCP|UDP] [--target-port=number-
|
||||
// Creates a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000.
|
||||
$ kubectl expose rc nginx --port=80 --target-port=8000
|
||||
|
||||
# Creates a service for a replication controller identified by type and name specified in "nginx-controller.yaml", which serves on port 80 and connects to the containers on port 8000.
|
||||
$ kubectl expose -f nginx-controller.yaml --port=80 --target-port=8000
|
||||
|
||||
// Creates a second service based on the above service, exposing the container port 8443 as port 443 with the name "nginx-https"
|
||||
$ kubectl expose service nginx --port=443 --target-port=8443 --name=nginx-https
|
||||
|
||||
@ -67,6 +70,7 @@ $ kubectl expose rc streamer --port=4100 --protocol=udp --name=video-stream
|
||||
--container-port="": Synonym for --target-port
|
||||
--create-external-load-balancer[=false]: If true, create an external load balancer for this service (trumped by --type). Implementation is cloud provider dependent. Default is 'false'.
|
||||
--dry-run[=false]: If true, only print the object that would be sent, without creating it.
|
||||
-f, --filename=[]: Filename, directory, or URL to a file identifying the resource to expose a service
|
||||
--generator="service/v2": The name of the API generator to use. There are 2 generators: 'service/v1' and 'service/v2'. The only difference between them is that service port in v1 is named 'default', while it is left unnamed in v2. Default is 'service/v2'.
|
||||
-h, --help[=false]: help for expose
|
||||
-l, --labels="": Labels to apply to the service created by this call.
|
||||
@ -118,7 +122,7 @@ $ kubectl expose rc streamer --port=4100 --protocol=udp --name=video-stream
|
||||
|
||||
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
||||
|
||||
###### Auto generated by spf13/cobra at 2015-08-07 19:25:02.004335817 +0000 UTC
|
||||
###### Auto generated by spf13/cobra at 2015-08-12 08:16:20.804863501 +0000 UTC
|
||||
|
||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||
[]()
|
||||
|
@ -20,11 +20,11 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -37,6 +37,9 @@ re-use the labels from the resource it exposes.`
|
||||
expose_example = `// Creates a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000.
|
||||
$ kubectl expose rc nginx --port=80 --target-port=8000
|
||||
|
||||
# Creates a service for a replication controller identified by type and name specified in "nginx-controller.yaml", which serves on port 80 and connects to the containers on port 8000.
|
||||
$ kubectl expose -f nginx-controller.yaml --port=80 --target-port=8000
|
||||
|
||||
// Creates a second service based on the above service, exposing the container port 8443 as port 443 with the name "nginx-https"
|
||||
$ kubectl expose service nginx --port=443 --target-port=8443 --name=nginx-https
|
||||
|
||||
@ -46,7 +49,7 @@ $ kubectl expose rc streamer --port=4100 --protocol=udp --name=video-stream`
|
||||
|
||||
func NewCmdExposeService(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "expose TYPE NAME --port=port [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [--public-ip=ip] [--type=type]",
|
||||
Use: "expose (-f FILENAME | TYPE NAME) --port=port [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [--public-ip=ip] [--type=type]",
|
||||
Short: "Take a replicated application and expose it as Kubernetes Service",
|
||||
Long: expose_long,
|
||||
Example: expose_example,
|
||||
@ -71,11 +74,14 @@ func NewCmdExposeService(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmd.Flags().String("overrides", "", "An inline JSON override for the generated object. If this is non-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field.")
|
||||
cmd.Flags().String("name", "", "The name for the newly created object.")
|
||||
cmd.Flags().String("session-affinity", "", "If non-empty, set the session affinity for the service to this; legal values: 'None', 'ClientIP'")
|
||||
|
||||
usage := "Filename, directory, or URL to a file identifying the resource to expose a service"
|
||||
kubectl.AddJsonFilenameFlag(cmd, usage)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
|
||||
namespace, _, err := f.DefaultNamespace()
|
||||
namespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -84,6 +90,7 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
||||
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()).
|
||||
ContinueOnError().
|
||||
NamespaceParam(namespace).DefaultNamespace().
|
||||
FilenameParam(enforceNamespace, cmdutil.GetFlagStringSlice(cmd, "filename")...).
|
||||
ResourceTypeOrNameArgs(false, args...).
|
||||
Flatten().
|
||||
Do()
|
||||
@ -91,10 +98,6 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mapping, err := r.ResourceMapping()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
infos, err := r.Infos()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -103,6 +106,7 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
||||
return fmt.Errorf("multiple resources provided: %v", args)
|
||||
}
|
||||
info := infos[0]
|
||||
mapping := info.ResourceMapping()
|
||||
|
||||
// Get the input object
|
||||
client, err := f.RESTClient(mapping)
|
||||
@ -201,6 +205,5 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return f.PrintObject(cmd, object, out)
|
||||
}
|
||||
|
@ -202,7 +202,6 @@ func TestRunExposeService(t *testing.T) {
|
||||
cmd.Flags().Set(flag, value)
|
||||
}
|
||||
cmd.Run(cmd, test.args)
|
||||
|
||||
if len(test.expected) > 0 {
|
||||
out := buf.String()
|
||||
if !strings.Contains(out, test.expected) {
|
||||
@ -211,3 +210,76 @@ func TestRunExposeService(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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: api.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: api.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 = &client.FakeRESTClient{
|
||||
Codec: codec,
|
||||
Client: client.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 !strings.Contains(out, test.expected) {
|
||||
t.Errorf("unexpected output: %s", out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user