mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #89069 from enj/enj/i/drop_password_file
Remove support for basic authentication
This commit is contained in:
		@@ -101,9 +101,6 @@ function start-kube-apiserver {
 | 
				
			|||||||
    params+=" --service-account-key-file=${SERVICEACCOUNT_CERT_PATH}"
 | 
					    params+=" --service-account-key-file=${SERVICEACCOUNT_CERT_PATH}"
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
  params+=" --token-auth-file=/etc/srv/kubernetes/known_tokens.csv"
 | 
					  params+=" --token-auth-file=/etc/srv/kubernetes/known_tokens.csv"
 | 
				
			||||||
  if [[ -n "${KUBE_PASSWORD:-}" && -n "${KUBE_USER:-}" ]]; then
 | 
					 | 
				
			||||||
    params+=" --basic-auth-file=/etc/srv/kubernetes/basic_auth.csv"
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if [[ -n "${KUBE_APISERVER_REQUEST_TIMEOUT_SEC:-}" ]]; then
 | 
					  if [[ -n "${KUBE_APISERVER_REQUEST_TIMEOUT_SEC:-}" ]]; then
 | 
				
			||||||
    params+=" --request-timeout=${KUBE_APISERVER_REQUEST_TIMEOUT_SEC}s"
 | 
					    params+=" --request-timeout=${KUBE_APISERVER_REQUEST_TIMEOUT_SEC}s"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,7 +37,7 @@ import (
 | 
				
			|||||||
// BuildHandlerChain builds a handler chain with a base handler and CompletedConfig.
 | 
					// BuildHandlerChain builds a handler chain with a base handler and CompletedConfig.
 | 
				
			||||||
func BuildHandlerChain(apiHandler http.Handler, authorizationInfo *apiserver.AuthorizationInfo, authenticationInfo *apiserver.AuthenticationInfo) http.Handler {
 | 
					func BuildHandlerChain(apiHandler http.Handler, authorizationInfo *apiserver.AuthorizationInfo, authenticationInfo *apiserver.AuthenticationInfo) http.Handler {
 | 
				
			||||||
	requestInfoResolver := &apirequest.RequestInfoFactory{}
 | 
						requestInfoResolver := &apirequest.RequestInfoFactory{}
 | 
				
			||||||
	failedHandler := genericapifilters.Unauthorized(legacyscheme.Codecs, false)
 | 
						failedHandler := genericapifilters.Unauthorized(legacyscheme.Codecs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	handler := apiHandler
 | 
						handler := apiHandler
 | 
				
			||||||
	if authorizationInfo != nil {
 | 
						if authorizationInfo != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -276,7 +276,6 @@ func TestAddFlags(t *testing.T) {
 | 
				
			|||||||
				UsernameClaim: "sub",
 | 
									UsernameClaim: "sub",
 | 
				
			||||||
				SigningAlgs:   []string{"RS256"},
 | 
									SigningAlgs:   []string{"RS256"},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			PasswordFile:  &kubeoptions.PasswordFileAuthenticationOptions{},
 | 
					 | 
				
			||||||
			RequestHeader: &apiserveroptions.RequestHeaderAuthenticationOptions{},
 | 
								RequestHeader: &apiserveroptions.RequestHeaderAuthenticationOptions{},
 | 
				
			||||||
			ServiceAccounts: &kubeoptions.ServiceAccountAuthenticationOptions{
 | 
								ServiceAccounts: &kubeoptions.ServiceAccountAuthenticationOptions{
 | 
				
			||||||
				Lookup: true,
 | 
									Lookup: true,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -262,7 +262,7 @@ func Run(ctx context.Context, cc schedulerserverconfig.CompletedConfig, outOfTre
 | 
				
			|||||||
// buildHandlerChain wraps the given handler with the standard filters.
 | 
					// buildHandlerChain wraps the given handler with the standard filters.
 | 
				
			||||||
func buildHandlerChain(handler http.Handler, authn authenticator.Request, authz authorizer.Authorizer) http.Handler {
 | 
					func buildHandlerChain(handler http.Handler, authn authenticator.Request, authz authorizer.Authorizer) http.Handler {
 | 
				
			||||||
	requestInfoResolver := &apirequest.RequestInfoFactory{}
 | 
						requestInfoResolver := &apirequest.RequestInfoFactory{}
 | 
				
			||||||
	failedHandler := genericapifilters.Unauthorized(legacyscheme.Codecs, false)
 | 
						failedHandler := genericapifilters.Unauthorized(legacyscheme.Codecs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	handler = genericapifilters.WithAuthorization(handler, authz, legacyscheme.Codecs)
 | 
						handler = genericapifilters.WithAuthorization(handler, authz, legacyscheme.Codecs)
 | 
				
			||||||
	handler = genericapifilters.WithAuthentication(handler, authn, failedHandler, nil)
 | 
						handler = genericapifilters.WithAuthentication(handler, authn, failedHandler, nil)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,8 +27,6 @@ go_library(
 | 
				
			|||||||
        "//staging/src/k8s.io/apiserver/pkg/authentication/token/union:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/pkg/authentication/token/union:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/server/dynamiccertificates:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/pkg/server/dynamiccertificates:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/client-go/plugin/pkg/client/auth:go_default_library",
 | 
					        "//staging/src/k8s.io/client-go/plugin/pkg/client/auth:go_default_library",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,8 +36,6 @@ import (
 | 
				
			|||||||
	tokenunion "k8s.io/apiserver/pkg/authentication/token/union"
 | 
						tokenunion "k8s.io/apiserver/pkg/authentication/token/union"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/server/dynamiccertificates"
 | 
						"k8s.io/apiserver/pkg/server/dynamiccertificates"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
	"k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile"
 | 
					 | 
				
			||||||
	"k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth"
 | 
					 | 
				
			||||||
	"k8s.io/apiserver/plugin/pkg/authenticator/token/oidc"
 | 
						"k8s.io/apiserver/plugin/pkg/authenticator/token/oidc"
 | 
				
			||||||
	"k8s.io/apiserver/plugin/pkg/authenticator/token/webhook"
 | 
						"k8s.io/apiserver/plugin/pkg/authenticator/token/webhook"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -51,7 +49,6 @@ import (
 | 
				
			|||||||
// Config contains the data on how to authenticate a request to the Kube API Server
 | 
					// Config contains the data on how to authenticate a request to the Kube API Server
 | 
				
			||||||
type Config struct {
 | 
					type Config struct {
 | 
				
			||||||
	Anonymous      bool
 | 
						Anonymous      bool
 | 
				
			||||||
	BasicAuthFile  string
 | 
					 | 
				
			||||||
	BootstrapToken bool
 | 
						BootstrapToken bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TokenAuthFile               string
 | 
						TokenAuthFile               string
 | 
				
			||||||
@@ -109,22 +106,6 @@ func (config Config) New() (authenticator.Request, *spec.SecurityDefinitions, er
 | 
				
			|||||||
		authenticators = append(authenticators, authenticator.WrapAudienceAgnosticRequest(config.APIAudiences, requestHeaderAuthenticator))
 | 
							authenticators = append(authenticators, authenticator.WrapAudienceAgnosticRequest(config.APIAudiences, requestHeaderAuthenticator))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// basic auth
 | 
					 | 
				
			||||||
	if len(config.BasicAuthFile) > 0 {
 | 
					 | 
				
			||||||
		basicAuth, err := newAuthenticatorFromBasicAuthFile(config.BasicAuthFile)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		authenticators = append(authenticators, authenticator.WrapAudienceAgnosticRequest(config.APIAudiences, basicAuth))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		securityDefinitions["HTTPBasic"] = &spec.SecurityScheme{
 | 
					 | 
				
			||||||
			SecuritySchemeProps: spec.SecuritySchemeProps{
 | 
					 | 
				
			||||||
				Type:        "basic",
 | 
					 | 
				
			||||||
				Description: "HTTP Basic authentication",
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// X509 methods
 | 
						// X509 methods
 | 
				
			||||||
	if config.ClientCAContentProvider != nil {
 | 
						if config.ClientCAContentProvider != nil {
 | 
				
			||||||
		certAuth := x509.NewDynamic(config.ClientCAContentProvider.VerifyOptions, x509.CommonNameUserConversion)
 | 
							certAuth := x509.NewDynamic(config.ClientCAContentProvider.VerifyOptions, x509.CommonNameUserConversion)
 | 
				
			||||||
@@ -235,16 +216,6 @@ func IsValidServiceAccountKeyFile(file string) bool {
 | 
				
			|||||||
	return err == nil
 | 
						return err == nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// newAuthenticatorFromBasicAuthFile returns an authenticator.Request or an error
 | 
					 | 
				
			||||||
func newAuthenticatorFromBasicAuthFile(basicAuthFile string) (authenticator.Request, error) {
 | 
					 | 
				
			||||||
	basicAuthenticator, err := passwordfile.NewCSV(basicAuthFile)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return basicauth.New(basicAuthenticator), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// newAuthenticatorFromTokenFile returns an authenticator.Token or an error
 | 
					// newAuthenticatorFromTokenFile returns an authenticator.Token or an error
 | 
				
			||||||
func newAuthenticatorFromTokenFile(tokenAuthFile string) (authenticator.Token, error) {
 | 
					func newAuthenticatorFromTokenFile(tokenAuthFile string) (authenticator.Token, error) {
 | 
				
			||||||
	tokenAuthenticator, err := tokenfile.NewCSV(tokenAuthFile)
 | 
						tokenAuthenticator, err := tokenfile.NewCSV(tokenAuthFile)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,7 +43,6 @@ type BuiltInAuthenticationOptions struct {
 | 
				
			|||||||
	BootstrapToken  *BootstrapTokenAuthenticationOptions
 | 
						BootstrapToken  *BootstrapTokenAuthenticationOptions
 | 
				
			||||||
	ClientCert      *genericoptions.ClientCertAuthenticationOptions
 | 
						ClientCert      *genericoptions.ClientCertAuthenticationOptions
 | 
				
			||||||
	OIDC            *OIDCAuthenticationOptions
 | 
						OIDC            *OIDCAuthenticationOptions
 | 
				
			||||||
	PasswordFile    *PasswordFileAuthenticationOptions
 | 
					 | 
				
			||||||
	RequestHeader   *genericoptions.RequestHeaderAuthenticationOptions
 | 
						RequestHeader   *genericoptions.RequestHeaderAuthenticationOptions
 | 
				
			||||||
	ServiceAccounts *ServiceAccountAuthenticationOptions
 | 
						ServiceAccounts *ServiceAccountAuthenticationOptions
 | 
				
			||||||
	TokenFile       *TokenFileAuthenticationOptions
 | 
						TokenFile       *TokenFileAuthenticationOptions
 | 
				
			||||||
@@ -73,10 +72,6 @@ type OIDCAuthenticationOptions struct {
 | 
				
			|||||||
	RequiredClaims map[string]string
 | 
						RequiredClaims map[string]string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type PasswordFileAuthenticationOptions struct {
 | 
					 | 
				
			||||||
	BasicAuthFile string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ServiceAccountAuthenticationOptions struct {
 | 
					type ServiceAccountAuthenticationOptions struct {
 | 
				
			||||||
	KeyFiles      []string
 | 
						KeyFiles      []string
 | 
				
			||||||
	Lookup        bool
 | 
						Lookup        bool
 | 
				
			||||||
@@ -108,7 +103,6 @@ func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions {
 | 
				
			|||||||
		WithBootstrapToken().
 | 
							WithBootstrapToken().
 | 
				
			||||||
		WithClientCert().
 | 
							WithClientCert().
 | 
				
			||||||
		WithOIDC().
 | 
							WithOIDC().
 | 
				
			||||||
		WithPasswordFile().
 | 
					 | 
				
			||||||
		WithRequestHeader().
 | 
							WithRequestHeader().
 | 
				
			||||||
		WithServiceAccounts().
 | 
							WithServiceAccounts().
 | 
				
			||||||
		WithTokenFile().
 | 
							WithTokenFile().
 | 
				
			||||||
@@ -135,11 +129,6 @@ func (s *BuiltInAuthenticationOptions) WithOIDC() *BuiltInAuthenticationOptions
 | 
				
			|||||||
	return s
 | 
						return s
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *BuiltInAuthenticationOptions) WithPasswordFile() *BuiltInAuthenticationOptions {
 | 
					 | 
				
			||||||
	s.PasswordFile = &PasswordFileAuthenticationOptions{}
 | 
					 | 
				
			||||||
	return s
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *BuiltInAuthenticationOptions) WithRequestHeader() *BuiltInAuthenticationOptions {
 | 
					func (s *BuiltInAuthenticationOptions) WithRequestHeader() *BuiltInAuthenticationOptions {
 | 
				
			||||||
	s.RequestHeader = &genericoptions.RequestHeaderAuthenticationOptions{}
 | 
						s.RequestHeader = &genericoptions.RequestHeaderAuthenticationOptions{}
 | 
				
			||||||
	return s
 | 
						return s
 | 
				
			||||||
@@ -274,13 +263,6 @@ func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
 | 
				
			|||||||
			"Repeat this flag to specify multiple claims.")
 | 
								"Repeat this flag to specify multiple claims.")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if s.PasswordFile != nil {
 | 
					 | 
				
			||||||
		fs.StringVar(&s.PasswordFile.BasicAuthFile, "basic-auth-file", s.PasswordFile.BasicAuthFile, ""+
 | 
					 | 
				
			||||||
			"If set, the file that will be used to admit requests to the secure port of the API server "+
 | 
					 | 
				
			||||||
			"via http basic authentication.")
 | 
					 | 
				
			||||||
		fs.MarkDeprecated("basic-auth-file", "Basic authentication mode is deprecated and will be removed in a future release. It is not recommended for production environments.")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if s.RequestHeader != nil {
 | 
						if s.RequestHeader != nil {
 | 
				
			||||||
		s.RequestHeader.AddFlags(fs)
 | 
							s.RequestHeader.AddFlags(fs)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -377,10 +359,6 @@ func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() (kubeauthenticat
 | 
				
			|||||||
		ret.OIDCRequiredClaims = s.OIDC.RequiredClaims
 | 
							ret.OIDCRequiredClaims = s.OIDC.RequiredClaims
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if s.PasswordFile != nil {
 | 
					 | 
				
			||||||
		ret.BasicAuthFile = s.PasswordFile.BasicAuthFile
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if s.RequestHeader != nil {
 | 
						if s.RequestHeader != nil {
 | 
				
			||||||
		var err error
 | 
							var err error
 | 
				
			||||||
		ret.RequestHeaderConfig, err = s.RequestHeader.ToAuthenticationRequestHeaderConfig()
 | 
							ret.RequestHeaderConfig, err = s.RequestHeader.ToAuthenticationRequestHeaderConfig()
 | 
				
			||||||
@@ -447,8 +425,6 @@ func (o *BuiltInAuthenticationOptions) ApplyTo(c *genericapiserver.Config) error
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.Authentication.SupportsBasicAuth = o.PasswordFile != nil && len(o.PasswordFile.BasicAuthFile) > 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	c.Authentication.APIAudiences = o.APIAudiences
 | 
						c.Authentication.APIAudiences = o.APIAudiences
 | 
				
			||||||
	if o.ServiceAccounts != nil && o.ServiceAccounts.Issuer != "" && len(o.APIAudiences) == 0 {
 | 
						if o.ServiceAccounts != nil && o.ServiceAccounts.Issuer != "" && len(o.APIAudiences) == 0 {
 | 
				
			||||||
		c.Authentication.APIAudiences = authenticator.Audiences{o.ServiceAccounts.Issuer}
 | 
							c.Authentication.APIAudiences = authenticator.Audiences{o.ServiceAccounts.Issuer}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -120,9 +120,6 @@ func TestToAuthenticationConfig(t *testing.T) {
 | 
				
			|||||||
			IssuerURL:     "testIssuerURL",
 | 
								IssuerURL:     "testIssuerURL",
 | 
				
			||||||
			ClientID:      "testClientID",
 | 
								ClientID:      "testClientID",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		PasswordFile: &PasswordFileAuthenticationOptions{
 | 
					 | 
				
			||||||
			BasicAuthFile: "/testBasicAuthFile",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		RequestHeader: &apiserveroptions.RequestHeaderAuthenticationOptions{
 | 
							RequestHeader: &apiserveroptions.RequestHeaderAuthenticationOptions{
 | 
				
			||||||
			UsernameHeaders:     []string{"x-remote-user"},
 | 
								UsernameHeaders:     []string{"x-remote-user"},
 | 
				
			||||||
			GroupHeaders:        []string{"x-remote-group"},
 | 
								GroupHeaders:        []string{"x-remote-group"},
 | 
				
			||||||
@@ -144,7 +141,6 @@ func TestToAuthenticationConfig(t *testing.T) {
 | 
				
			|||||||
	expectConfig := kubeauthenticator.Config{
 | 
						expectConfig := kubeauthenticator.Config{
 | 
				
			||||||
		APIAudiences:                authenticator.Audiences{"http://foo.bar.com"},
 | 
							APIAudiences:                authenticator.Audiences{"http://foo.bar.com"},
 | 
				
			||||||
		Anonymous:                   false,
 | 
							Anonymous:                   false,
 | 
				
			||||||
		BasicAuthFile:               "/testBasicAuthFile",
 | 
					 | 
				
			||||||
		BootstrapToken:              false,
 | 
							BootstrapToken:              false,
 | 
				
			||||||
		ClientCAContentProvider:     nil, // this is nil because you can't compare functions
 | 
							ClientCAContentProvider:     nil, // this is nil because you can't compare functions
 | 
				
			||||||
		TokenAuthFile:               "/testTokenFile",
 | 
							TokenAuthFile:               "/testTokenFile",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,13 +35,6 @@ type Request interface {
 | 
				
			|||||||
	AuthenticateRequest(req *http.Request) (*Response, bool, error)
 | 
						AuthenticateRequest(req *http.Request) (*Response, bool, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Password checks a username and password against a backing authentication
 | 
					 | 
				
			||||||
// store and returns a Response or an error if the password could not be
 | 
					 | 
				
			||||||
// checked.
 | 
					 | 
				
			||||||
type Password interface {
 | 
					 | 
				
			||||||
	AuthenticatePassword(ctx context.Context, user, password string) (*Response, bool, error)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TokenFunc is a function that implements the Token interface.
 | 
					// TokenFunc is a function that implements the Token interface.
 | 
				
			||||||
type TokenFunc func(ctx context.Context, token string) (*Response, bool, error)
 | 
					type TokenFunc func(ctx context.Context, token string) (*Response, bool, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -58,14 +51,6 @@ func (f RequestFunc) AuthenticateRequest(req *http.Request) (*Response, bool, er
 | 
				
			|||||||
	return f(req)
 | 
						return f(req)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PasswordFunc is a function that implements the Password interface.
 | 
					 | 
				
			||||||
type PasswordFunc func(ctx context.Context, user, password string) (*Response, bool, error)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AuthenticatePassword implements authenticator.Password.
 | 
					 | 
				
			||||||
func (f PasswordFunc) AuthenticatePassword(ctx context.Context, user, password string) (*Response, bool, error) {
 | 
					 | 
				
			||||||
	return f(ctx, user, password)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Response is the struct returned by authenticator interfaces upon successful
 | 
					// Response is the struct returned by authenticator interfaces upon successful
 | 
				
			||||||
// authentication. It contains information about whether the authenticator
 | 
					// authentication. It contains information about whether the authenticator
 | 
				
			||||||
// authenticated the request, information about the context of the
 | 
					// authenticated the request, information about the context of the
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,11 +71,8 @@ func WithAuthentication(handler http.Handler, auth authenticator.Request, failed
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Unauthorized(s runtime.NegotiatedSerializer, supportsBasicAuth bool) http.Handler {
 | 
					func Unauthorized(s runtime.NegotiatedSerializer) http.Handler {
 | 
				
			||||||
	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
						return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
		if supportsBasicAuth {
 | 
					 | 
				
			||||||
			w.Header().Set("WWW-Authenticate", `Basic realm="kubernetes-master"`)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		ctx := req.Context()
 | 
							ctx := req.Context()
 | 
				
			||||||
		requestInfo, found := genericapirequest.RequestInfoFrom(ctx)
 | 
							requestInfo, found := genericapirequest.RequestInfoFrom(ctx)
 | 
				
			||||||
		if !found {
 | 
							if !found {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -272,10 +272,6 @@ type AuthenticationInfo struct {
 | 
				
			|||||||
	APIAudiences authenticator.Audiences
 | 
						APIAudiences authenticator.Audiences
 | 
				
			||||||
	// Authenticator determines which subject is making the request
 | 
						// Authenticator determines which subject is making the request
 | 
				
			||||||
	Authenticator authenticator.Request
 | 
						Authenticator authenticator.Request
 | 
				
			||||||
	// SupportsBasicAuth indicates that's at least one Authenticator supports basic auth
 | 
					 | 
				
			||||||
	// If this is true, a basic auth challenge is returned on authentication failure
 | 
					 | 
				
			||||||
	// TODO(roberthbailey): Remove once the server no longer supports http basic auth.
 | 
					 | 
				
			||||||
	SupportsBasicAuth bool
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AuthorizationInfo struct {
 | 
					type AuthorizationInfo struct {
 | 
				
			||||||
@@ -670,7 +666,7 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	handler = genericapifilters.WithImpersonation(handler, c.Authorization.Authorizer, c.Serializer)
 | 
						handler = genericapifilters.WithImpersonation(handler, c.Authorization.Authorizer, c.Serializer)
 | 
				
			||||||
	handler = genericapifilters.WithAudit(handler, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc)
 | 
						handler = genericapifilters.WithAudit(handler, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc)
 | 
				
			||||||
	failedHandler := genericapifilters.Unauthorized(c.Serializer, c.Authentication.SupportsBasicAuth)
 | 
						failedHandler := genericapifilters.Unauthorized(c.Serializer)
 | 
				
			||||||
	failedHandler = genericapifilters.WithFailedAuthenticationAudit(failedHandler, c.AuditBackend, c.AuditPolicyChecker)
 | 
						failedHandler = genericapifilters.WithFailedAuthenticationAudit(failedHandler, c.AuditBackend, c.AuditPolicyChecker)
 | 
				
			||||||
	handler = genericapifilters.WithAuthentication(handler, c.Authentication.Authenticator, failedHandler, c.Authentication.APIAudiences)
 | 
						handler = genericapifilters.WithAuthentication(handler, c.Authentication.Authenticator, failedHandler, c.Authentication.APIAudiences)
 | 
				
			||||||
	handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
 | 
						handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -319,7 +319,6 @@ func (s *DelegatingAuthenticationOptions) ApplyTo(authenticationInfo *server.Aut
 | 
				
			|||||||
	if openAPIConfig != nil {
 | 
						if openAPIConfig != nil {
 | 
				
			||||||
		openAPIConfig.SecurityDefinitions = securityDefinitions
 | 
							openAPIConfig.SecurityDefinitions = securityDefinitions
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	authenticationInfo.SupportsBasicAuth = false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,8 +23,6 @@ filegroup(
 | 
				
			|||||||
    name = "all-srcs",
 | 
					    name = "all-srcs",
 | 
				
			||||||
    srcs = [
 | 
					    srcs = [
 | 
				
			||||||
        ":package-srcs",
 | 
					        ":package-srcs",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password:all-srcs",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth:all-srcs",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:all-srcs",
 | 
					        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:all-srcs",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest:all-srcs",
 | 
					        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest:all-srcs",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:all-srcs",
 | 
					        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:all-srcs",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,29 +0,0 @@
 | 
				
			|||||||
package(default_visibility = ["//visibility:public"])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
load(
 | 
					 | 
				
			||||||
    "@io_bazel_rules_go//go:def.bzl",
 | 
					 | 
				
			||||||
    "go_library",
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_library(
 | 
					 | 
				
			||||||
    name = "go_default_library",
 | 
					 | 
				
			||||||
    srcs = ["doc.go"],
 | 
					 | 
				
			||||||
    importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/plugin/pkg/authenticator/password",
 | 
					 | 
				
			||||||
    importpath = "k8s.io/apiserver/plugin/pkg/authenticator/password",
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "package-srcs",
 | 
					 | 
				
			||||||
    srcs = glob(["**"]),
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "all-srcs",
 | 
					 | 
				
			||||||
    srcs = [
 | 
					 | 
				
			||||||
        ":package-srcs",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile:all-srcs",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2014 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 password contains authenticator.Password implementations
 | 
					 | 
				
			||||||
package password // import "k8s.io/apiserver/plugin/pkg/authenticator/password"
 | 
					 | 
				
			||||||
@@ -1,39 +0,0 @@
 | 
				
			|||||||
package(default_visibility = ["//visibility:public"])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
load(
 | 
					 | 
				
			||||||
    "@io_bazel_rules_go//go:def.bzl",
 | 
					 | 
				
			||||||
    "go_library",
 | 
					 | 
				
			||||||
    "go_test",
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_test(
 | 
					 | 
				
			||||||
    name = "go_default_test",
 | 
					 | 
				
			||||||
    srcs = ["passwordfile_test.go"],
 | 
					 | 
				
			||||||
    embed = [":go_default_library"],
 | 
					 | 
				
			||||||
    deps = ["//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_library(
 | 
					 | 
				
			||||||
    name = "go_default_library",
 | 
					 | 
				
			||||||
    srcs = ["passwordfile.go"],
 | 
					 | 
				
			||||||
    importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile",
 | 
					 | 
				
			||||||
    importpath = "k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile",
 | 
					 | 
				
			||||||
    deps = [
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/klog:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "package-srcs",
 | 
					 | 
				
			||||||
    srcs = glob(["**"]),
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "all-srcs",
 | 
					 | 
				
			||||||
    srcs = [":package-srcs"],
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
@@ -1,95 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 passwordfile
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"crypto/subtle"
 | 
					 | 
				
			||||||
	"encoding/csv"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"k8s.io/klog"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"k8s.io/apiserver/pkg/authentication/authenticator"
 | 
					 | 
				
			||||||
	"k8s.io/apiserver/pkg/authentication/user"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PasswordAuthenticator authenticates users by password
 | 
					 | 
				
			||||||
type PasswordAuthenticator struct {
 | 
					 | 
				
			||||||
	users map[string]*userPasswordInfo
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type userPasswordInfo struct {
 | 
					 | 
				
			||||||
	info     *user.DefaultInfo
 | 
					 | 
				
			||||||
	password string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewCSV returns a PasswordAuthenticator, populated from a CSV file.
 | 
					 | 
				
			||||||
// The CSV file must contain records in the format "password,username,useruid"
 | 
					 | 
				
			||||||
func NewCSV(path string) (*PasswordAuthenticator, error) {
 | 
					 | 
				
			||||||
	file, err := os.Open(path)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer file.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	recordNum := 0
 | 
					 | 
				
			||||||
	users := make(map[string]*userPasswordInfo)
 | 
					 | 
				
			||||||
	reader := csv.NewReader(file)
 | 
					 | 
				
			||||||
	reader.FieldsPerRecord = -1
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		record, err := reader.Read()
 | 
					 | 
				
			||||||
		if err == io.EOF {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(record) < 3 {
 | 
					 | 
				
			||||||
			return nil, fmt.Errorf("password file '%s' must have at least 3 columns (password, user name, user uid), found %d", path, len(record))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		obj := &userPasswordInfo{
 | 
					 | 
				
			||||||
			info:     &user.DefaultInfo{Name: record[1], UID: record[2]},
 | 
					 | 
				
			||||||
			password: record[0],
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(record) >= 4 {
 | 
					 | 
				
			||||||
			obj.info.Groups = strings.Split(record[3], ",")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		recordNum++
 | 
					 | 
				
			||||||
		if _, exist := users[obj.info.Name]; exist {
 | 
					 | 
				
			||||||
			klog.Warningf("duplicate username '%s' has been found in password file '%s', record number '%d'", obj.info.Name, path, recordNum)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		users[obj.info.Name] = obj
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &PasswordAuthenticator{users}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AuthenticatePassword returns user info if authentication is successful, nil otherwise
 | 
					 | 
				
			||||||
func (a *PasswordAuthenticator) AuthenticatePassword(ctx context.Context, username, password string) (*authenticator.Response, bool, error) {
 | 
					 | 
				
			||||||
	user, ok := a.users[username]
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return nil, false, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if subtle.ConstantTimeCompare([]byte(user.password), []byte(password)) == 0 {
 | 
					 | 
				
			||||||
		return nil, false, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &authenticator.Response{User: user.info}, true, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,161 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 passwordfile
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"io/ioutil"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"reflect"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"k8s.io/apiserver/pkg/authentication/user"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestPasswordFile(t *testing.T) {
 | 
					 | 
				
			||||||
	auth, err := newWithContents(t, `
 | 
					 | 
				
			||||||
password1,user1,uid1
 | 
					 | 
				
			||||||
password2,user2,uid2
 | 
					 | 
				
			||||||
password3,user3,uid3,"group1,group2"
 | 
					 | 
				
			||||||
password4,user4,uid4,"group2"
 | 
					 | 
				
			||||||
password5,user5,uid5,group5
 | 
					 | 
				
			||||||
password6,user6,uid6,group5,otherdata
 | 
					 | 
				
			||||||
password7,user7,uid7,"group1,group2",otherdata
 | 
					 | 
				
			||||||
`)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatalf("unable to read passwordfile: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	testCases := []struct {
 | 
					 | 
				
			||||||
		Username string
 | 
					 | 
				
			||||||
		Password string
 | 
					 | 
				
			||||||
		User     *user.DefaultInfo
 | 
					 | 
				
			||||||
		Ok       bool
 | 
					 | 
				
			||||||
		Err      bool
 | 
					 | 
				
			||||||
	}{
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "user1",
 | 
					 | 
				
			||||||
			Password: "password1",
 | 
					 | 
				
			||||||
			User:     &user.DefaultInfo{Name: "user1", UID: "uid1"},
 | 
					 | 
				
			||||||
			Ok:       true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "user2",
 | 
					 | 
				
			||||||
			Password: "password2",
 | 
					 | 
				
			||||||
			User:     &user.DefaultInfo{Name: "user2", UID: "uid2"},
 | 
					 | 
				
			||||||
			Ok:       true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "user1",
 | 
					 | 
				
			||||||
			Password: "password2",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "user2",
 | 
					 | 
				
			||||||
			Password: "password1",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "user3",
 | 
					 | 
				
			||||||
			Password: "password3",
 | 
					 | 
				
			||||||
			User:     &user.DefaultInfo{Name: "user3", UID: "uid3", Groups: []string{"group1", "group2"}},
 | 
					 | 
				
			||||||
			Ok:       true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "user4",
 | 
					 | 
				
			||||||
			Password: "password4",
 | 
					 | 
				
			||||||
			User:     &user.DefaultInfo{Name: "user4", UID: "uid4", Groups: []string{"group2"}},
 | 
					 | 
				
			||||||
			Ok:       true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "user5",
 | 
					 | 
				
			||||||
			Password: "password5",
 | 
					 | 
				
			||||||
			User:     &user.DefaultInfo{Name: "user5", UID: "uid5", Groups: []string{"group5"}},
 | 
					 | 
				
			||||||
			Ok:       true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "user6",
 | 
					 | 
				
			||||||
			Password: "password6",
 | 
					 | 
				
			||||||
			User:     &user.DefaultInfo{Name: "user6", UID: "uid6", Groups: []string{"group5"}},
 | 
					 | 
				
			||||||
			Ok:       true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "user7",
 | 
					 | 
				
			||||||
			Password: "password7",
 | 
					 | 
				
			||||||
			User:     &user.DefaultInfo{Name: "user7", UID: "uid7", Groups: []string{"group1", "group2"}},
 | 
					 | 
				
			||||||
			Ok:       true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "user7",
 | 
					 | 
				
			||||||
			Password: "passwordbad",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "userbad",
 | 
					 | 
				
			||||||
			Password: "password7",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Username: "user8",
 | 
					 | 
				
			||||||
			Password: "password8",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for i, testCase := range testCases {
 | 
					 | 
				
			||||||
		resp, ok, err := auth.AuthenticatePassword(context.Background(), testCase.Username, testCase.Password)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			t.Errorf("%d: unexpected error: %v", i, err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if testCase.User == nil {
 | 
					 | 
				
			||||||
			if resp != nil {
 | 
					 | 
				
			||||||
				t.Errorf("%d: unexpected non-nil user %#v", i, resp.User)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else if !reflect.DeepEqual(testCase.User, resp.User) {
 | 
					 | 
				
			||||||
			t.Errorf("%d: expected user %#v, got %#v", i, testCase.User, resp.User)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if testCase.Ok != ok {
 | 
					 | 
				
			||||||
			t.Errorf("%d: expected auth %v, got %v", i, testCase.Ok, ok)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestBadPasswordFile(t *testing.T) {
 | 
					 | 
				
			||||||
	if _, err := newWithContents(t, `
 | 
					 | 
				
			||||||
password1,user1,uid1
 | 
					 | 
				
			||||||
password2,user2,uid2
 | 
					 | 
				
			||||||
password3,user3
 | 
					 | 
				
			||||||
password4
 | 
					 | 
				
			||||||
`); err == nil {
 | 
					 | 
				
			||||||
		t.Fatalf("unexpected non error")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestInsufficientColumnsPasswordFile(t *testing.T) {
 | 
					 | 
				
			||||||
	if _, err := newWithContents(t, "password4\n"); err == nil {
 | 
					 | 
				
			||||||
		t.Fatalf("unexpected non error")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newWithContents(t *testing.T, contents string) (auth *PasswordAuthenticator, err error) {
 | 
					 | 
				
			||||||
	f, err := ioutil.TempFile("", "passwordfile_test")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatalf("unexpected error creating passwordfile: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	f.Close()
 | 
					 | 
				
			||||||
	defer os.Remove(f.Name())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := ioutil.WriteFile(f.Name(), []byte(contents), 0700); err != nil {
 | 
					 | 
				
			||||||
		t.Fatalf("unexpected error writing passwordfile: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return NewCSV(f.Name())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,38 +0,0 @@
 | 
				
			|||||||
package(default_visibility = ["//visibility:public"])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
load(
 | 
					 | 
				
			||||||
    "@io_bazel_rules_go//go:def.bzl",
 | 
					 | 
				
			||||||
    "go_library",
 | 
					 | 
				
			||||||
    "go_test",
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_test(
 | 
					 | 
				
			||||||
    name = "go_default_test",
 | 
					 | 
				
			||||||
    srcs = ["basicauth_test.go"],
 | 
					 | 
				
			||||||
    embed = [":go_default_library"],
 | 
					 | 
				
			||||||
    deps = [
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
 | 
					 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_library(
 | 
					 | 
				
			||||||
    name = "go_default_library",
 | 
					 | 
				
			||||||
    srcs = ["basicauth.go"],
 | 
					 | 
				
			||||||
    importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth",
 | 
					 | 
				
			||||||
    importpath = "k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth",
 | 
					 | 
				
			||||||
    deps = ["//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "package-srcs",
 | 
					 | 
				
			||||||
    srcs = glob(["**"]),
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "all-srcs",
 | 
					 | 
				
			||||||
    srcs = [":package-srcs"],
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
@@ -1,53 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2014 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 basicauth
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"k8s.io/apiserver/pkg/authentication/authenticator"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Authenticator authenticates requests using basic auth
 | 
					 | 
				
			||||||
type Authenticator struct {
 | 
					 | 
				
			||||||
	auth authenticator.Password
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// New returns a request authenticator that validates credentials using the provided password authenticator
 | 
					 | 
				
			||||||
func New(auth authenticator.Password) *Authenticator {
 | 
					 | 
				
			||||||
	return &Authenticator{auth}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var errInvalidAuth = errors.New("invalid username/password combination")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AuthenticateRequest authenticates the request using the "Authorization: Basic" header in the request
 | 
					 | 
				
			||||||
func (a *Authenticator) AuthenticateRequest(req *http.Request) (*authenticator.Response, bool, error) {
 | 
					 | 
				
			||||||
	username, password, found := req.BasicAuth()
 | 
					 | 
				
			||||||
	if !found {
 | 
					 | 
				
			||||||
		return nil, false, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	resp, ok, err := a.auth.AuthenticatePassword(req.Context(), username, password)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// If the password authenticator didn't error, provide a default error
 | 
					 | 
				
			||||||
	if !ok && err == nil {
 | 
					 | 
				
			||||||
		err = errInvalidAuth
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return resp, ok, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,126 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2014 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 basicauth
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"k8s.io/apiserver/pkg/authentication/authenticator"
 | 
					 | 
				
			||||||
	"k8s.io/apiserver/pkg/authentication/user"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type testPassword struct {
 | 
					 | 
				
			||||||
	Username string
 | 
					 | 
				
			||||||
	Password string
 | 
					 | 
				
			||||||
	Called   bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	User user.Info
 | 
					 | 
				
			||||||
	OK   bool
 | 
					 | 
				
			||||||
	Err  error
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (t *testPassword) AuthenticatePassword(ctx context.Context, user, password string) (*authenticator.Response, bool, error) {
 | 
					 | 
				
			||||||
	t.Called = true
 | 
					 | 
				
			||||||
	t.Username = user
 | 
					 | 
				
			||||||
	t.Password = password
 | 
					 | 
				
			||||||
	return &authenticator.Response{User: t.User}, t.OK, t.Err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestBasicAuth(t *testing.T) {
 | 
					 | 
				
			||||||
	testCases := map[string]struct {
 | 
					 | 
				
			||||||
		Header   string
 | 
					 | 
				
			||||||
		Password testPassword
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ExpectedCalled   bool
 | 
					 | 
				
			||||||
		ExpectedUsername string
 | 
					 | 
				
			||||||
		ExpectedPassword string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ExpectedUser string
 | 
					 | 
				
			||||||
		ExpectedOK   bool
 | 
					 | 
				
			||||||
		ExpectedErr  bool
 | 
					 | 
				
			||||||
	}{
 | 
					 | 
				
			||||||
		"no auth": {},
 | 
					 | 
				
			||||||
		"empty password basic header": {
 | 
					 | 
				
			||||||
			ExpectedCalled:   true,
 | 
					 | 
				
			||||||
			ExpectedUsername: "user_with_empty_password",
 | 
					 | 
				
			||||||
			ExpectedPassword: "",
 | 
					 | 
				
			||||||
			ExpectedErr:      true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		"valid basic header": {
 | 
					 | 
				
			||||||
			ExpectedCalled:   true,
 | 
					 | 
				
			||||||
			ExpectedUsername: "myuser",
 | 
					 | 
				
			||||||
			ExpectedPassword: "mypassword:withcolon",
 | 
					 | 
				
			||||||
			ExpectedErr:      true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		"password auth returned user": {
 | 
					 | 
				
			||||||
			Password:         testPassword{User: &user.DefaultInfo{Name: "returneduser"}, OK: true},
 | 
					 | 
				
			||||||
			ExpectedCalled:   true,
 | 
					 | 
				
			||||||
			ExpectedUsername: "myuser",
 | 
					 | 
				
			||||||
			ExpectedPassword: "mypw",
 | 
					 | 
				
			||||||
			ExpectedUser:     "returneduser",
 | 
					 | 
				
			||||||
			ExpectedOK:       true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		"password auth returned error": {
 | 
					 | 
				
			||||||
			Password:         testPassword{Err: errors.New("auth error")},
 | 
					 | 
				
			||||||
			ExpectedCalled:   true,
 | 
					 | 
				
			||||||
			ExpectedUsername: "myuser",
 | 
					 | 
				
			||||||
			ExpectedPassword: "mypw",
 | 
					 | 
				
			||||||
			ExpectedErr:      true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for k, testCase := range testCases {
 | 
					 | 
				
			||||||
		password := testCase.Password
 | 
					 | 
				
			||||||
		auth := authenticator.Request(New(&password))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		req, _ := http.NewRequest("GET", "/", nil)
 | 
					 | 
				
			||||||
		if testCase.ExpectedUsername != "" || testCase.ExpectedPassword != "" {
 | 
					 | 
				
			||||||
			req.SetBasicAuth(testCase.ExpectedUsername, testCase.ExpectedPassword)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		resp, ok, err := auth.AuthenticateRequest(req)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if testCase.ExpectedCalled != password.Called {
 | 
					 | 
				
			||||||
			t.Errorf("%s: Expected called=%v, got %v", k, testCase.ExpectedCalled, password.Called)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if testCase.ExpectedUsername != password.Username {
 | 
					 | 
				
			||||||
			t.Errorf("%s: Expected called with username=%v, got %v", k, testCase.ExpectedUsername, password.Username)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if testCase.ExpectedPassword != password.Password {
 | 
					 | 
				
			||||||
			t.Errorf("%s: Expected called with password=%v, got %v", k, testCase.ExpectedPassword, password.Password)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if testCase.ExpectedErr != (err != nil) {
 | 
					 | 
				
			||||||
			t.Errorf("%s: Expected err=%v, got err=%v", k, testCase.ExpectedErr, err)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if testCase.ExpectedOK != ok {
 | 
					 | 
				
			||||||
			t.Errorf("%s: Expected ok=%v, got ok=%v", k, testCase.ExpectedOK, ok)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if testCase.ExpectedUser != "" && testCase.ExpectedUser != resp.User.GetName() {
 | 
					 | 
				
			||||||
			t.Errorf("%s: Expected user.GetName()=%v, got %v", k, testCase.ExpectedUser, resp.User.GetName())
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -13,7 +13,7 @@ spec:
 | 
				
			|||||||
    - /usr/local/bin/kube-apiserver --address=127.0.0.1 --etcd-servers=http://127.0.0.1:4001
 | 
					    - /usr/local/bin/kube-apiserver --address=127.0.0.1 --etcd-servers=http://127.0.0.1:4001
 | 
				
			||||||
      --cloud-provider=gce   --admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota
 | 
					      --cloud-provider=gce   --admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota
 | 
				
			||||||
      --service-cluster-ip-range=10.0.0.0/16 --client-ca-file=/srv/kubernetes/ca.crt
 | 
					      --service-cluster-ip-range=10.0.0.0/16 --client-ca-file=/srv/kubernetes/ca.crt
 | 
				
			||||||
      --basic-auth-file=/srv/kubernetes/basic_auth.csv --cluster-name=e2e-test-bburns
 | 
					      --cluster-name=e2e-test-bburns
 | 
				
			||||||
      --tls-cert-file=/srv/kubernetes/server.cert --tls-private-key-file=/srv/kubernetes/server.key
 | 
					      --tls-cert-file=/srv/kubernetes/server.cert --tls-private-key-file=/srv/kubernetes/server.key
 | 
				
			||||||
      --secure-port=443 --token-auth-file=/srv/kubernetes/known_tokens.csv  --v=2
 | 
					      --secure-port=443 --token-auth-file=/srv/kubernetes/known_tokens.csv  --v=2
 | 
				
			||||||
      --allow-privileged=False 1>>/var/log/kube-apiserver.log 2>&1
 | 
					      --allow-privileged=False 1>>/var/log/kube-apiserver.log 2>&1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -547,7 +547,6 @@ function compute-kube-apiserver-params {
 | 
				
			|||||||
	params+=" --client-ca-file=/etc/srv/kubernetes/ca.crt"
 | 
						params+=" --client-ca-file=/etc/srv/kubernetes/ca.crt"
 | 
				
			||||||
	params+=" --token-auth-file=/etc/srv/kubernetes/known_tokens.csv"
 | 
						params+=" --token-auth-file=/etc/srv/kubernetes/known_tokens.csv"
 | 
				
			||||||
	params+=" --secure-port=443"
 | 
						params+=" --secure-port=443"
 | 
				
			||||||
	params+=" --basic-auth-file=/etc/srv/kubernetes/basic_auth.csv"
 | 
					 | 
				
			||||||
	params+=" --target-ram-mb=$((NUM_NODES * 60))"
 | 
						params+=" --target-ram-mb=$((NUM_NODES * 60))"
 | 
				
			||||||
	params+=" --service-cluster-ip-range=${SERVICE_CLUSTER_IP_RANGE}"
 | 
						params+=" --service-cluster-ip-range=${SERVICE_CLUSTER_IP_RANGE}"
 | 
				
			||||||
	params+=" --admission-control=${CUSTOM_ADMISSION_PLUGINS}"
 | 
						params+=" --admission-control=${CUSTOM_ADMISSION_PLUGINS}"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							@@ -1401,8 +1401,6 @@ k8s.io/apiserver/plugin/pkg/audit/dynamic/enforced
 | 
				
			|||||||
k8s.io/apiserver/plugin/pkg/audit/log
 | 
					k8s.io/apiserver/plugin/pkg/audit/log
 | 
				
			||||||
k8s.io/apiserver/plugin/pkg/audit/truncate
 | 
					k8s.io/apiserver/plugin/pkg/audit/truncate
 | 
				
			||||||
k8s.io/apiserver/plugin/pkg/audit/webhook
 | 
					k8s.io/apiserver/plugin/pkg/audit/webhook
 | 
				
			||||||
k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile
 | 
					 | 
				
			||||||
k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth
 | 
					 | 
				
			||||||
k8s.io/apiserver/plugin/pkg/authenticator/token/oidc
 | 
					k8s.io/apiserver/plugin/pkg/authenticator/token/oidc
 | 
				
			||||||
k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest
 | 
					k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest
 | 
				
			||||||
k8s.io/apiserver/plugin/pkg/authenticator/token/webhook
 | 
					k8s.io/apiserver/plugin/pkg/authenticator/token/webhook
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user