2015-01-17 01:52:27 +00:00
/ *
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
import (
"fmt"
"io"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
2015-02-05 00:14:48 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
2015-01-17 01:52:27 +00:00
"github.com/spf13/cobra"
)
2015-02-20 21:28:43 +00:00
const (
expose_long = ` Take a replicated application and expose it as Kubernetes Service .
2015-03-11 17:22:08 +00:00
2015-03-26 02:35:26 +00:00
Looks up a replication controller or service by name and uses the selector for that resource as the
selector for a new Service on the specified port . `
2015-01-17 01:52:27 +00:00
2015-02-20 21:28:43 +00:00
expose_example = ` // Creates a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000.
$ kubectl expose nginx -- port = 80 -- container - port = 8000
2015-01-17 01:52:27 +00:00
2015-03-26 02:35:26 +00:00
// 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 -- container - port = 8443 -- service - name = nginx - https
2015-02-20 21:28:43 +00:00
// Create a service for a replicated streaming application on port 4100 balancing UDP traffic and named 'video-stream'.
$ kubectl expose streamer -- port = 4100 -- protocol = udp -- service - name = video - stream `
)
2015-02-03 17:59:21 +00:00
2015-02-20 21:28:43 +00:00
func ( f * Factory ) NewCmdExposeService ( out io . Writer ) * cobra . Command {
cmd := & cobra . Command {
2015-03-26 02:35:26 +00:00
Use : "expose RESOURCE NAME --port=port [--protocol=TCP|UDP] [--container-port=number-or-name] [--service-name=name] [--public-ip=ip] [--create-external-load-balancer=bool]" ,
2015-02-20 21:28:43 +00:00
Short : "Take a replicated application and expose it as Kubernetes Service" ,
Long : expose_long ,
Example : expose_example ,
2015-01-17 01:52:27 +00:00
Run : func ( cmd * cobra . Command , args [ ] string ) {
2015-03-09 22:08:16 +00:00
err := RunExpose ( f , out , cmd , args )
2015-03-04 00:24:29 +00:00
util . CheckErr ( err )
2015-01-17 01:52:27 +00:00
} ,
}
2015-02-05 00:14:48 +00:00
util . AddPrinterFlags ( cmd )
2015-02-03 17:59:21 +00:00
cmd . Flags ( ) . String ( "generator" , "service/v1" , "The name of the API generator to use. Default is 'service/v1'." )
cmd . Flags ( ) . String ( "protocol" , "TCP" , "The network protocol for the service to be created. Default is 'tcp'." )
2015-01-17 01:52:27 +00:00
cmd . Flags ( ) . Int ( "port" , - 1 , "The port that the service should serve on. Required." )
2015-02-03 17:59:21 +00:00
cmd . Flags ( ) . Bool ( "create-external-load-balancer" , false , "If true, create an external load balancer for this service. Implementation is cloud provider dependent. Default is 'false'." )
cmd . Flags ( ) . String ( "selector" , "" , "A label selector to use for this service. If empty (the default) infer the selector from the replication controller." )
2015-03-16 21:18:17 +00:00
cmd . Flags ( ) . StringP ( "labels" , "l" , "" , "Labels to apply to the service created by this call." )
2015-02-03 17:59:21 +00:00
cmd . Flags ( ) . Bool ( "dry-run" , false , "If true, only print the object that would be sent, without creating it." )
2015-01-17 01:52:27 +00:00
cmd . Flags ( ) . String ( "container-port" , "" , "Name or number for the port on the container that the service should direct traffic to. Optional." )
2015-02-03 17:59:21 +00:00
cmd . Flags ( ) . String ( "public-ip" , "" , "Name of a public IP address to set for the service. The service will be assigned this IP in addition to its generated service IP." )
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." )
2015-01-27 18:23:28 +00:00
cmd . Flags ( ) . String ( "service-name" , "" , "The name for the newly created service." )
2015-01-17 01:52:27 +00:00
return cmd
}
2015-03-09 22:08:16 +00:00
func RunExpose ( f * Factory , out io . Writer , cmd * cobra . Command , args [ ] string ) error {
2015-03-26 02:35:26 +00:00
var name , resource string
switch l := len ( args ) ; {
case l == 2 :
resource , name = args [ 0 ] , args [ 1 ]
default :
return util . UsageError ( cmd , "the type and name of a resource to expose are required arguments" )
2015-03-09 22:08:16 +00:00
}
2015-03-14 10:45:18 +00:00
namespace , err := f . DefaultNamespace ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2015-03-14 10:45:18 +00:00
client , err := f . Client ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
generatorName := util . GetFlagString ( cmd , "generator" )
generator , found := kubectl . Generators [ generatorName ]
if ! found {
2015-03-26 02:35:26 +00:00
return util . UsageError ( cmd , fmt . Sprintf ( "generator %q not found." , generator ) )
2015-03-09 22:08:16 +00:00
}
if util . GetFlagInt ( cmd , "port" ) < 1 {
return util . UsageError ( cmd , "--port is required and must be a positive integer." )
}
names := generator . ParamNames ( )
params := kubectl . MakeParams ( cmd , names )
if len ( util . GetFlagString ( cmd , "service-name" ) ) == 0 {
2015-03-26 02:35:26 +00:00
params [ "name" ] = name
2015-03-09 22:08:16 +00:00
} else {
params [ "name" ] = util . GetFlagString ( cmd , "service-name" )
}
2015-03-26 02:35:26 +00:00
if s , found := params [ "selector" ] ; ! found || len ( s ) == 0 {
mapper , _ := f . Object ( )
v , k , err := mapper . VersionAndKindForResource ( resource )
if err != nil {
return err
}
mapping , err := mapper . RESTMapping ( k , v )
if err != nil {
return err
}
s , err := f . PodSelectorForResource ( mapping , namespace , name )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2015-03-26 02:35:26 +00:00
params [ "selector" ] = s
2015-03-09 22:08:16 +00:00
}
if util . GetFlagBool ( cmd , "create-external-load-balancer" ) {
params [ "create-external-load-balancer" ] = "true"
}
err = kubectl . ValidateParams ( names , params )
if err != nil {
return err
}
service , err := generator . Generate ( params )
if err != nil {
return err
}
inline := util . GetFlagString ( cmd , "overrides" )
if len ( inline ) > 0 {
service , err = util . Merge ( service , inline , "Service" )
if err != nil {
return err
}
}
// TODO: extract this flag to a central location, when such a location exists.
if ! util . GetFlagBool ( cmd , "dry-run" ) {
service , err = client . Services ( namespace ) . Create ( service . ( * api . Service ) )
if err != nil {
return err
}
}
return f . PrintObject ( cmd , service , out )
}