From 7c0e48f544cfc4be4938f374444e6c0027562bb1 Mon Sep 17 00:00:00 2001 From: deads2k Date: Wed, 9 Nov 2016 13:14:20 -0500 Subject: [PATCH] split out authentication options --- cmd/kube-apiserver/app/options/options.go | 43 +-- cmd/kube-apiserver/app/server.go | 34 +- examples/apiserver/apiserver.go | 3 + .../app/options/options.go | 3 + .../cmd/federation-apiserver/app/server.go | 16 +- pkg/apiserver/authenticator/authn.go | 4 +- pkg/genericapiserver/config.go | 10 +- .../options/authentication.go | 321 ++++++++++++++++++ pkg/genericapiserver/options/authenticator.go | 35 -- .../options/server_run_options.go | 122 ++----- 10 files changed, 386 insertions(+), 205 deletions(-) create mode 100644 pkg/genericapiserver/options/authentication.go delete mode 100644 pkg/genericapiserver/options/authenticator.go diff --git a/cmd/kube-apiserver/app/options/options.go b/cmd/kube-apiserver/app/options/options.go index 2dcabb0e480..49e5c1d7609 100644 --- a/cmd/kube-apiserver/app/options/options.go +++ b/cmd/kube-apiserver/app/options/options.go @@ -35,17 +35,14 @@ type ServerRunOptions struct { Etcd *genericoptions.EtcdOptions SecureServing *genericoptions.SecureServingOptions InsecureServing *genericoptions.ServingOptions + Authentication *genericoptions.BuiltInAuthenticationOptions - AllowPrivileged bool - EventTTL time.Duration - KubeletConfig kubeletclient.KubeletClientConfig - MaxConnectionBytesPerSec int64 - SSHKeyfile string - SSHUser string - ServiceAccountKeyFiles []string - ServiceAccountLookup bool - WebhookTokenAuthnConfigFile string - WebhookTokenAuthnCacheTTL time.Duration + AllowPrivileged bool + EventTTL time.Duration + KubeletConfig kubeletclient.KubeletClientConfig + MaxConnectionBytesPerSec int64 + SSHKeyfile string + SSHUser string } // NewServerRunOptions creates a new ServerRunOptions object with default parameters @@ -55,6 +52,7 @@ func NewServerRunOptions() *ServerRunOptions { Etcd: genericoptions.NewEtcdOptions(), SecureServing: genericoptions.NewSecureServingOptions(), InsecureServing: genericoptions.NewInsecureServingOptions(), + Authentication: genericoptions.NewBuiltInAuthenticationOptions().WithAll(), EventTTL: 1 * time.Hour, KubeletConfig: kubeletclient.KubeletClientConfig{ @@ -68,7 +66,6 @@ func NewServerRunOptions() *ServerRunOptions { EnableHttps: true, HTTPTimeout: time.Duration(5) * time.Second, }, - WebhookTokenAuthnCacheTTL: 2 * time.Minute, } return &s } @@ -79,10 +76,11 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { s.GenericServerRunOptions.AddUniversalFlags(fs) s.Etcd.AddFlags(fs) - s.SecureServing.AddFlags(pflag.CommandLine) - s.SecureServing.AddDeprecatedFlags(pflag.CommandLine) - s.InsecureServing.AddFlags(pflag.CommandLine) - s.InsecureServing.AddDeprecatedFlags(pflag.CommandLine) + s.SecureServing.AddFlags(fs) + s.SecureServing.AddDeprecatedFlags(fs) + s.InsecureServing.AddFlags(fs) + s.InsecureServing.AddDeprecatedFlags(fs) + s.Authentication.AddFlags(fs) // Note: the weird ""+ in below lines seems to be the only way to get gofmt to // arrange these text blocks sensibly. Grrr. @@ -90,21 +88,6 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { fs.DurationVar(&s.EventTTL, "event-ttl", s.EventTTL, "Amount of time to retain events. Default is 1h.") - fs.StringArrayVar(&s.ServiceAccountKeyFiles, "service-account-key-file", s.ServiceAccountKeyFiles, ""+ - "File containing PEM-encoded x509 RSA or ECDSA private or public keys, used to verify "+ - "ServiceAccount tokens. If unspecified, --tls-private-key-file is used. "+ - "The specified file can contain multiple keys, and the flag can be specified multiple times with different files.") - - fs.BoolVar(&s.ServiceAccountLookup, "service-account-lookup", s.ServiceAccountLookup, - "If true, validate ServiceAccount tokens exist in etcd as part of authentication.") - - fs.StringVar(&s.WebhookTokenAuthnConfigFile, "authentication-token-webhook-config-file", s.WebhookTokenAuthnConfigFile, ""+ - "File with webhook configuration for token authentication in kubeconfig format. "+ - "The API server will query the remote service to determine authentication for bearer tokens.") - - fs.DurationVar(&s.WebhookTokenAuthnCacheTTL, "authentication-token-webhook-cache-ttl", s.WebhookTokenAuthnCacheTTL, - "The duration to cache responses from the webhook token authenticator. Default is 2m.") - fs.BoolVar(&s.AllowPrivileged, "allow-privileged", s.AllowPrivileged, "If true, allow privileged containers.") diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index 163d7c7f3f9..331926e33d5 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -55,7 +55,6 @@ import ( "k8s.io/kubernetes/pkg/master" "k8s.io/kubernetes/pkg/registry/cachesize" "k8s.io/kubernetes/pkg/runtime/schema" - "k8s.io/kubernetes/pkg/serviceaccount" utilerrors "k8s.io/kubernetes/pkg/util/errors" utilnet "k8s.io/kubernetes/pkg/util/net" "k8s.io/kubernetes/pkg/util/wait" @@ -94,6 +93,7 @@ func Run(s *options.ServerRunOptions) error { ApplyOptions(s.GenericServerRunOptions). // apply the options selected ApplySecureServingOptions(s.SecureServing). ApplyInsecureServingOptions(s.InsecureServing). + ApplyAuthenticationOptions(s.Authentication). Complete() // set default values based on the known values serviceIPRange, apiServerServiceIP, err := genericapiserver.DefaultServiceIPRange(s.GenericServerRunOptions.ServiceClusterIPRange) @@ -210,46 +210,26 @@ func Run(s *options.ServerRunOptions) error { } // Default to the private server key for service account token signing - if len(s.ServiceAccountKeyFiles) == 0 && s.SecureServing.ServerCert.CertKey.KeyFile != "" { + if len(s.Authentication.ServiceAccounts.KeyFiles) == 0 && s.SecureServing.ServerCert.CertKey.KeyFile != "" { if authenticator.IsValidServiceAccountKeyFile(s.SecureServing.ServerCert.CertKey.KeyFile) { - s.ServiceAccountKeyFiles = []string{s.SecureServing.ServerCert.CertKey.KeyFile} + s.Authentication.ServiceAccounts.KeyFiles = []string{s.SecureServing.ServerCert.CertKey.KeyFile} } else { glog.Warning("No TLS key provided, service account token authentication disabled") } } - var serviceAccountGetter serviceaccount.ServiceAccountTokenGetter - if s.ServiceAccountLookup { + authenticatorConfig := s.Authentication.ToAuthenticationConfig(s.SecureServing.ClientCA) + if s.Authentication.ServiceAccounts.Lookup { // If we need to look up service accounts and tokens, // go directly to etcd to avoid recursive auth insanity storageConfig, err := storageFactory.NewConfig(api.Resource("serviceaccounts")) if err != nil { glog.Fatalf("Unable to get serviceaccounts storage: %v", err) } - serviceAccountGetter = serviceaccountcontroller.NewGetterFromStorageInterface(storageConfig, storageFactory.ResourcePrefix(api.Resource("serviceaccounts")), storageFactory.ResourcePrefix(api.Resource("secrets"))) + authenticatorConfig.ServiceAccountTokenGetter = serviceaccountcontroller.NewGetterFromStorageInterface(storageConfig, storageFactory.ResourcePrefix(api.Resource("serviceaccounts")), storageFactory.ResourcePrefix(api.Resource("secrets"))) } - apiAuthenticator, securityDefinitions, err := authenticator.New(authenticator.AuthenticatorConfig{ - Anonymous: s.GenericServerRunOptions.AnonymousAuth, - AnyToken: s.GenericServerRunOptions.EnableAnyToken, - BasicAuthFile: s.GenericServerRunOptions.BasicAuthFile, - ClientCAFile: s.SecureServing.ClientCA, - TokenAuthFile: s.GenericServerRunOptions.TokenAuthFile, - OIDCIssuerURL: s.GenericServerRunOptions.OIDCIssuerURL, - OIDCClientID: s.GenericServerRunOptions.OIDCClientID, - OIDCCAFile: s.GenericServerRunOptions.OIDCCAFile, - OIDCUsernameClaim: s.GenericServerRunOptions.OIDCUsernameClaim, - OIDCGroupsClaim: s.GenericServerRunOptions.OIDCGroupsClaim, - ServiceAccountKeyFiles: s.ServiceAccountKeyFiles, - ServiceAccountLookup: s.ServiceAccountLookup, - ServiceAccountTokenGetter: serviceAccountGetter, - KeystoneURL: s.GenericServerRunOptions.KeystoneURL, - KeystoneCAFile: s.GenericServerRunOptions.KeystoneCAFile, - WebhookTokenAuthnConfigFile: s.WebhookTokenAuthnConfigFile, - WebhookTokenAuthnCacheTTL: s.WebhookTokenAuthnCacheTTL, - RequestHeaderConfig: s.GenericServerRunOptions.AuthenticationRequestHeaderConfig(), - }) - + apiAuthenticator, securityDefinitions, err := authenticator.New(authenticatorConfig) if err != nil { glog.Fatalf("Invalid Authentication Config: %v", err) } diff --git a/examples/apiserver/apiserver.go b/examples/apiserver/apiserver.go index 694676a6d94..cc4e4618dc7 100644 --- a/examples/apiserver/apiserver.go +++ b/examples/apiserver/apiserver.go @@ -60,6 +60,7 @@ type ServerRunOptions struct { Etcd *genericoptions.EtcdOptions SecureServing *genericoptions.SecureServingOptions InsecureServing *genericoptions.ServingOptions + Authentication *genericoptions.BuiltInAuthenticationOptions } func NewServerRunOptions() *ServerRunOptions { @@ -68,6 +69,7 @@ func NewServerRunOptions() *ServerRunOptions { Etcd: genericoptions.NewEtcdOptions(), SecureServing: genericoptions.NewSecureServingOptions(), InsecureServing: genericoptions.NewInsecureServingOptions(), + Authentication: genericoptions.NewBuiltInAuthenticationOptions().WithAll(), } s.InsecureServing.BindPort = InsecurePort s.SecureServing.ServingOptions.BindPort = SecurePort @@ -96,6 +98,7 @@ func (serverOptions *ServerRunOptions) Run(stopCh <-chan struct{}) error { ApplyOptions(serverOptions.GenericServerRunOptions). ApplySecureServingOptions(serverOptions.SecureServing). ApplyInsecureServingOptions(serverOptions.InsecureServing). + ApplyAuthenticationOptions(serverOptions.Authentication). Complete() if err := config.MaybeGenerateServingCerts(); err != nil { // this wasn't treated as fatal for this process before diff --git a/federation/cmd/federation-apiserver/app/options/options.go b/federation/cmd/federation-apiserver/app/options/options.go index 49084fb30f6..9b51e01f97d 100644 --- a/federation/cmd/federation-apiserver/app/options/options.go +++ b/federation/cmd/federation-apiserver/app/options/options.go @@ -31,6 +31,7 @@ type ServerRunOptions struct { Etcd *genericoptions.EtcdOptions SecureServing *genericoptions.SecureServingOptions InsecureServing *genericoptions.ServingOptions + Authentication *genericoptions.BuiltInAuthenticationOptions EventTTL time.Duration } @@ -42,6 +43,7 @@ func NewServerRunOptions() *ServerRunOptions { Etcd: genericoptions.NewEtcdOptions(), SecureServing: genericoptions.NewSecureServingOptions(), InsecureServing: genericoptions.NewInsecureServingOptions(), + Authentication: genericoptions.NewBuiltInAuthenticationOptions().WithAll(), EventTTL: 1 * time.Hour, } @@ -55,6 +57,7 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { s.Etcd.AddFlags(fs) s.SecureServing.AddFlags(fs) s.InsecureServing.AddFlags(fs) + s.Authentication.AddFlags(fs) fs.DurationVar(&s.EventTTL, "event-ttl", s.EventTTL, "Amount of time to retain events. Default is 1h.") diff --git a/federation/cmd/federation-apiserver/app/server.go b/federation/cmd/federation-apiserver/app/server.go index 89abe7bab72..9038fe8dfed 100644 --- a/federation/cmd/federation-apiserver/app/server.go +++ b/federation/cmd/federation-apiserver/app/server.go @@ -81,6 +81,7 @@ func Run(s *options.ServerRunOptions) error { ApplyOptions(s.GenericServerRunOptions). // apply the options selected ApplySecureServingOptions(s.SecureServing). ApplyInsecureServingOptions(s.InsecureServing). + ApplyAuthenticationOptions(s.Authentication). Complete() // set default values based on the known values if err := genericConfig.MaybeGenerateServingCerts(); err != nil { @@ -126,20 +127,7 @@ func Run(s *options.ServerRunOptions) error { storageFactory.SetEtcdLocation(groupResource, servers) } - apiAuthenticator, securityDefinitions, err := authenticator.New(authenticator.AuthenticatorConfig{ - Anonymous: s.GenericServerRunOptions.AnonymousAuth, - AnyToken: s.GenericServerRunOptions.EnableAnyToken, - BasicAuthFile: s.GenericServerRunOptions.BasicAuthFile, - ClientCAFile: s.SecureServing.ClientCA, - TokenAuthFile: s.GenericServerRunOptions.TokenAuthFile, - OIDCIssuerURL: s.GenericServerRunOptions.OIDCIssuerURL, - OIDCClientID: s.GenericServerRunOptions.OIDCClientID, - OIDCCAFile: s.GenericServerRunOptions.OIDCCAFile, - OIDCUsernameClaim: s.GenericServerRunOptions.OIDCUsernameClaim, - OIDCGroupsClaim: s.GenericServerRunOptions.OIDCGroupsClaim, - KeystoneURL: s.GenericServerRunOptions.KeystoneURL, - RequestHeaderConfig: s.GenericServerRunOptions.AuthenticationRequestHeaderConfig(), - }) + apiAuthenticator, securityDefinitions, err := authenticator.New(s.Authentication.ToAuthenticationConfig()) if err != nil { glog.Fatalf("Invalid Authentication Config: %v", err) } diff --git a/pkg/apiserver/authenticator/authn.go b/pkg/apiserver/authenticator/authn.go index 5719774ede2..65280ae677e 100644 --- a/pkg/apiserver/authenticator/authn.go +++ b/pkg/apiserver/authenticator/authn.go @@ -62,13 +62,15 @@ type AuthenticatorConfig struct { OIDCGroupsClaim string ServiceAccountKeyFiles []string ServiceAccountLookup bool - ServiceAccountTokenGetter serviceaccount.ServiceAccountTokenGetter KeystoneURL string KeystoneCAFile string WebhookTokenAuthnConfigFile string WebhookTokenAuthnCacheTTL time.Duration RequestHeaderConfig *RequestHeaderConfig + + // TODO, this is the only non-serializable part of the entire config. Factor it out into a clientconfig + ServiceAccountTokenGetter serviceaccount.ServiceAccountTokenGetter } // New returns an authenticator.Request or an error that supports the standard diff --git a/pkg/genericapiserver/config.go b/pkg/genericapiserver/config.go index 957d87b48a1..4c84a44ec32 100644 --- a/pkg/genericapiserver/config.go +++ b/pkg/genericapiserver/config.go @@ -282,6 +282,15 @@ func (c *Config) ApplyInsecureServingOptions(insecureServing *options.ServingOpt return c } +func (c *Config) ApplyAuthenticationOptions(o *options.BuiltInAuthenticationOptions) *Config { + if o == nil || o.PasswordFile == nil { + return c + } + + c.SupportsBasicAuth = len(o.PasswordFile.BasicAuthFile) > 0 + return c +} + // ApplyOptions applies the run options to the method receiver and returns self func (c *Config) ApplyOptions(options *options.ServerRunOptions) *Config { if len(options.AuditLogPath) != 0 { @@ -303,7 +312,6 @@ func (c *Config) ApplyOptions(options *options.ServerRunOptions) *Config { c.MaxRequestsInFlight = options.MaxRequestsInFlight c.MinRequestTimeout = options.MinRequestTimeout c.PublicAddress = options.AdvertiseAddress - c.SupportsBasicAuth = len(options.BasicAuthFile) > 0 return c } diff --git a/pkg/genericapiserver/options/authentication.go b/pkg/genericapiserver/options/authentication.go new file mode 100644 index 00000000000..e3f9a233b8c --- /dev/null +++ b/pkg/genericapiserver/options/authentication.go @@ -0,0 +1,321 @@ +/* +Copyright 2016 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 options + +import ( + "time" + + "github.com/spf13/pflag" + + "k8s.io/kubernetes/pkg/apiserver/authenticator" +) + +type BuiltInAuthenticationOptions struct { + Anonymous *AnonymousAuthenticationOptions + AnyToken *AnyTokenAuthenticationOptions + Keystone *KeystoneAuthenticationOptions + OIDC *OIDCAuthenticationOptions + PasswordFile *PasswordFileAuthenticationOptions + RequestHeader *RequestHeaderAuthenticationOptions + ServiceAccounts *ServiceAccountAuthenticationOptions + TokenFile *TokenFileAuthenticationOptions + WebHook *WebHookAuthenticationOptions +} + +type AnyTokenAuthenticationOptions struct { + Allow bool +} + +type AnonymousAuthenticationOptions struct { + Allow bool +} + +type KeystoneAuthenticationOptions struct { + URL string + CAFile string +} + +type OIDCAuthenticationOptions struct { + CAFile string + ClientID string + IssuerURL string + UsernameClaim string + GroupsClaim string +} + +type PasswordFileAuthenticationOptions struct { + BasicAuthFile string +} + +type RequestHeaderAuthenticationOptions struct { + UsernameHeaders []string + ClientCAFile string + AllowedNames []string +} + +type ServiceAccountAuthenticationOptions struct { + KeyFiles []string + Lookup bool +} + +type TokenFileAuthenticationOptions struct { + TokenFile string +} + +type WebHookAuthenticationOptions struct { + ConfigFile string + CacheTTL time.Duration +} + +func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions { + return &BuiltInAuthenticationOptions{} +} + +func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions { + return s. + WithAnyonymous(). + WithAnyToken(). + WithKeystone(). + WithOIDC(). + WithPasswordFile(). + WithRequestHeader(). + WithServiceAccounts(). + WithTokenFile(). + WithWebHook() +} + +func (s *BuiltInAuthenticationOptions) WithAnyonymous() *BuiltInAuthenticationOptions { + s.Anonymous = &AnonymousAuthenticationOptions{Allow: true} + return s +} + +func (s *BuiltInAuthenticationOptions) WithAnyToken() *BuiltInAuthenticationOptions { + s.AnyToken = &AnyTokenAuthenticationOptions{} + return s +} + +func (s *BuiltInAuthenticationOptions) WithKeystone() *BuiltInAuthenticationOptions { + s.Keystone = &KeystoneAuthenticationOptions{} + return s +} + +func (s *BuiltInAuthenticationOptions) WithOIDC() *BuiltInAuthenticationOptions { + s.OIDC = &OIDCAuthenticationOptions{} + return s +} + +func (s *BuiltInAuthenticationOptions) WithPasswordFile() *BuiltInAuthenticationOptions { + s.PasswordFile = &PasswordFileAuthenticationOptions{} + return s +} + +func (s *BuiltInAuthenticationOptions) WithRequestHeader() *BuiltInAuthenticationOptions { + s.RequestHeader = &RequestHeaderAuthenticationOptions{} + return s +} + +func (s *BuiltInAuthenticationOptions) WithServiceAccounts() *BuiltInAuthenticationOptions { + s.ServiceAccounts = &ServiceAccountAuthenticationOptions{} + return s +} + +func (s *BuiltInAuthenticationOptions) WithTokenFile() *BuiltInAuthenticationOptions { + s.TokenFile = &TokenFileAuthenticationOptions{} + return s +} + +func (s *BuiltInAuthenticationOptions) WithWebHook() *BuiltInAuthenticationOptions { + s.WebHook = &WebHookAuthenticationOptions{ + CacheTTL: 2 * time.Minute, + } + return s +} + +func (s *BuiltInAuthenticationOptions) Validate() []error { + allErrors := []error{} + return allErrors +} + +func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) { + if s.Anonymous != nil { + fs.BoolVar(&s.Anonymous.Allow, "anonymous-auth", s.Anonymous.Allow, ""+ + "Enables anonymous requests to the secure port of the API server. "+ + "Requests that are not rejected by another authentication method are treated as anonymous requests. "+ + "Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated.") + } + + if s.AnyToken != nil { + fs.BoolVar(&s.AnyToken.Allow, "insecure-allow-any-token", s.AnyToken.Allow, ""+ + "If set, your server will be INSECURE. Any token will be allowed and user information will be parsed "+ + "from the token as `username/group1,group2`") + + } + + if s.Keystone != nil { + fs.StringVar(&s.Keystone.URL, "experimental-keystone-url", s.Keystone.URL, + "If passed, activates the keystone authentication plugin.") + + fs.StringVar(&s.Keystone.CAFile, "experimental-keystone-ca-file", s.Keystone.CAFile, ""+ + "If set, the Keystone server's certificate will be verified by one of the authorities "+ + "in the experimental-keystone-ca-file, otherwise the host's root CA set will be used.") + } + + if s.OIDC != nil { + fs.StringVar(&s.OIDC.IssuerURL, "oidc-issuer-url", s.OIDC.IssuerURL, ""+ + "The URL of the OpenID issuer, only HTTPS scheme will be accepted. "+ + "If set, it will be used to verify the OIDC JSON Web Token (JWT).") + + fs.StringVar(&s.OIDC.ClientID, "oidc-client-id", s.OIDC.ClientID, + "The client ID for the OpenID Connect client, must be set if oidc-issuer-url is set.") + + fs.StringVar(&s.OIDC.CAFile, "oidc-ca-file", s.OIDC.CAFile, ""+ + "If set, the OpenID server's certificate will be verified by one of the authorities "+ + "in the oidc-ca-file, otherwise the host's root CA set will be used.") + + fs.StringVar(&s.OIDC.UsernameClaim, "oidc-username-claim", "sub", ""+ + "The OpenID claim to use as the user name. Note that claims other than the default ('sub') "+ + "is not guaranteed to be unique and immutable. This flag is experimental, please see "+ + "the authentication documentation for further details.") + + fs.StringVar(&s.OIDC.GroupsClaim, "oidc-groups-claim", "", ""+ + "If provided, the name of a custom OpenID Connect claim for specifying user groups. "+ + "The claim value is expected to be a string or array of strings. This flag is experimental, "+ + "please see the authentication documentation for further details.") + } + + 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.") + } + + if s.RequestHeader != nil { + fs.StringSliceVar(&s.RequestHeader.UsernameHeaders, "requestheader-username-headers", s.RequestHeader.UsernameHeaders, ""+ + "List of request headers to inspect for usernames. X-Remote-User is common.") + + fs.StringVar(&s.RequestHeader.ClientCAFile, "requestheader-client-ca-file", s.RequestHeader.ClientCAFile, ""+ + "Root certificate bundle to use to verify client certificates on incoming requests "+ + "before trusting usernames in headers specified by --requestheader-username-headers") + + fs.StringSliceVar(&s.RequestHeader.AllowedNames, "requestheader-allowed-names", s.RequestHeader.AllowedNames, ""+ + "List of client certificate common names to allow to provide usernames in headers "+ + "specified by --requestheader-username-headers. If empty, any client certificate validated "+ + "by the authorities in --requestheader-client-ca-file is allowed.") + } + + if s.ServiceAccounts != nil { + fs.StringArrayVar(&s.ServiceAccounts.KeyFiles, "service-account-key-file", s.ServiceAccounts.KeyFiles, ""+ + "File containing PEM-encoded x509 RSA or ECDSA private or public keys, used to verify "+ + "ServiceAccount tokens. If unspecified, --tls-private-key-file is used. "+ + "The specified file can contain multiple keys, and the flag can be specified multiple times with different files.") + + fs.BoolVar(&s.ServiceAccounts.Lookup, "service-account-lookup", s.ServiceAccounts.Lookup, + "If true, validate ServiceAccount tokens exist in etcd as part of authentication.") + } + + if s.TokenFile != nil { + fs.StringVar(&s.TokenFile.TokenFile, "token-auth-file", s.TokenFile.TokenFile, ""+ + "If set, the file that will be used to secure the secure port of the API server "+ + "via token authentication.") + } + + if s.WebHook != nil { + fs.StringVar(&s.WebHook.ConfigFile, "authentication-token-webhook-config-file", s.WebHook.ConfigFile, ""+ + "File with webhook configuration for token authentication in kubeconfig format. "+ + "The API server will query the remote service to determine authentication for bearer tokens.") + + fs.DurationVar(&s.WebHook.CacheTTL, "authentication-token-webhook-cache-ttl", s.WebHook.CacheTTL, + "The duration to cache responses from the webhook token authenticator. Default is 2m.") + } +} + +func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() authenticator.AuthenticatorConfig { + ret := authenticator.AuthenticatorConfig{} + if s.Anonymous != nil { + ret.Anonymous = s.Anonymous.Allow + } + + if s.AnyToken != nil { + ret.AnyToken = s.AnyToken.Allow + } + + if s.Keystone != nil { + ret.KeystoneURL = s.Keystone.URL + ret.KeystoneCAFile = s.Keystone.CAFile + } + + if s.OIDC != nil { + ret.OIDCCAFile = s.OIDC.CAFile + ret.OIDCClientID = s.OIDC.ClientID + ret.OIDCGroupsClaim = s.OIDC.GroupsClaim + ret.OIDCIssuerURL = s.OIDC.IssuerURL + ret.OIDCUsernameClaim = s.OIDC.UsernameClaim + } + + if s.PasswordFile != nil { + ret.BasicAuthFile = s.PasswordFile.BasicAuthFile + } + + if s.RequestHeader != nil { + ret.RequestHeaderConfig = s.RequestHeader.AuthenticationRequestHeaderConfig() + } + + if s.ServiceAccounts != nil { + ret.ServiceAccountKeyFiles = s.ServiceAccounts.KeyFiles + ret.ServiceAccountLookup = s.ServiceAccounts.Lookup + } + + if s.TokenFile != nil { + ret.TokenAuthFile = s.TokenFile.TokenFile + } + + if s.WebHook != nil { + ret.WebhookTokenAuthnConfigFile = s.WebHook.ConfigFile + ret.WebhookTokenAuthnCacheTTL = s.WebHook.CacheTTL + } + + return ret +} + +// AuthenticationRequestHeaderConfig returns an authenticator config object for these options +// if necessary. nil otherwise. +func (s *RequestHeaderAuthenticationOptions) AuthenticationRequestHeaderConfig() *authenticator.RequestHeaderConfig { + if len(s.UsernameHeaders) == 0 { + return nil + } + + return &authenticator.RequestHeaderConfig{ + UsernameHeaders: s.UsernameHeaders, + ClientCA: s.ClientCAFile, + AllowedClientNames: s.AllowedNames, + } +} + +type DelegatingAuthenticationOptions struct { +} + +func NewDelegatingAuthenticationOptions() *DelegatingAuthenticationOptions { + return &DelegatingAuthenticationOptions{} +} + +func (s *DelegatingAuthenticationOptions) Validate() []error { + allErrors := []error{} + return allErrors +} + +func (s *DelegatingAuthenticationOptions) AddFlags(fs *pflag.FlagSet) { +} diff --git a/pkg/genericapiserver/options/authenticator.go b/pkg/genericapiserver/options/authenticator.go deleted file mode 100644 index 58f943050e4..00000000000 --- a/pkg/genericapiserver/options/authenticator.go +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright 2016 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 options - -import ( - "k8s.io/kubernetes/pkg/apiserver/authenticator" -) - -// AuthenticationRequestHeaderConfig returns an authenticator config object for these options -// if necessary. nil otherwise. -func (s *ServerRunOptions) AuthenticationRequestHeaderConfig() *authenticator.RequestHeaderConfig { - if len(s.RequestHeaderUsernameHeaders) == 0 { - return nil - } - - return &authenticator.RequestHeaderConfig{ - UsernameHeaders: s.RequestHeaderUsernameHeaders, - ClientCA: s.RequestHeaderClientCAFile, - AllowedClientNames: s.RequestHeaderAllowedNames, - } -} diff --git a/pkg/genericapiserver/options/server_run_options.go b/pkg/genericapiserver/options/server_run_options.go index e7220868cf6..c123bdde4c9 100644 --- a/pkg/genericapiserver/options/server_run_options.go +++ b/pkg/genericapiserver/options/server_run_options.go @@ -63,58 +63,43 @@ type ServerRunOptions struct { AuthorizationWebhookCacheUnauthorizedTTL time.Duration AuthorizationRBACSuperUser string - AnonymousAuth bool - BasicAuthFile string - CloudConfigFile string - CloudProvider string - CorsAllowedOriginList []string - DefaultStorageMediaType string - DeleteCollectionWorkers int - AuditLogPath string - AuditLogMaxAge int - AuditLogMaxBackups int - AuditLogMaxSize int - EnableGarbageCollection bool - EnableProfiling bool - EnableContentionProfiling bool - EnableSwaggerUI bool - EnableWatchCache bool - ExternalHost string - KeystoneURL string - KeystoneCAFile string - KubernetesServiceNodePort int - LongRunningRequestRE string - MasterCount int - MasterServiceNamespace string - MaxRequestsInFlight int - MinRequestTimeout int - OIDCCAFile string - OIDCClientID string - OIDCIssuerURL string - OIDCUsernameClaim string - OIDCGroupsClaim string - RequestHeaderUsernameHeaders []string - RequestHeaderClientCAFile string - RequestHeaderAllowedNames []string - RuntimeConfig config.ConfigurationMap - ServiceClusterIPRange net.IPNet // TODO: make this a list - ServiceNodePortRange utilnet.PortRange - StorageVersions string + CloudConfigFile string + CloudProvider string + CorsAllowedOriginList []string + DefaultStorageMediaType string + DeleteCollectionWorkers int + AuditLogPath string + AuditLogMaxAge int + AuditLogMaxBackups int + AuditLogMaxSize int + EnableGarbageCollection bool + EnableProfiling bool + EnableContentionProfiling bool + EnableSwaggerUI bool + EnableWatchCache bool + ExternalHost string + KubernetesServiceNodePort int + LongRunningRequestRE string + MasterCount int + MasterServiceNamespace string + MaxRequestsInFlight int + MinRequestTimeout int + RuntimeConfig config.ConfigurationMap + ServiceClusterIPRange net.IPNet // TODO: make this a list + ServiceNodePortRange utilnet.PortRange + StorageVersions string // The default values for StorageVersions. StorageVersions overrides // these; you can change this if you want to change the defaults (e.g., // for testing). This is not actually exposed as a flag. DefaultStorageVersions string TargetRAMMB int TLSCAFile string - TokenAuthFile string - EnableAnyToken bool WatchCacheSizes []string } func NewServerRunOptions() *ServerRunOptions { return &ServerRunOptions{ AdmissionControl: "AlwaysAdmit", - AnonymousAuth: true, AuthorizationMode: "AlwaysAllow", AuthorizationWebhookCacheAuthorizedTTL: 5 * time.Minute, AuthorizationWebhookCacheUnauthorizedTTL: 30 * time.Second, @@ -247,15 +232,6 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) { "If specified, a username which avoids RBAC authorization checks and role binding "+ "privilege escalation checks, to be used with --authorization-mode=RBAC.") - fs.BoolVar(&s.AnonymousAuth, "anonymous-auth", s.AnonymousAuth, ""+ - "Enables anonymous requests to the secure port of the API server. "+ - "Requests that are not rejected by another authentication method are treated as anonymous requests. "+ - "Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated.") - - fs.StringVar(&s.BasicAuthFile, "basic-auth-file", s.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.StringVar(&s.CloudProvider, "cloud-provider", s.CloudProvider, "The provider for cloud services. Empty string for no provider.") @@ -304,13 +280,6 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) { fs.StringVar(&s.ExternalHost, "external-hostname", s.ExternalHost, "The hostname to use when generating externalized URLs for this master (e.g. Swagger API Docs).") - fs.StringVar(&s.KeystoneURL, "experimental-keystone-url", s.KeystoneURL, - "If passed, activates the keystone authentication plugin.") - - fs.StringVar(&s.KeystoneCAFile, "experimental-keystone-ca-file", s.KeystoneCAFile, ""+ - "If set, the Keystone server's certificate will be verified by one of the authorities "+ - "in the experimental-keystone-ca-file, otherwise the host's root CA set will be used.") - // See #14282 for details on how to test/try this option out. // TODO: remove this comment once this option is tested in CI. fs.IntVar(&s.KubernetesServiceNodePort, "kubernetes-service-node-port", s.KubernetesServiceNodePort, ""+ @@ -338,39 +307,6 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) { "handler, which picks a randomized value above this number as the connection timeout, "+ "to spread out load.") - fs.StringVar(&s.OIDCIssuerURL, "oidc-issuer-url", s.OIDCIssuerURL, ""+ - "The URL of the OpenID issuer, only HTTPS scheme will be accepted. "+ - "If set, it will be used to verify the OIDC JSON Web Token (JWT).") - - fs.StringVar(&s.OIDCClientID, "oidc-client-id", s.OIDCClientID, - "The client ID for the OpenID Connect client, must be set if oidc-issuer-url is set.") - - fs.StringVar(&s.OIDCCAFile, "oidc-ca-file", s.OIDCCAFile, ""+ - "If set, the OpenID server's certificate will be verified by one of the authorities "+ - "in the oidc-ca-file, otherwise the host's root CA set will be used.") - - fs.StringVar(&s.OIDCUsernameClaim, "oidc-username-claim", "sub", ""+ - "The OpenID claim to use as the user name. Note that claims other than the default ('sub') "+ - "is not guaranteed to be unique and immutable. This flag is experimental, please see "+ - "the authentication documentation for further details.") - - fs.StringVar(&s.OIDCGroupsClaim, "oidc-groups-claim", "", ""+ - "If provided, the name of a custom OpenID Connect claim for specifying user groups. "+ - "The claim value is expected to be a string or array of strings. This flag is experimental, "+ - "please see the authentication documentation for further details.") - - fs.StringSliceVar(&s.RequestHeaderUsernameHeaders, "requestheader-username-headers", s.RequestHeaderUsernameHeaders, ""+ - "List of request headers to inspect for usernames. X-Remote-User is common.") - - fs.StringVar(&s.RequestHeaderClientCAFile, "requestheader-client-ca-file", s.RequestHeaderClientCAFile, ""+ - "Root certificate bundle to use to verify client certificates on incoming requests "+ - "before trusting usernames in headers specified by --requestheader-username-headers") - - fs.StringSliceVar(&s.RequestHeaderAllowedNames, "requestheader-allowed-names", s.RequestHeaderAllowedNames, ""+ - "List of client certificate common names to allow to provide usernames in headers "+ - "specified by --requestheader-username-headers. If empty, any client certificate validated "+ - "by the authorities in --requestheader-client-ca-file is allowed.") - fs.Var(&s.RuntimeConfig, "runtime-config", ""+ "A set of key=value pairs that describe runtime configuration that may be passed "+ "to apiserver. apis/ key can be used to turn on/off specific api versions. "+ @@ -406,14 +342,6 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) { "It defaults to a list of preferred versions of all registered groups, "+ "which is derived from the KUBE_API_VERSIONS environment variable.") - fs.StringVar(&s.TokenAuthFile, "token-auth-file", s.TokenAuthFile, ""+ - "If set, the file that will be used to secure the secure port of the API server "+ - "via token authentication.") - - fs.BoolVar(&s.EnableAnyToken, "insecure-allow-any-token", s.EnableAnyToken, ""+ - "If set, your server will be INSECURE. Any token will be allowed and user information will be parsed "+ - "from the token as `username/group1,group2`") - fs.StringSliceVar(&s.WatchCacheSizes, "watch-cache-sizes", s.WatchCacheSizes, ""+ "List of watch cache sizes for every resource (pods, nodes, etc.), comma separated. "+ "The individual override format: resource#size, where size is a number. It takes effect "+