Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --skip-open-browser flag #92

Merged
merged 1 commit into from
Aug 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Flags:
-n, --namespace string If present, the namespace scope for this CLI request
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--skip-open-browser If set, skip opening the browser
--skip_headers If true, avoid header prefixes in the log messages
--skip_log_headers If true, avoid headers when opening log files
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
Expand Down
3 changes: 1 addition & 2 deletions e2e_test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ deploy: cluster

.PHONY: test
test: main.go
#TODO: add an option to skip opening the browser
BROWSER=/bin/true go run main.go
go run main.go

.PHONY: delete-cluster
delete-cluster:
Expand Down
1 change: 1 addition & 0 deletions e2e_test/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func runKauthproxy(chInterrupt <-chan struct{}) error {
c := exec.Command("../kauthproxy",
"--namespace=kubernetes-dashboard",
"--user=tester",
"--skip-open-browser",
"https://kubernetes-dashboard.svc",
)
c.Stdout = os.Stdout
Expand Down
63 changes: 40 additions & 23 deletions pkg/authproxy/auth_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type Option struct {
Namespace string
TargetURL *url.URL
BindAddressCandidates []string
SkipOpenBrowser bool
}

// Do runs the use-case.
Expand All @@ -75,23 +76,28 @@ func (u *AuthProxy) Do(ctx context.Context, o Option) error {
return xerrors.Errorf("could not create a transport for reverse proxy: %w", err)
}
u.Logger.V(1).Infof("client -> reverse_proxy -> port_forwarder:%d -> pod -> container:%d", transitPort, containerPort)
pfo := portforwarder.Option{
Config: o.Config,
SourcePort: transitPort,
TargetPodURL: pod.GetSelfLink(),
TargetContainerPort: containerPort,
}
rpo := reverseproxy.Option{
Transport: rpTransport,
BindAddressCandidates: o.BindAddressCandidates,
TargetScheme: o.TargetURL.Scheme,
TargetHost: "localhost",
TargetPort: transitPort,
}

var once sync.Once
ro := runOption{
portForwarderOption: portforwarder.Option{
Config: o.Config,
SourcePort: transitPort,
TargetPodURL: pod.GetSelfLink(),
TargetContainerPort: containerPort,
},
reverseProxyOption: reverseproxy.Option{
Transport: rpTransport,
BindAddressCandidates: o.BindAddressCandidates,
TargetScheme: o.TargetURL.Scheme,
TargetHost: "localhost",
TargetPort: transitPort,
},
skipOpenBrowser: o.SkipOpenBrowser,
onceOpenBrowser: &once,
}
b := backoff.NewExponentialBackOff()
if err := backoff.Retry(func() error {
if err := u.run(ctx, pfo, rpo, &once); err != nil {
if err := u.run(ctx, ro); err != nil {
if xerrors.Is(err, portForwarderConnectionLostError) {
u.Logger.Printf("retrying: %s", err)
return err
Expand All @@ -105,6 +111,13 @@ func (u *AuthProxy) Do(ctx context.Context, o Option) error {
return nil
}

type runOption struct {
portForwarderOption portforwarder.Option
reverseProxyOption reverseproxy.Option
skipOpenBrowser bool
onceOpenBrowser *sync.Once
}

// run runs a port forwarder and reverse proxy, and waits for them, as follows:
//
// 1. Run a port forwarder.
Expand All @@ -119,7 +132,7 @@ func (u *AuthProxy) Do(ctx context.Context, o Option) error {
// This never returns nil.
// It returns an error which wraps context.Canceled if the context is canceled.
// It returns portForwarderConnectionLostError if a connection has lost.
func (u *AuthProxy) run(ctx context.Context, pfo portforwarder.Option, rpo reverseproxy.Option, once *sync.Once) error {
func (u *AuthProxy) run(ctx context.Context, o runOption) error {
portForwarderIsReady := make(chan struct{})
reverseProxyIsReady := make(chan reverseproxy.Instance, 1)
stopPortForwarder := make(chan struct{})
Expand All @@ -129,7 +142,7 @@ func (u *AuthProxy) run(ctx context.Context, pfo portforwarder.Option, rpo rever
// start a port forwarder
eg.Go(func() error {
u.Logger.V(1).Infof("starting a port forwarder")
if err := u.PortForwarder.Run(pfo, portForwarderIsReady, stopPortForwarder); err != nil {
if err := u.PortForwarder.Run(o.portForwarderOption, portForwarderIsReady, stopPortForwarder); err != nil {
return xerrors.Errorf("could not run a port forwarder: %w", err)
}
u.Logger.V(1).Infof("stopped the port forwarder")
Expand All @@ -151,7 +164,7 @@ func (u *AuthProxy) run(ctx context.Context, pfo portforwarder.Option, rpo rever
select {
case <-portForwarderIsReady:
u.Logger.V(1).Infof("starting a reverse proxy")
if err := u.ReverseProxy.Run(rpo, reverseProxyIsReady); err != nil {
if err := u.ReverseProxy.Run(o.reverseProxyOption, reverseProxyIsReady); err != nil {
return xerrors.Errorf("could not run a reverse proxy: %w", err)
}
u.Logger.V(1).Infof("stopped the reverse proxy")
Expand All @@ -168,12 +181,16 @@ func (u *AuthProxy) run(ctx context.Context, pfo portforwarder.Option, rpo rever
case rp := <-reverseProxyIsReady:
u.Logger.V(1).Infof("the reverse proxy is ready")
rpURL := rp.URL().String()
u.Logger.Printf("Open %s", rpURL)
once.Do(func() {
if err := u.Browser.Open(rpURL); err != nil {
u.Logger.Printf("error while opening the browser: %s", err)
}
})
if o.skipOpenBrowser {
u.Logger.Printf("Please open %s in the browser", rpURL)
} else {
o.onceOpenBrowser.Do(func() {
u.Logger.V(1).Infof("opening %s in the browser", rpURL)
if err := u.Browser.Open(rpURL); err != nil {
u.Logger.Printf("Please open %s in the browser (could not open the browser: %s)", rpURL, err)
}
})
}
// shutdown the reverse proxy when the context is done
eg.Go(func() error {
<-ctx.Done()
Expand Down
3 changes: 3 additions & 0 deletions pkg/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ func (cmd *Cmd) Run(ctx context.Context, osArgs []string, version string) int {
type rootCmdOptions struct {
k8sOptions *genericclioptions.ConfigFlags
addressCandidates []string
skipOpenBrowser bool
}

func (o *rootCmdOptions) addFlags(f *pflag.FlagSet) {
o.k8sOptions.AddFlags(f)
f.StringArrayVar(&o.addressCandidates, "address", defaultAddress, "The address on which to run the proxy. If set multiple times, it will try binding the address in order")
f.BoolVar(&o.skipOpenBrowser, "skip-open-browser", false, "If set, skip opening the browser")
}

func (cmd *Cmd) newRootCmd() *cobra.Command {
Expand Down Expand Up @@ -108,6 +110,7 @@ func (cmd *Cmd) runRootCmd(ctx context.Context, o rootCmdOptions, args []string)
Namespace: namespace,
TargetURL: remoteURL,
BindAddressCandidates: o.addressCandidates,
SkipOpenBrowser: o.skipOpenBrowser,
}
if err := cmd.AuthProxy.Do(ctx, authProxyOption); err != nil {
return xerrors.Errorf("could not run an authentication proxy: %w", err)
Expand Down