Skip to content

Commit

Permalink
Merge pull request #243 from liouk/cmd-minor-improvements
Browse files Browse the repository at this point in the history
Minor improvements in cmd/kube-rbac-proxy
  • Loading branch information
ibihim committed Jul 4, 2023
2 parents 653ccba + 8953fe1 commit 01ff844
Showing 1 changed file with 83 additions and 93 deletions.
176 changes: 83 additions & 93 deletions cmd/kube-rbac-proxy/app/kube-rbac-proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ import (
"net/http"
"net/http/httputil"
"os"
"os/signal"
"syscall"
"time"

"github.com/oklog/run"
"github.com/spf13/cobra"
"golang.org/x/net/http2"

utilerrors "k8s.io/apimachinery/pkg/util/errors"
waitgroup "k8s.io/apimachinery/pkg/util/waitgroup"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/authorization/union"
Expand Down Expand Up @@ -90,16 +88,15 @@ that can perform RBAC authorization against the Kubernetes API using SubjectAcce
return utilerrors.NewAggregate(errs)
}

return Run(completedOptions)
},
Args: func(cmd *cobra.Command, args []string) error {
for _, arg := range args {
if len(arg) > 0 {
return fmt.Errorf("%q does not take any arguments, got %q", cmd.CommandPath(), args)
}
// create the KubeRBACProxyConfig based on the completed options
proxyCfg, err := completedOptions.ProxyConfig()
if err != nil {
return err
}
return nil

return Run(proxyCfg)
},
Args: cobra.NoArgs,
}

fs := cmd.Flags()
Expand Down Expand Up @@ -132,6 +129,40 @@ func (o *completedProxyRunOptions) Validate() []error {
return errs
}

func (opts *completedProxyRunOptions) ProxyConfig() (*server.KubeRBACProxyConfig, error) {
proxyConfig := server.NewConfig()
if err := opts.SecureServing.ApplyTo(&proxyConfig.SecureServing); err != nil {
return nil, err
}

if opts.ProxySecureServing != nil {
if err := opts.ProxySecureServing.ApplyTo(&proxyConfig.KubeRBACProxyInfo.ProxyEndpointsSecureServing); err != nil {
return nil, err
}
}
if err := opts.DelegatingAuthentication.ApplyTo(
proxyConfig.DelegatingAuthentication,
proxyConfig.SecureServing,
nil,
); err != nil {
return nil, err
}

if err := opts.DelegatingAuthorization.ApplyTo(proxyConfig.DelegatingAuthorization); err != nil {
return nil, err
}

if err := opts.ProxyOptions.ApplyTo(proxyConfig.KubeRBACProxyInfo, proxyConfig.DelegatingAuthentication); err != nil {
return nil, err
}

if err := opts.OIDCOptions.ApplyTo(proxyConfig.KubeRBACProxyInfo); err != nil {
return nil, err
}

return proxyConfig, nil
}

