2014-10-05 21:24:19 -04:00
/ *
2016-06-02 20:25:58 -04:00
Copyright 2014 The Kubernetes Authors .
2014-10-05 21:24:19 -04:00
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 .
* /
2018-10-05 07:06:12 -04:00
package proxy
2014-10-05 21:24:19 -04:00
import (
2015-07-01 04:17:53 -04:00
"errors"
2015-03-09 18:08:16 -04:00
"fmt"
2014-10-05 21:24:19 -04:00
"io"
2015-07-01 04:17:53 -04:00
"net"
2017-04-26 05:53:54 -04:00
"os"
2015-02-04 04:31:39 -05:00
"strings"
2014-10-05 21:24:19 -04:00
"github.com/spf13/cobra"
2018-08-21 06:46:39 -04:00
"k8s.io/cli-runtime/pkg/genericclioptions"
2018-11-09 13:49:10 -05:00
"k8s.io/klog"
2015-08-05 18:05:17 -04:00
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
2017-07-12 23:21:03 -04:00
"k8s.io/kubernetes/pkg/kubectl/proxy"
2017-07-07 00:04:11 -04:00
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
2018-10-10 14:29:30 -04:00
"k8s.io/kubernetes/pkg/kubectl/util/templates"
2014-10-05 21:24:19 -04:00
)
2016-05-20 13:49:56 -04:00
var (
2017-02-15 22:47:00 -05:00
defaultPort = 8001
proxyLong = templates . LongDesc ( i18n . T ( `
2018-10-05 07:06:12 -04:00
Creates a proxy server or application - level gateway between localhost and
the Kubernetes API Server . It also allows serving static content over specified
HTTP path . All incoming data enters through one port and gets forwarded to
2017-05-13 18:03:23 -04:00
the remote kubernetes API Server port , except for the path matching the static content path . ` ) )
proxyExample = templates . Examples ( i18n . T ( `
# To proxy all of the kubernetes api and nothing else , use :
2016-10-07 18:24:42 -04:00
$ kubectl proxy -- api - prefix = /
2017-05-13 18:03:23 -04:00
# To proxy only part of the kubernetes api and also some static files :
2016-10-07 18:24:42 -04:00
$ kubectl proxy -- www = / my / files -- www - prefix = / static / -- api - prefix = / api /
2017-05-13 18:03:23 -04:00
# The above lets you ' curl localhost : 8001 / api / v1 / pods ' .
2016-10-07 18:24:42 -04:00
2017-05-13 18:03:23 -04:00
# To proxy the entire kubernetes api at a different root , use :
2016-10-07 18:24:42 -04:00
$ kubectl proxy -- api - prefix = / custom /
2017-05-13 18:03:23 -04:00
# The above lets you ' curl localhost : 8001 / custom / api / v1 / pods '
2016-10-07 18:24:42 -04:00
2016-05-20 13:49:56 -04:00
# Run a proxy to kubernetes apiserver on port 8011 , serving static content from . / local / www /
kubectl proxy -- port = 8011 -- www = . / local / www /
2015-03-11 13:22:08 -04:00
2016-05-20 13:49:56 -04:00
# Run a proxy to kubernetes apiserver on an arbitrary local port .
# The chosen port for the server will be output to stdout .
kubectl proxy -- port = 0
2015-07-07 01:04:39 -04:00
2016-05-20 13:49:56 -04:00
# Run a proxy to kubernetes apiserver , changing the api prefix to k8s - api
2016-11-29 06:54:48 -05:00
# This makes e . g . the pods api available at localhost : 8001 / k8s - api / v1 / pods /
2017-03-14 23:49:10 -04:00
kubectl proxy -- api - prefix = / k8s - api ` ) )
2015-03-11 13:22:08 -04:00
)
2018-05-08 09:02:34 -04:00
func NewCmdProxy ( f cmdutil . Factory , streams genericclioptions . IOStreams ) * cobra . Command {
2014-10-05 21:24:19 -04:00
cmd := & cobra . Command {
2018-10-05 15:59:38 -04:00
Use : "proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix]" ,
2017-10-11 02:26:02 -04:00
DisableFlagsInUseLine : true ,
2018-10-05 15:59:38 -04:00
Short : i18n . T ( "Run a proxy to the Kubernetes API server" ) ,
Long : proxyLong ,
Example : proxyExample ,
2014-10-05 21:24:19 -04:00
Run : func ( cmd * cobra . Command , args [ ] string ) {
2018-05-08 09:02:34 -04:00
err := RunProxy ( f , streams . Out , cmd )
2015-04-07 14:21:25 -04:00
cmdutil . CheckErr ( err )
2014-10-05 21:24:19 -04:00
} ,
}
2015-02-03 12:59:21 -05:00
cmd . Flags ( ) . StringP ( "www" , "w" , "" , "Also serve static files from the given directory under the specified prefix." )
cmd . Flags ( ) . StringP ( "www-prefix" , "P" , "/static/" , "Prefix to serve static files under, if static file directory is specified." )
2015-10-09 15:02:16 -04:00
cmd . Flags ( ) . StringP ( "api-prefix" , "" , "/" , "Prefix to serve the proxied API under." )
2017-07-12 23:21:03 -04:00
cmd . Flags ( ) . String ( "accept-paths" , proxy . DefaultPathAcceptRE , "Regular expression for paths that the proxy should accept." )
cmd . Flags ( ) . String ( "reject-paths" , proxy . DefaultPathRejectRE , "Regular expression for paths that the proxy should reject. Paths specified here will be rejected even accepted by --accept-paths." )
cmd . Flags ( ) . String ( "accept-hosts" , proxy . DefaultHostAcceptRE , "Regular expression for hosts that the proxy should accept." )
cmd . Flags ( ) . String ( "reject-methods" , proxy . DefaultMethodRejectRE , "Regular expression for HTTP methods that the proxy should reject (example --reject-methods='POST,PUT,PATCH'). " )
2017-02-15 22:47:00 -05:00
cmd . Flags ( ) . IntP ( "port" , "p" , defaultPort , "The port on which to run the proxy. Set to 0 to pick a random port." )
2015-09-30 06:14:00 -04:00
cmd . Flags ( ) . StringP ( "address" , "" , "127.0.0.1" , "The IP address on which to serve on." )
2015-07-01 04:17:53 -04:00
cmd . Flags ( ) . Bool ( "disable-filter" , false , "If true, disable request filtering in the proxy. This is dangerous, and can leave you vulnerable to XSRF attacks, when used with an accessible port." )
cmd . Flags ( ) . StringP ( "unix-socket" , "u" , "" , "Unix socket on which to run the proxy." )
2018-05-14 08:11:43 -04:00
cmd . Flags ( ) . Duration ( "keepalive" , 0 , "keepalive specifies the keep-alive period for an active network connection. Set to 0 to disable keepalive." )
2014-10-05 21:24:19 -04:00
return cmd
}
2015-03-09 18:08:16 -04:00
2016-10-12 20:18:39 -04:00
func RunProxy ( f cmdutil . Factory , out io . Writer , cmd * cobra . Command ) error {
2015-07-01 04:17:53 -04:00
path := cmdutil . GetFlagString ( cmd , "unix-socket" )
2015-04-07 14:21:25 -04:00
port := cmdutil . GetFlagInt ( cmd , "port" )
2015-09-30 06:14:00 -04:00
address := cmdutil . GetFlagString ( cmd , "address" )
2015-03-09 18:08:16 -04:00
2017-02-15 22:47:00 -05:00
if port != defaultPort && path != "" {
2015-07-01 04:17:53 -04:00
return errors . New ( "Don't specify both --unix-socket and --port" )
}
2018-05-16 10:54:42 -04:00
clientConfig , err := f . ToRESTConfig ( )
2015-03-09 18:08:16 -04:00
if err != nil {
return err
}
2015-04-07 14:21:25 -04:00
staticPrefix := cmdutil . GetFlagString ( cmd , "www-prefix" )
2015-03-09 18:08:16 -04:00
if ! strings . HasSuffix ( staticPrefix , "/" ) {
staticPrefix += "/"
}
2017-04-26 05:53:54 -04:00
staticDir := cmdutil . GetFlagString ( cmd , "www" )
if staticDir != "" {
fileInfo , err := os . Stat ( staticDir )
if err != nil {
2018-11-09 13:49:10 -05:00
klog . Warning ( "Failed to stat static file directory " + staticDir + ": " , err )
2017-04-26 05:53:54 -04:00
} else if ! fileInfo . IsDir ( ) {
2018-11-09 13:49:10 -05:00
klog . Warning ( "Static file directory " + staticDir + " is not a directory" )
2017-04-26 05:53:54 -04:00
}
}
2015-03-09 18:08:16 -04:00
2015-04-07 14:21:25 -04:00
apiProxyPrefix := cmdutil . GetFlagString ( cmd , "api-prefix" )
2015-03-09 18:08:16 -04:00
if ! strings . HasSuffix ( apiProxyPrefix , "/" ) {
apiProxyPrefix += "/"
}
2017-07-12 23:21:03 -04:00
filter := & proxy . FilterServer {
AcceptPaths : proxy . MakeRegexpArrayOrDie ( cmdutil . GetFlagString ( cmd , "accept-paths" ) ) ,
RejectPaths : proxy . MakeRegexpArrayOrDie ( cmdutil . GetFlagString ( cmd , "reject-paths" ) ) ,
AcceptHosts : proxy . MakeRegexpArrayOrDie ( cmdutil . GetFlagString ( cmd , "accept-hosts" ) ) ,
RejectMethods : proxy . MakeRegexpArrayOrDie ( cmdutil . GetFlagString ( cmd , "reject-methods" ) ) ,
2015-06-04 19:21:11 -04:00
}
if cmdutil . GetFlagBool ( cmd , "disable-filter" ) {
2015-07-01 04:17:53 -04:00
if path == "" {
2018-11-09 13:49:10 -05:00
klog . Warning ( "Request filter disabled, your proxy is vulnerable to XSRF attacks, please be cautious" )
2015-07-01 04:17:53 -04:00
}
2015-06-04 19:21:11 -04:00
filter = nil
}
2018-05-14 08:11:43 -04:00
keepalive := cmdutil . GetFlagDuration ( cmd , "keepalive" )
server , err := proxy . NewServer ( staticDir , apiProxyPrefix , staticPrefix , filter , clientConfig , keepalive )
2015-03-09 18:08:16 -04:00
2015-07-07 01:04:39 -04:00
// Separate listening from serving so we can report the bound port
2015-07-01 04:17:53 -04:00
// when it is chosen by os (eg: port == 0)
var l net . Listener
if path == "" {
2015-09-30 06:14:00 -04:00
l , err = server . Listen ( address , port )
2015-07-01 04:17:53 -04:00
} else {
l , err = server . ListenUnix ( path )
}
2015-07-07 01:04:39 -04:00
if err != nil {
2018-11-09 13:49:10 -05:00
klog . Fatal ( err )
2015-07-07 01:04:39 -04:00
}
2017-07-24 23:37:19 -04:00
fmt . Fprintf ( out , "Starting to serve on %s\n" , l . Addr ( ) . String ( ) )
2018-11-09 13:49:10 -05:00
klog . Fatal ( server . ServeOnListener ( l ) )
2015-03-09 18:08:16 -04:00
return nil
}