Merge pull request #93101 from yiduyangyi/fix-golint

fix golint failures in pkg/kubeapiserver/options
This commit is contained in:
Kubernetes Prow Robot 2020-08-28 08:03:50 -07:00 committed by GitHub
commit eae3294b8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 168 additions and 139 deletions

View File

@ -93,7 +93,6 @@ pkg/controller/volume/persistentvolume
pkg/controller/volume/persistentvolume/config/v1alpha1 pkg/controller/volume/persistentvolume/config/v1alpha1
pkg/features pkg/features
pkg/kubeapiserver pkg/kubeapiserver
pkg/kubeapiserver/options
pkg/kubectl/cmd/convert pkg/kubectl/cmd/convert
pkg/kubelet/apis/config/v1beta1 pkg/kubelet/apis/config/v1beta1
pkg/kubelet/cm pkg/kubelet/cm

View File

@ -37,6 +37,7 @@ import (
cliflag "k8s.io/component-base/cli/flag" cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog/v2" "k8s.io/klog/v2"
openapicommon "k8s.io/kube-openapi/pkg/common" openapicommon "k8s.io/kube-openapi/pkg/common"
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount" serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator" kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
@ -44,6 +45,7 @@ import (
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap"
) )
// BuiltInAuthenticationOptions contains all build-in authentication options for API Server
type BuiltInAuthenticationOptions struct { type BuiltInAuthenticationOptions struct {
APIAudiences []string APIAudiences []string
Anonymous *AnonymousAuthenticationOptions Anonymous *AnonymousAuthenticationOptions
@ -59,14 +61,17 @@ type BuiltInAuthenticationOptions struct {
TokenFailureCacheTTL time.Duration TokenFailureCacheTTL time.Duration
} }
// AnonymousAuthenticationOptions contains anonymous authentication options for API Server
type AnonymousAuthenticationOptions struct { type AnonymousAuthenticationOptions struct {
Allow bool Allow bool
} }
// BootstrapTokenAuthenticationOptions contains bootstrap token authentication options for API Server
type BootstrapTokenAuthenticationOptions struct { type BootstrapTokenAuthenticationOptions struct {
Enable bool Enable bool
} }
// OIDCAuthenticationOptions contains OIDC authentication options for API Server
type OIDCAuthenticationOptions struct { type OIDCAuthenticationOptions struct {
CAFile string CAFile string
ClientID string ClientID string
@ -79,6 +84,7 @@ type OIDCAuthenticationOptions struct {
RequiredClaims map[string]string RequiredClaims map[string]string
} }
// ServiceAccountAuthenticationOptions contains service account authentication options for API Server
type ServiceAccountAuthenticationOptions struct { type ServiceAccountAuthenticationOptions struct {
KeyFiles []string KeyFiles []string
Lookup bool Lookup bool
@ -88,16 +94,19 @@ type ServiceAccountAuthenticationOptions struct {
ExtendExpiration bool ExtendExpiration bool
} }
// TokenFileAuthenticationOptions contains token file authentication options for API Server
type TokenFileAuthenticationOptions struct { type TokenFileAuthenticationOptions struct {
TokenFile string TokenFile string
} }
// WebHookAuthenticationOptions contains web hook authentication options for API Server
type WebHookAuthenticationOptions struct { type WebHookAuthenticationOptions struct {
ConfigFile string ConfigFile string
Version string Version string
CacheTTL time.Duration CacheTTL time.Duration
} }
// NewBuiltInAuthenticationOptions create a new BuiltInAuthenticationOptions, just set default token cache TTL
func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions { func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions {
return &BuiltInAuthenticationOptions{ return &BuiltInAuthenticationOptions{
TokenSuccessCacheTTL: 10 * time.Second, TokenSuccessCacheTTL: 10 * time.Second,
@ -105,8 +114,9 @@ func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions {
} }
} }
func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions { // WithAll set default value for every build-in authentication option
return s. func (o *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions {
return o.
WithAnonymous(). WithAnonymous().
WithBootstrapToken(). WithBootstrapToken().
WithClientCert(). WithClientCert().
@ -117,87 +127,95 @@ func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions {
WithWebHook() WithWebHook()
} }
func (s *BuiltInAuthenticationOptions) WithAnonymous() *BuiltInAuthenticationOptions { // WithAnonymous set default value for anonymous authentication
s.Anonymous = &AnonymousAuthenticationOptions{Allow: true} func (o *BuiltInAuthenticationOptions) WithAnonymous() *BuiltInAuthenticationOptions {
return s o.Anonymous = &AnonymousAuthenticationOptions{Allow: true}
return o
} }
func (s *BuiltInAuthenticationOptions) WithBootstrapToken() *BuiltInAuthenticationOptions { // WithBootstrapToken set default value for bootstrap token authentication
s.BootstrapToken = &BootstrapTokenAuthenticationOptions{} func (o *BuiltInAuthenticationOptions) WithBootstrapToken() *BuiltInAuthenticationOptions {
return s o.BootstrapToken = &BootstrapTokenAuthenticationOptions{}
return o
} }
func (s *BuiltInAuthenticationOptions) WithClientCert() *BuiltInAuthenticationOptions { // WithClientCert set default value for client cert
s.ClientCert = &genericoptions.ClientCertAuthenticationOptions{} func (o *BuiltInAuthenticationOptions) WithClientCert() *BuiltInAuthenticationOptions {
return s o.ClientCert = &genericoptions.ClientCertAuthenticationOptions{}
return o
} }
func (s *BuiltInAuthenticationOptions) WithOIDC() *BuiltInAuthenticationOptions { // WithOIDC set default value for OIDC authentication
s.OIDC = &OIDCAuthenticationOptions{} func (o *BuiltInAuthenticationOptions) WithOIDC() *BuiltInAuthenticationOptions {
return s o.OIDC = &OIDCAuthenticationOptions{}
return o
} }
func (s *BuiltInAuthenticationOptions) WithRequestHeader() *BuiltInAuthenticationOptions { // WithRequestHeader set default value for request header authentication
s.RequestHeader = &genericoptions.RequestHeaderAuthenticationOptions{} func (o *BuiltInAuthenticationOptions) WithRequestHeader() *BuiltInAuthenticationOptions {
return s o.RequestHeader = &genericoptions.RequestHeaderAuthenticationOptions{}
return o
} }
func (s *BuiltInAuthenticationOptions) WithServiceAccounts() *BuiltInAuthenticationOptions { // WithServiceAccounts set default value for service account authentication
s.ServiceAccounts = &ServiceAccountAuthenticationOptions{Lookup: true} func (o *BuiltInAuthenticationOptions) WithServiceAccounts() *BuiltInAuthenticationOptions {
return s o.ServiceAccounts = &ServiceAccountAuthenticationOptions{Lookup: true}
return o
} }
func (s *BuiltInAuthenticationOptions) WithTokenFile() *BuiltInAuthenticationOptions { // WithTokenFile set default value for token file authentication
s.TokenFile = &TokenFileAuthenticationOptions{} func (o *BuiltInAuthenticationOptions) WithTokenFile() *BuiltInAuthenticationOptions {
return s o.TokenFile = &TokenFileAuthenticationOptions{}
return o
} }
func (s *BuiltInAuthenticationOptions) WithWebHook() *BuiltInAuthenticationOptions { // WithWebHook set default value for web hook authentication
s.WebHook = &WebHookAuthenticationOptions{ func (o *BuiltInAuthenticationOptions) WithWebHook() *BuiltInAuthenticationOptions {
o.WebHook = &WebHookAuthenticationOptions{
Version: "v1beta1", Version: "v1beta1",
CacheTTL: 2 * time.Minute, CacheTTL: 2 * time.Minute,
} }
return s return o
} }
// Validate checks invalid config combination // Validate checks invalid config combination
func (s *BuiltInAuthenticationOptions) Validate() []error { func (o *BuiltInAuthenticationOptions) Validate() []error {
allErrors := []error{} allErrors := []error{}
if s.OIDC != nil && (len(s.OIDC.IssuerURL) > 0) != (len(s.OIDC.ClientID) > 0) { if o.OIDC != nil && (len(o.OIDC.IssuerURL) > 0) != (len(o.OIDC.ClientID) > 0) {
allErrors = append(allErrors, fmt.Errorf("oidc-issuer-url and oidc-client-id should be specified together")) allErrors = append(allErrors, fmt.Errorf("oidc-issuer-url and oidc-client-id should be specified together"))
} }
if s.ServiceAccounts != nil && len(s.ServiceAccounts.Issuer) > 0 && strings.Contains(s.ServiceAccounts.Issuer, ":") { if o.ServiceAccounts != nil && len(o.ServiceAccounts.Issuer) > 0 && strings.Contains(o.ServiceAccounts.Issuer, ":") {
if _, err := url.Parse(s.ServiceAccounts.Issuer); err != nil { if _, err := url.Parse(o.ServiceAccounts.Issuer); err != nil {
allErrors = append(allErrors, fmt.Errorf("service-account-issuer contained a ':' but was not a valid URL: %v", err)) allErrors = append(allErrors, fmt.Errorf("service-account-issuer contained a ':' but was not a valid URL: %v", err))
} }
} }
if s.ServiceAccounts != nil && utilfeature.DefaultFeatureGate.Enabled(features.BoundServiceAccountTokenVolume) { if o.ServiceAccounts != nil && utilfeature.DefaultFeatureGate.Enabled(features.BoundServiceAccountTokenVolume) {
if !utilfeature.DefaultFeatureGate.Enabled(features.TokenRequest) || !utilfeature.DefaultFeatureGate.Enabled(features.TokenRequestProjection) { if !utilfeature.DefaultFeatureGate.Enabled(features.TokenRequest) || !utilfeature.DefaultFeatureGate.Enabled(features.TokenRequestProjection) {
allErrors = append(allErrors, errors.New("if the BoundServiceAccountTokenVolume feature is enabled,"+ allErrors = append(allErrors, errors.New("if the BoundServiceAccountTokenVolume feature is enabled,"+
" the TokenRequest and TokenRequestProjection features must also be enabled")) " the TokenRequest and TokenRequestProjection features must also be enabled"))
} }
if len(s.ServiceAccounts.Issuer) == 0 { if len(o.ServiceAccounts.Issuer) == 0 {
allErrors = append(allErrors, errors.New("service-account-issuer is a required flag when BoundServiceAccountTokenVolume is enabled")) allErrors = append(allErrors, errors.New("service-account-issuer is a required flag when BoundServiceAccountTokenVolume is enabled"))
} }
if len(s.ServiceAccounts.KeyFiles) == 0 { if len(o.ServiceAccounts.KeyFiles) == 0 {
allErrors = append(allErrors, errors.New("service-account-key-file is a required flag when BoundServiceAccountTokenVolume is enabled")) allErrors = append(allErrors, errors.New("service-account-key-file is a required flag when BoundServiceAccountTokenVolume is enabled"))
} }
} }
if s.ServiceAccounts != nil { if o.ServiceAccounts != nil {
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceAccountIssuerDiscovery) { if utilfeature.DefaultFeatureGate.Enabled(features.ServiceAccountIssuerDiscovery) {
// Validate the JWKS URI when it is explicitly set. // Validate the JWKS URI when it is explicitly set.
// When unset, it is later derived from ExternalHost. // When unset, it is later derived from ExternalHost.
if s.ServiceAccounts.JWKSURI != "" { if o.ServiceAccounts.JWKSURI != "" {
if u, err := url.Parse(s.ServiceAccounts.JWKSURI); err != nil { if u, err := url.Parse(o.ServiceAccounts.JWKSURI); err != nil {
allErrors = append(allErrors, fmt.Errorf("service-account-jwks-uri must be a valid URL: %v", err)) allErrors = append(allErrors, fmt.Errorf("service-account-jwks-uri must be a valid URL: %v", err))
} else if u.Scheme != "https" { } else if u.Scheme != "https" {
allErrors = append(allErrors, fmt.Errorf("service-account-jwks-uri requires https scheme, parsed as: %v", u.String())) allErrors = append(allErrors, fmt.Errorf("service-account-jwks-uri requires https scheme, parsed as: %v", u.String()))
} }
} }
} else if len(s.ServiceAccounts.JWKSURI) > 0 { } else if len(o.ServiceAccounts.JWKSURI) > 0 {
allErrors = append(allErrors, fmt.Errorf("service-account-jwks-uri may only be set when the ServiceAccountIssuerDiscovery feature gate is enabled")) allErrors = append(allErrors, fmt.Errorf("service-account-jwks-uri may only be set when the ServiceAccountIssuerDiscovery feature gate is enabled"))
} }
} }
@ -205,88 +223,89 @@ func (s *BuiltInAuthenticationOptions) Validate() []error {
return allErrors return allErrors
} }
func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) { // AddFlags returns flags of authentication for a API Server
fs.StringSliceVar(&s.APIAudiences, "api-audiences", s.APIAudiences, ""+ func (o *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringSliceVar(&o.APIAudiences, "api-audiences", o.APIAudiences, ""+
"Identifiers of the API. The service account token authenticator will validate that "+ "Identifiers of the API. The service account token authenticator will validate that "+
"tokens used against the API are bound to at least one of these audiences. If the "+ "tokens used against the API are bound to at least one of these audiences. If the "+
"--service-account-issuer flag is configured and this flag is not, this field "+ "--service-account-issuer flag is configured and this flag is not, this field "+
"defaults to a single element list containing the issuer URL.") "defaults to a single element list containing the issuer URL.")
if s.Anonymous != nil { if o.Anonymous != nil {
fs.BoolVar(&s.Anonymous.Allow, "anonymous-auth", s.Anonymous.Allow, ""+ fs.BoolVar(&o.Anonymous.Allow, "anonymous-auth", o.Anonymous.Allow, ""+
"Enables anonymous requests to the secure port of the API server. "+ "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. "+ "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.") "Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated.")
} }
if s.BootstrapToken != nil { if o.BootstrapToken != nil {
fs.BoolVar(&s.BootstrapToken.Enable, "enable-bootstrap-token-auth", s.BootstrapToken.Enable, ""+ fs.BoolVar(&o.BootstrapToken.Enable, "enable-bootstrap-token-auth", o.BootstrapToken.Enable, ""+
"Enable to allow secrets of type 'bootstrap.kubernetes.io/token' in the 'kube-system' "+ "Enable to allow secrets of type 'bootstrap.kubernetes.io/token' in the 'kube-system' "+
"namespace to be used for TLS bootstrapping authentication.") "namespace to be used for TLS bootstrapping authentication.")
} }
if s.ClientCert != nil { if o.ClientCert != nil {
s.ClientCert.AddFlags(fs) o.ClientCert.AddFlags(fs)
} }
if s.OIDC != nil { if o.OIDC != nil {
fs.StringVar(&s.OIDC.IssuerURL, "oidc-issuer-url", s.OIDC.IssuerURL, ""+ fs.StringVar(&o.OIDC.IssuerURL, "oidc-issuer-url", o.OIDC.IssuerURL, ""+
"The URL of the OpenID issuer, only HTTPS scheme will be accepted. "+ "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).") "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, fs.StringVar(&o.OIDC.ClientID, "oidc-client-id", o.OIDC.ClientID,
"The client ID for the OpenID Connect client, must be set if oidc-issuer-url is set.") "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, ""+ fs.StringVar(&o.OIDC.CAFile, "oidc-ca-file", o.OIDC.CAFile, ""+
"If set, the OpenID server's certificate will be verified by one of the authorities "+ "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.") "in the oidc-ca-file, otherwise the host's root CA set will be used.")
fs.StringVar(&s.OIDC.UsernameClaim, "oidc-username-claim", "sub", ""+ fs.StringVar(&o.OIDC.UsernameClaim, "oidc-username-claim", "sub", ""+
"The OpenID claim to use as the user name. Note that claims other than the default ('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 "+ "is not guaranteed to be unique and immutable. This flag is experimental, please see "+
"the authentication documentation for further details.") "the authentication documentation for further details.")
fs.StringVar(&s.OIDC.UsernamePrefix, "oidc-username-prefix", "", ""+ fs.StringVar(&o.OIDC.UsernamePrefix, "oidc-username-prefix", "", ""+
"If provided, all usernames will be prefixed with this value. If not provided, "+ "If provided, all usernames will be prefixed with this value. If not provided, "+
"username claims other than 'email' are prefixed by the issuer URL to avoid "+ "username claims other than 'email' are prefixed by the issuer URL to avoid "+
"clashes. To skip any prefixing, provide the value '-'.") "clashes. To skip any prefixing, provide the value '-'.")
fs.StringVar(&s.OIDC.GroupsClaim, "oidc-groups-claim", "", ""+ fs.StringVar(&o.OIDC.GroupsClaim, "oidc-groups-claim", "", ""+
"If provided, the name of a custom OpenID Connect claim for specifying user groups. "+ "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, "+ "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.") "please see the authentication documentation for further details.")
fs.StringVar(&s.OIDC.GroupsPrefix, "oidc-groups-prefix", "", ""+ fs.StringVar(&o.OIDC.GroupsPrefix, "oidc-groups-prefix", "", ""+
"If provided, all groups will be prefixed with this value to prevent conflicts with "+ "If provided, all groups will be prefixed with this value to prevent conflicts with "+
"other authentication strategies.") "other authentication strategies.")
fs.StringSliceVar(&s.OIDC.SigningAlgs, "oidc-signing-algs", []string{"RS256"}, ""+ fs.StringSliceVar(&o.OIDC.SigningAlgs, "oidc-signing-algs", []string{"RS256"}, ""+
"Comma-separated list of allowed JOSE asymmetric signing algorithms. JWTs with a "+ "Comma-separated list of allowed JOSE asymmetric signing algorithms. JWTs with a "+
"'alg' header value not in this list will be rejected. "+ "'alg' header value not in this list will be rejected. "+
"Values are defined by RFC 7518 https://tools.ietf.org/html/rfc7518#section-3.1.") "Values are defined by RFC 7518 https://tools.ietf.org/html/rfc7518#section-3.1.")
fs.Var(cliflag.NewMapStringStringNoSplit(&s.OIDC.RequiredClaims), "oidc-required-claim", ""+ fs.Var(cliflag.NewMapStringStringNoSplit(&o.OIDC.RequiredClaims), "oidc-required-claim", ""+
"A key=value pair that describes a required claim in the ID Token. "+ "A key=value pair that describes a required claim in the ID Token. "+
"If set, the claim is verified to be present in the ID Token with a matching value. "+ "If set, the claim is verified to be present in the ID Token with a matching value. "+
"Repeat this flag to specify multiple claims.") "Repeat this flag to specify multiple claims.")
} }
if s.RequestHeader != nil { if o.RequestHeader != nil {
s.RequestHeader.AddFlags(fs) o.RequestHeader.AddFlags(fs)
} }
if s.ServiceAccounts != nil { if o.ServiceAccounts != nil {
fs.StringArrayVar(&s.ServiceAccounts.KeyFiles, "service-account-key-file", s.ServiceAccounts.KeyFiles, ""+ fs.StringArrayVar(&o.ServiceAccounts.KeyFiles, "service-account-key-file", o.ServiceAccounts.KeyFiles, ""+
"File containing PEM-encoded x509 RSA or ECDSA private or public keys, used to verify "+ "File containing PEM-encoded x509 RSA or ECDSA private or public keys, used to verify "+
"ServiceAccount tokens. The specified file can contain multiple keys, and the flag can "+ "ServiceAccount tokens. The specified file can contain multiple keys, and the flag can "+
"be specified multiple times with different files. If unspecified, "+ "be specified multiple times with different files. If unspecified, "+
"--tls-private-key-file is used. Must be specified when "+ "--tls-private-key-file is used. Must be specified when "+
"--service-account-signing-key is provided") "--service-account-signing-key is provided")
fs.BoolVar(&s.ServiceAccounts.Lookup, "service-account-lookup", s.ServiceAccounts.Lookup, fs.BoolVar(&o.ServiceAccounts.Lookup, "service-account-lookup", o.ServiceAccounts.Lookup,
"If true, validate ServiceAccount tokens exist in etcd as part of authentication.") "If true, validate ServiceAccount tokens exist in etcd as part of authentication.")
fs.StringVar(&s.ServiceAccounts.Issuer, "service-account-issuer", s.ServiceAccounts.Issuer, ""+ fs.StringVar(&o.ServiceAccounts.Issuer, "service-account-issuer", o.ServiceAccounts.Issuer, ""+
"Identifier of the service account token issuer. The issuer will assert this identifier "+ "Identifier of the service account token issuer. The issuer will assert this identifier "+
"in \"iss\" claim of issued tokens. This value is a string or URI. If this option is not "+ "in \"iss\" claim of issued tokens. This value is a string or URI. If this option is not "+
"a valid URI per the OpenID Discovery 1.0 spec, the ServiceAccountIssuerDiscovery feature "+ "a valid URI per the OpenID Discovery 1.0 spec, the ServiceAccountIssuerDiscovery feature "+
@ -296,7 +315,7 @@ func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
"recommended that this URL be capable of serving OpenID discovery documents at "+ "recommended that this URL be capable of serving OpenID discovery documents at "+
"`{service-account-issuer}/.well-known/openid-configuration`.") "`{service-account-issuer}/.well-known/openid-configuration`.")
fs.StringVar(&s.ServiceAccounts.JWKSURI, "service-account-jwks-uri", s.ServiceAccounts.JWKSURI, ""+ fs.StringVar(&o.ServiceAccounts.JWKSURI, "service-account-jwks-uri", o.ServiceAccounts.JWKSURI, ""+
"Overrides the URI for the JSON Web Key Set in the discovery doc served at "+ "Overrides the URI for the JSON Web Key Set in the discovery doc served at "+
"/.well-known/openid-configuration. This flag is useful if the discovery doc"+ "/.well-known/openid-configuration. This flag is useful if the discovery doc"+
"and key set are served to relying parties from a URL other than the "+ "and key set are served to relying parties from a URL other than the "+
@ -304,108 +323,109 @@ func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
"Only valid if the ServiceAccountIssuerDiscovery feature gate is enabled.") "Only valid if the ServiceAccountIssuerDiscovery feature gate is enabled.")
// Deprecated in 1.13 // Deprecated in 1.13
fs.StringSliceVar(&s.APIAudiences, "service-account-api-audiences", s.APIAudiences, ""+ fs.StringSliceVar(&o.APIAudiences, "service-account-api-audiences", o.APIAudiences, ""+
"Identifiers of the API. The service account token authenticator will validate that "+ "Identifiers of the API. The service account token authenticator will validate that "+
"tokens used against the API are bound to at least one of these audiences.") "tokens used against the API are bound to at least one of these audiences.")
fs.MarkDeprecated("service-account-api-audiences", "Use --api-audiences") fs.MarkDeprecated("service-account-api-audiences", "Use --api-audiences")
fs.DurationVar(&s.ServiceAccounts.MaxExpiration, "service-account-max-token-expiration", s.ServiceAccounts.MaxExpiration, ""+ fs.DurationVar(&o.ServiceAccounts.MaxExpiration, "service-account-max-token-expiration", o.ServiceAccounts.MaxExpiration, ""+
"The maximum validity duration of a token created by the service account token issuer. If an otherwise valid "+ "The maximum validity duration of a token created by the service account token issuer. If an otherwise valid "+
"TokenRequest with a validity duration larger than this value is requested, a token will be issued with a validity duration of this value.") "TokenRequest with a validity duration larger than this value is requested, a token will be issued with a validity duration of this value.")
fs.BoolVar(&s.ServiceAccounts.ExtendExpiration, "service-account-extend-token-expiration", s.ServiceAccounts.ExtendExpiration, ""+ fs.BoolVar(&o.ServiceAccounts.ExtendExpiration, "service-account-extend-token-expiration", o.ServiceAccounts.ExtendExpiration, ""+
"Turns on projected service account expiration extension during token generation, "+ "Turns on projected service account expiration extension during token generation, "+
"which helps safe transition from legacy token to bound service account token feature. "+ "which helps safe transition from legacy token to bound service account token feature. "+
"If this flag is enabled, admission injected tokens would be extended up to 1 year to "+ "If this flag is enabled, admission injected tokens would be extended up to 1 year to "+
"prevent unexpected failure during transition, ignoring value of service-account-max-token-expiration.") "prevent unexpected failure during transition, ignoring value of service-account-max-token-expiration.")
} }
if s.TokenFile != nil { if o.TokenFile != nil {
fs.StringVar(&s.TokenFile.TokenFile, "token-auth-file", s.TokenFile.TokenFile, ""+ fs.StringVar(&o.TokenFile.TokenFile, "token-auth-file", o.TokenFile.TokenFile, ""+
"If set, the file that will be used to secure the secure port of the API server "+ "If set, the file that will be used to secure the secure port of the API server "+
"via token authentication.") "via token authentication.")
} }
if s.WebHook != nil { if o.WebHook != nil {
fs.StringVar(&s.WebHook.ConfigFile, "authentication-token-webhook-config-file", s.WebHook.ConfigFile, ""+ fs.StringVar(&o.WebHook.ConfigFile, "authentication-token-webhook-config-file", o.WebHook.ConfigFile, ""+
"File with webhook configuration for token authentication in kubeconfig format. "+ "File with webhook configuration for token authentication in kubeconfig format. "+
"The API server will query the remote service to determine authentication for bearer tokens.") "The API server will query the remote service to determine authentication for bearer tokens.")
fs.StringVar(&s.WebHook.Version, "authentication-token-webhook-version", s.WebHook.Version, ""+ fs.StringVar(&o.WebHook.Version, "authentication-token-webhook-version", o.WebHook.Version, ""+
"The API version of the authentication.k8s.io TokenReview to send to and expect from the webhook.") "The API version of the authentication.k8s.io TokenReview to send to and expect from the webhook.")
fs.DurationVar(&s.WebHook.CacheTTL, "authentication-token-webhook-cache-ttl", s.WebHook.CacheTTL, fs.DurationVar(&o.WebHook.CacheTTL, "authentication-token-webhook-cache-ttl", o.WebHook.CacheTTL,
"The duration to cache responses from the webhook token authenticator.") "The duration to cache responses from the webhook token authenticator.")
} }
} }
func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() (kubeauthenticator.Config, error) { // ToAuthenticationConfig convert BuiltInAuthenticationOptions to kubeauthenticator.Config
func (o *BuiltInAuthenticationOptions) ToAuthenticationConfig() (kubeauthenticator.Config, error) {
ret := kubeauthenticator.Config{ ret := kubeauthenticator.Config{
TokenSuccessCacheTTL: s.TokenSuccessCacheTTL, TokenSuccessCacheTTL: o.TokenSuccessCacheTTL,
TokenFailureCacheTTL: s.TokenFailureCacheTTL, TokenFailureCacheTTL: o.TokenFailureCacheTTL,
} }
if s.Anonymous != nil { if o.Anonymous != nil {
ret.Anonymous = s.Anonymous.Allow ret.Anonymous = o.Anonymous.Allow
} }
if s.BootstrapToken != nil { if o.BootstrapToken != nil {
ret.BootstrapToken = s.BootstrapToken.Enable ret.BootstrapToken = o.BootstrapToken.Enable
} }
if s.ClientCert != nil { if o.ClientCert != nil {
var err error var err error
ret.ClientCAContentProvider, err = s.ClientCert.GetClientCAContentProvider() ret.ClientCAContentProvider, err = o.ClientCert.GetClientCAContentProvider()
if err != nil { if err != nil {
return kubeauthenticator.Config{}, err return kubeauthenticator.Config{}, err
} }
} }
if s.OIDC != nil { if o.OIDC != nil {
ret.OIDCCAFile = s.OIDC.CAFile ret.OIDCCAFile = o.OIDC.CAFile
ret.OIDCClientID = s.OIDC.ClientID ret.OIDCClientID = o.OIDC.ClientID
ret.OIDCGroupsClaim = s.OIDC.GroupsClaim ret.OIDCGroupsClaim = o.OIDC.GroupsClaim
ret.OIDCGroupsPrefix = s.OIDC.GroupsPrefix ret.OIDCGroupsPrefix = o.OIDC.GroupsPrefix
ret.OIDCIssuerURL = s.OIDC.IssuerURL ret.OIDCIssuerURL = o.OIDC.IssuerURL
ret.OIDCUsernameClaim = s.OIDC.UsernameClaim ret.OIDCUsernameClaim = o.OIDC.UsernameClaim
ret.OIDCUsernamePrefix = s.OIDC.UsernamePrefix ret.OIDCUsernamePrefix = o.OIDC.UsernamePrefix
ret.OIDCSigningAlgs = s.OIDC.SigningAlgs ret.OIDCSigningAlgs = o.OIDC.SigningAlgs
ret.OIDCRequiredClaims = s.OIDC.RequiredClaims ret.OIDCRequiredClaims = o.OIDC.RequiredClaims
} }
if s.RequestHeader != nil { if o.RequestHeader != nil {
var err error var err error
ret.RequestHeaderConfig, err = s.RequestHeader.ToAuthenticationRequestHeaderConfig() ret.RequestHeaderConfig, err = o.RequestHeader.ToAuthenticationRequestHeaderConfig()
if err != nil { if err != nil {
return kubeauthenticator.Config{}, err return kubeauthenticator.Config{}, err
} }
} }
ret.APIAudiences = s.APIAudiences ret.APIAudiences = o.APIAudiences
if s.ServiceAccounts != nil { if o.ServiceAccounts != nil {
if s.ServiceAccounts.Issuer != "" && len(s.APIAudiences) == 0 { if o.ServiceAccounts.Issuer != "" && len(o.APIAudiences) == 0 {
ret.APIAudiences = authenticator.Audiences{s.ServiceAccounts.Issuer} ret.APIAudiences = authenticator.Audiences{o.ServiceAccounts.Issuer}
} }
ret.ServiceAccountKeyFiles = s.ServiceAccounts.KeyFiles ret.ServiceAccountKeyFiles = o.ServiceAccounts.KeyFiles
ret.ServiceAccountIssuer = s.ServiceAccounts.Issuer ret.ServiceAccountIssuer = o.ServiceAccounts.Issuer
ret.ServiceAccountLookup = s.ServiceAccounts.Lookup ret.ServiceAccountLookup = o.ServiceAccounts.Lookup
} }
if s.TokenFile != nil { if o.TokenFile != nil {
ret.TokenAuthFile = s.TokenFile.TokenFile ret.TokenAuthFile = o.TokenFile.TokenFile
} }
if s.WebHook != nil { if o.WebHook != nil {
ret.WebhookTokenAuthnConfigFile = s.WebHook.ConfigFile ret.WebhookTokenAuthnConfigFile = o.WebHook.ConfigFile
ret.WebhookTokenAuthnVersion = s.WebHook.Version ret.WebhookTokenAuthnVersion = o.WebHook.Version
ret.WebhookTokenAuthnCacheTTL = s.WebHook.CacheTTL ret.WebhookTokenAuthnCacheTTL = o.WebHook.CacheTTL
if len(s.WebHook.ConfigFile) > 0 && s.WebHook.CacheTTL > 0 { if len(o.WebHook.ConfigFile) > 0 && o.WebHook.CacheTTL > 0 {
if s.TokenSuccessCacheTTL > 0 && s.WebHook.CacheTTL < s.TokenSuccessCacheTTL { if o.TokenSuccessCacheTTL > 0 && o.WebHook.CacheTTL < o.TokenSuccessCacheTTL {
klog.Warningf("the webhook cache ttl of %s is shorter than the overall cache ttl of %s for successful token authentication attempts.", s.WebHook.CacheTTL, s.TokenSuccessCacheTTL) klog.Warningf("the webhook cache ttl of %s is shorter than the overall cache ttl of %s for successful token authentication attempts.", o.WebHook.CacheTTL, o.TokenSuccessCacheTTL)
} }
if s.TokenFailureCacheTTL > 0 && s.WebHook.CacheTTL < s.TokenFailureCacheTTL { if o.TokenFailureCacheTTL > 0 && o.WebHook.CacheTTL < o.TokenFailureCacheTTL {
klog.Warningf("the webhook cache ttl of %s is shorter than the overall cache ttl of %s for failed token authentication attempts.", s.WebHook.CacheTTL, s.TokenFailureCacheTTL) klog.Warningf("the webhook cache ttl of %s is shorter than the overall cache ttl of %s for failed token authentication attempts.", o.WebHook.CacheTTL, o.TokenFailureCacheTTL)
} }
} }
} }

View File

@ -29,6 +29,7 @@ import (
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes" authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
) )
// BuiltInAuthorizationOptions contains all build-in authorization options for API Server
type BuiltInAuthorizationOptions struct { type BuiltInAuthorizationOptions struct {
Modes []string Modes []string
PolicyFile string PolicyFile string
@ -38,6 +39,7 @@ type BuiltInAuthorizationOptions struct {
WebhookCacheUnauthorizedTTL time.Duration WebhookCacheUnauthorizedTTL time.Duration
} }
// NewBuiltInAuthorizationOptions create a BuiltInAuthorizationOptions with default value
func NewBuiltInAuthorizationOptions() *BuiltInAuthorizationOptions { func NewBuiltInAuthorizationOptions() *BuiltInAuthorizationOptions {
return &BuiltInAuthorizationOptions{ return &BuiltInAuthorizationOptions{
Modes: []string{authzmodes.ModeAlwaysAllow}, Modes: []string{authzmodes.ModeAlwaysAllow},
@ -47,80 +49,83 @@ func NewBuiltInAuthorizationOptions() *BuiltInAuthorizationOptions {
} }
} }
func (s *BuiltInAuthorizationOptions) Validate() []error { // Validate checks invalid config combination
if s == nil { func (o *BuiltInAuthorizationOptions) Validate() []error {
if o == nil {
return nil return nil
} }
allErrors := []error{} allErrors := []error{}
if len(s.Modes) == 0 { if len(o.Modes) == 0 {
allErrors = append(allErrors, fmt.Errorf("at least one authorization-mode must be passed")) allErrors = append(allErrors, fmt.Errorf("at least one authorization-mode must be passed"))
} }
modes := sets.NewString(s.Modes...) modes := sets.NewString(o.Modes...)
for _, mode := range s.Modes { for _, mode := range o.Modes {
if !authzmodes.IsValidAuthorizationMode(mode) { if !authzmodes.IsValidAuthorizationMode(mode) {
allErrors = append(allErrors, fmt.Errorf("authorization-mode %q is not a valid mode", mode)) allErrors = append(allErrors, fmt.Errorf("authorization-mode %q is not a valid mode", mode))
} }
if mode == authzmodes.ModeABAC { if mode == authzmodes.ModeABAC {
if s.PolicyFile == "" { if o.PolicyFile == "" {
allErrors = append(allErrors, fmt.Errorf("authorization-mode ABAC's authorization policy file not passed")) allErrors = append(allErrors, fmt.Errorf("authorization-mode ABAC's authorization policy file not passed"))
} }
} }
if mode == authzmodes.ModeWebhook { if mode == authzmodes.ModeWebhook {
if s.WebhookConfigFile == "" { if o.WebhookConfigFile == "" {
allErrors = append(allErrors, fmt.Errorf("authorization-mode Webhook's authorization config file not passed")) allErrors = append(allErrors, fmt.Errorf("authorization-mode Webhook's authorization config file not passed"))
} }
} }
} }
if s.PolicyFile != "" && !modes.Has(authzmodes.ModeABAC) { if o.PolicyFile != "" && !modes.Has(authzmodes.ModeABAC) {
allErrors = append(allErrors, fmt.Errorf("cannot specify --authorization-policy-file without mode ABAC")) allErrors = append(allErrors, fmt.Errorf("cannot specify --authorization-policy-file without mode ABAC"))
} }
if s.WebhookConfigFile != "" && !modes.Has(authzmodes.ModeWebhook) { if o.WebhookConfigFile != "" && !modes.Has(authzmodes.ModeWebhook) {
allErrors = append(allErrors, fmt.Errorf("cannot specify --authorization-webhook-config-file without mode Webhook")) allErrors = append(allErrors, fmt.Errorf("cannot specify --authorization-webhook-config-file without mode Webhook"))
} }
if len(s.Modes) != len(modes.List()) { if len(o.Modes) != len(modes.List()) {
allErrors = append(allErrors, fmt.Errorf("authorization-mode %q has mode specified more than once", s.Modes)) allErrors = append(allErrors, fmt.Errorf("authorization-mode %q has mode specified more than once", o.Modes))
} }
return allErrors return allErrors
} }
func (s *BuiltInAuthorizationOptions) AddFlags(fs *pflag.FlagSet) { // AddFlags returns flags of authorization for a API Server
fs.StringSliceVar(&s.Modes, "authorization-mode", s.Modes, ""+ func (o *BuiltInAuthorizationOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringSliceVar(&o.Modes, "authorization-mode", o.Modes, ""+
"Ordered list of plug-ins to do authorization on secure port. Comma-delimited list of: "+ "Ordered list of plug-ins to do authorization on secure port. Comma-delimited list of: "+
strings.Join(authzmodes.AuthorizationModeChoices, ",")+".") strings.Join(authzmodes.AuthorizationModeChoices, ",")+".")
fs.StringVar(&s.PolicyFile, "authorization-policy-file", s.PolicyFile, ""+ fs.StringVar(&o.PolicyFile, "authorization-policy-file", o.PolicyFile, ""+
"File with authorization policy in json line by line format, used with --authorization-mode=ABAC, on the secure port.") "File with authorization policy in json line by line format, used with --authorization-mode=ABAC, on the secure port.")
fs.StringVar(&s.WebhookConfigFile, "authorization-webhook-config-file", s.WebhookConfigFile, ""+ fs.StringVar(&o.WebhookConfigFile, "authorization-webhook-config-file", o.WebhookConfigFile, ""+
"File with webhook configuration in kubeconfig format, used with --authorization-mode=Webhook. "+ "File with webhook configuration in kubeconfig format, used with --authorization-mode=Webhook. "+
"The API server will query the remote service to determine access on the API server's secure port.") "The API server will query the remote service to determine access on the API server's secure port.")
fs.StringVar(&s.WebhookVersion, "authorization-webhook-version", s.WebhookVersion, ""+ fs.StringVar(&o.WebhookVersion, "authorization-webhook-version", o.WebhookVersion, ""+
"The API version of the authorization.k8s.io SubjectAccessReview to send to and expect from the webhook.") "The API version of the authorization.k8s.io SubjectAccessReview to send to and expect from the webhook.")
fs.DurationVar(&s.WebhookCacheAuthorizedTTL, "authorization-webhook-cache-authorized-ttl", fs.DurationVar(&o.WebhookCacheAuthorizedTTL, "authorization-webhook-cache-authorized-ttl",
s.WebhookCacheAuthorizedTTL, o.WebhookCacheAuthorizedTTL,
"The duration to cache 'authorized' responses from the webhook authorizer.") "The duration to cache 'authorized' responses from the webhook authorizer.")
fs.DurationVar(&s.WebhookCacheUnauthorizedTTL, fs.DurationVar(&o.WebhookCacheUnauthorizedTTL,
"authorization-webhook-cache-unauthorized-ttl", s.WebhookCacheUnauthorizedTTL, "authorization-webhook-cache-unauthorized-ttl", o.WebhookCacheUnauthorizedTTL,
"The duration to cache 'unauthorized' responses from the webhook authorizer.") "The duration to cache 'unauthorized' responses from the webhook authorizer.")
} }
func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(versionedInformerFactory versionedinformers.SharedInformerFactory) authorizer.Config { // ToAuthorizationConfig convert BuiltInAuthorizationOptions to authorizer.Config
func (o *BuiltInAuthorizationOptions) ToAuthorizationConfig(versionedInformerFactory versionedinformers.SharedInformerFactory) authorizer.Config {
return authorizer.Config{ return authorizer.Config{
AuthorizationModes: s.Modes, AuthorizationModes: o.Modes,
PolicyFile: s.PolicyFile, PolicyFile: o.PolicyFile,
WebhookConfigFile: s.WebhookConfigFile, WebhookConfigFile: o.WebhookConfigFile,
WebhookVersion: s.WebhookVersion, WebhookVersion: o.WebhookVersion,
WebhookCacheAuthorizedTTL: s.WebhookCacheAuthorizedTTL, WebhookCacheAuthorizedTTL: o.WebhookCacheAuthorizedTTL,
WebhookCacheUnauthorizedTTL: s.WebhookCacheUnauthorizedTTL, WebhookCacheUnauthorizedTTL: o.WebhookCacheUnauthorizedTTL,
VersionedInformerFactory: versionedInformerFactory, VersionedInformerFactory: versionedInformerFactory,
} }
} }

View File

@ -20,20 +20,24 @@ import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
) )
// CloudProviderOptions contains cloud provider config
type CloudProviderOptions struct { type CloudProviderOptions struct {
CloudConfigFile string CloudConfigFile string
CloudProvider string CloudProvider string
} }
// NewCloudProviderOptions creates a default CloudProviderOptions
func NewCloudProviderOptions() *CloudProviderOptions { func NewCloudProviderOptions() *CloudProviderOptions {
return &CloudProviderOptions{} return &CloudProviderOptions{}
} }
// Validate checks invalid config
func (s *CloudProviderOptions) Validate() []error { func (s *CloudProviderOptions) Validate() []error {
allErrors := []error{} allErrors := []error{}
return allErrors return allErrors
} }
// AddFlags returns flags of cloud provider for a API Server
func (s *CloudProviderOptions) AddFlags(fs *pflag.FlagSet) { func (s *CloudProviderOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.CloudProvider, "cloud-provider", s.CloudProvider, fs.StringVar(&s.CloudProvider, "cloud-provider", s.CloudProvider,
"The provider for cloud services. Empty string for no provider.") "The provider for cloud services. Empty string for no provider.")

View File

@ -26,6 +26,7 @@ import (
var DefaultServiceNodePortRange = utilnet.PortRange{Base: 30000, Size: 2768} var DefaultServiceNodePortRange = utilnet.PortRange{Base: 30000, Size: 2768}
// DefaultServiceIPCIDR is a CIDR notation of IP range from which to allocate service cluster IPs // DefaultServiceIPCIDR is a CIDR notation of IP range from which to allocate service cluster IPs
var DefaultServiceIPCIDR net.IPNet = net.IPNet{IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(24, 32)} var DefaultServiceIPCIDR = net.IPNet{IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(24, 32)}
// DefaultEtcdPathPrefix is the default key prefix of etcd for API Server
const DefaultEtcdPathPrefix = "/registry" const DefaultEtcdPathPrefix = "/registry"