// Complete sets defaults for the ProxyRunOptions.
// Should be called after the flags are parsed.
func Complete(o *options.ProxyRunOptions) (*completedProxyRunOptions, error) {
Expand Down Expand Up @@ -159,13 +190,8 @@ func Complete(o *options.ProxyRunOptions) (*completedProxyRunOptions, error) {
return completed, nil
}

func Run(opts *completedProxyRunOptions) error {
cfg, err := createKubeRBACProxyConfig(opts)
if err != nil {
return err
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
func Run(cfg *server.KubeRBACProxyConfig) error {
ctx := serverconfig.SetupSignalContext()

var authenticator authenticator.Request
// If OIDC configuration provided, use oidc authenticator
Expand Down Expand Up @@ -207,100 +233,64 @@ func Run(opts *completedProxyRunOptions) error {
handler := identityheaders.WithAuthHeaders(proxy, cfg.KubeRBACProxyInfo.UpstreamHeaders)
handler = kubefilters.WithAuthorization(handler, authz, scheme.Codecs)
handler = kubefilters.WithAuthentication(handler, authenticator, http.HandlerFunc(filters.UnauthorizedHandler), cfg.DelegatingAuthentication.APIAudiences)
// passing an empty RequestInfoFactory results in attaching a non-resource RequestInfo to the context
handler = kubefilters.WithRequestInfo(handler, &request.RequestInfoFactory{})
handler = rewrite.WithKubeRBACProxyParamsHandler(handler, cfg.KubeRBACProxyInfo.Authorization.RewriteAttributesConfig)

var wg waitgroup.SafeWaitGroup
serverCtx, cancel := context.WithCancel(ctx)
defer cancel()

// listener for proxying HTTPS with authentication and authorization (on port --secure-port)
mux := http.NewServeMux()
mux.Handle("/", handler)

gr := &run.Group{}
{
gr.Add(secureServerRunner(ctx, cfg.SecureServing, mux))

if cfg.KubeRBACProxyInfo.ProxyEndpointsSecureServing != nil {
proxyEndpointsMux := http.NewServeMux()
proxyEndpointsMux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("ok")) })

gr.Add(secureServerRunner(ctx, cfg.KubeRBACProxyInfo.ProxyEndpointsSecureServing, proxyEndpointsMux))
}
}
{
sig := make(chan os.Signal, 1)
gr.Add(func() error {
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
<-sig
klog.Info("received interrupt, shutting down")
return nil
}, func(err error) {
close(sig)
})
}

if err := gr.Run(); err != nil {
return fmt.Errorf("failed to run groups: %w", err)
if err := wg.Add(1); err != nil {
return err
}

return nil
}

func createKubeRBACProxyConfig(opts *completedProxyRunOptions) (*server.KubeRBACProxyConfig, error) {
proxyConfig := server.NewConfig()
if err := opts.SecureServing.ApplyTo(&proxyConfig.SecureServing); err != nil {
return nil, err
}
go func() {
defer wg.Done()
defer cancel()

if opts.ProxySecureServing != nil {
if err := opts.ProxySecureServing.ApplyTo(&proxyConfig.KubeRBACProxyInfo.ProxyEndpointsSecureServing); err != nil {
return nil, err
stoppedCh, listenerStoppedCh, err := cfg.SecureServing.Serve(mux, 10*time.Second, serverCtx.Done())
if err != nil {
klog.Errorf("%v", err)
return
}
}
if err := opts.DelegatingAuthentication.ApplyTo(
proxyConfig.DelegatingAuthentication,
proxyConfig.SecureServing,
nil,
); err != nil {
return nil, err
}

if err := opts.DelegatingAuthorization.ApplyTo(proxyConfig.DelegatingAuthorization); err != nil {
return nil, err
}

if err := opts.ProxyOptions.ApplyTo(proxyConfig.KubeRBACProxyInfo, proxyConfig.DelegatingAuthentication); err != nil {
return nil, err
}

if err := opts.OIDCOptions.ApplyTo(proxyConfig.KubeRBACProxyInfo); err != nil {
return nil, err
}

return proxyConfig, nil
}
<-listenerStoppedCh
<-stoppedCh
}()

func secureServerRunner(
ctx context.Context,
config *serverconfig.SecureServingInfo,
handler http.Handler,
) (func() error, func(error)) {
serverStopCtx, serverCtxCancel := context.WithCancel(ctx)
if cfg.KubeRBACProxyInfo.ProxyEndpointsSecureServing != nil {
// we need a second listener in order to serve proxy-specific endpoints
// on a different port (--proxy-endpoints-port)
proxyEndpointsMux := http.NewServeMux()
proxyEndpointsMux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("ok")) })

runner := func() error {
stoppedCh, listenerStoppedCh, err := config.Serve(handler, 10*time.Second, serverStopCtx.Done())
if err != nil {
serverCtxCancel()
if err := wg.Add(1); err != nil {
return err
}

<-listenerStoppedCh
<-stoppedCh
return err
}
go func() {
defer wg.Done()
defer cancel()

stoppedCh, listenerStoppedCh, err := cfg.KubeRBACProxyInfo.ProxyEndpointsSecureServing.Serve(proxyEndpointsMux, 10*time.Second, serverCtx.Done())
if err != nil {
klog.Errorf("%v", err)
return
}

interrupter := func(err error) {
serverCtxCancel()
<-listenerStoppedCh
<-stoppedCh
}()
}

return runner, interrupter
wg.Wait()

return nil
}

func setupAuthorizer(krbInfo *server.KubeRBACProxyInfo, delegatedAuthz *serverconfig.AuthorizationInfo) (authorizer.Authorizer, error) {
Expand Down

0 comments on commit 01ff844

Please sign in to comment.