mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-29 21:29:24 +00:00
Merge pull request #36604 from deads2k/api-42-add-generic-loopback
Automatic merge from submit-queue move parts of the mega generic run struct out This splits the main `ServerRunOptions` into composeable pieces that are bindable separately and adds easy paths for composing servers to run delegating authentication and authorization. @sttts @ncdc alright, I think this is as far as I need to go to make the composing servers reasonable to write. I'll try leaving it here
This commit is contained in:
@@ -26,9 +26,8 @@ go_library(
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apiserver:go_default_library",
|
||||
"//pkg/apiserver/authenticator:go_default_library",
|
||||
"//pkg/auth/authorizer/union:go_default_library",
|
||||
"//pkg/auth/user:go_default_library",
|
||||
"//pkg/capabilities:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/cloudprovider:go_default_library",
|
||||
"//pkg/cloudprovider/providers:go_default_library",
|
||||
"//pkg/controller/informers:go_default_library",
|
||||
@@ -36,11 +35,11 @@ go_library(
|
||||
"//pkg/generated/openapi:go_default_library",
|
||||
"//pkg/genericapiserver:go_default_library",
|
||||
"//pkg/genericapiserver/authorizer:go_default_library",
|
||||
"//pkg/genericapiserver/validation:go_default_library",
|
||||
"//pkg/genericapiserver/options:go_default_library",
|
||||
"//pkg/master:go_default_library",
|
||||
"//pkg/registry/cachesize:go_default_library",
|
||||
"//pkg/runtime/schema:go_default_library",
|
||||
"//pkg/serviceaccount:go_default_library",
|
||||
"//pkg/util/errors:go_default_library",
|
||||
"//pkg/util/net:go_default_library",
|
||||
"//pkg/util/wait:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
@@ -63,7 +62,6 @@ go_library(
|
||||
"//plugin/pkg/admission/securitycontext/scdeny:go_default_library",
|
||||
"//plugin/pkg/admission/serviceaccount:go_default_library",
|
||||
"//plugin/pkg/admission/storageclass/default:go_default_library",
|
||||
"//plugin/pkg/auth/authenticator/request/union:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:github.com/pborman/uuid",
|
||||
"//vendor:github.com/spf13/cobra",
|
||||
|
||||
@@ -31,24 +31,32 @@ import (
|
||||
|
||||
// ServerRunOptions runs a kubernetes api server.
|
||||
type ServerRunOptions struct {
|
||||
GenericServerRunOptions *genericoptions.ServerRunOptions
|
||||
AllowPrivileged bool
|
||||
EventTTL time.Duration
|
||||
KubeletConfig kubeletclient.KubeletClientConfig
|
||||
MaxConnectionBytesPerSec int64
|
||||
SSHKeyfile string
|
||||
SSHUser string
|
||||
ServiceAccountKeyFiles []string
|
||||
ServiceAccountLookup bool
|
||||
WebhookTokenAuthnConfigFile string
|
||||
WebhookTokenAuthnCacheTTL time.Duration
|
||||
GenericServerRunOptions *genericoptions.ServerRunOptions
|
||||
Etcd *genericoptions.EtcdOptions
|
||||
SecureServing *genericoptions.SecureServingOptions
|
||||
InsecureServing *genericoptions.ServingOptions
|
||||
Authentication *genericoptions.BuiltInAuthenticationOptions
|
||||
Authorization *genericoptions.BuiltInAuthorizationOptions
|
||||
|
||||
AllowPrivileged bool
|
||||
EventTTL time.Duration
|
||||
KubeletConfig kubeletclient.KubeletClientConfig
|
||||
MaxConnectionBytesPerSec int64
|
||||
SSHKeyfile string
|
||||
SSHUser string
|
||||
}
|
||||
|
||||
// NewServerRunOptions creates a new ServerRunOptions object with default parameters
|
||||
func NewServerRunOptions() *ServerRunOptions {
|
||||
s := ServerRunOptions{
|
||||
GenericServerRunOptions: genericoptions.NewServerRunOptions().WithEtcdOptions(),
|
||||
EventTTL: 1 * time.Hour,
|
||||
GenericServerRunOptions: genericoptions.NewServerRunOptions(),
|
||||
Etcd: genericoptions.NewEtcdOptions(),
|
||||
SecureServing: genericoptions.NewSecureServingOptions(),
|
||||
InsecureServing: genericoptions.NewInsecureServingOptions(),
|
||||
Authentication: genericoptions.NewBuiltInAuthenticationOptions().WithAll(),
|
||||
Authorization: genericoptions.NewBuiltInAuthorizationOptions(),
|
||||
|
||||
EventTTL: 1 * time.Hour,
|
||||
KubeletConfig: kubeletclient.KubeletClientConfig{
|
||||
Port: ports.KubeletPort,
|
||||
PreferredAddressTypes: []string{
|
||||
@@ -60,7 +68,6 @@ func NewServerRunOptions() *ServerRunOptions {
|
||||
EnableHttps: true,
|
||||
HTTPTimeout: time.Duration(5) * time.Second,
|
||||
},
|
||||
WebhookTokenAuthnCacheTTL: 2 * time.Minute,
|
||||
}
|
||||
return &s
|
||||
}
|
||||
@@ -69,29 +76,21 @@ func NewServerRunOptions() *ServerRunOptions {
|
||||
func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
// Add the generic flags.
|
||||
s.GenericServerRunOptions.AddUniversalFlags(fs)
|
||||
//Add etcd specific flags.
|
||||
s.GenericServerRunOptions.AddEtcdStorageFlags(fs)
|
||||
|
||||
s.Etcd.AddFlags(fs)
|
||||
s.SecureServing.AddFlags(fs)
|
||||
s.SecureServing.AddDeprecatedFlags(fs)
|
||||
s.InsecureServing.AddFlags(fs)
|
||||
s.InsecureServing.AddDeprecatedFlags(fs)
|
||||
s.Authentication.AddFlags(fs)
|
||||
s.Authorization.AddFlags(fs)
|
||||
|
||||
// Note: the weird ""+ in below lines seems to be the only way to get gofmt to
|
||||
// arrange these text blocks sensibly. Grrr.
|
||||
|
||||
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.")
|
||||
|
||||
|
||||
@@ -41,24 +41,22 @@ import (
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apiserver"
|
||||
"k8s.io/kubernetes/pkg/apiserver/authenticator"
|
||||
authorizerunion "k8s.io/kubernetes/pkg/auth/authorizer/union"
|
||||
"k8s.io/kubernetes/pkg/auth/user"
|
||||
"k8s.io/kubernetes/pkg/capabilities"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||
generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
|
||||
"k8s.io/kubernetes/pkg/genericapiserver"
|
||||
"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
|
||||
genericvalidation "k8s.io/kubernetes/pkg/genericapiserver/validation"
|
||||
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
|
||||
"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"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
authenticatorunion "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union"
|
||||
)
|
||||
|
||||
// NewAPIServerCommand creates a *cobra.Command object with default parameters
|
||||
@@ -80,11 +78,20 @@ cluster's shared state through which all other components interact.`,
|
||||
|
||||
// Run runs the specified APIServer. This should never exit.
|
||||
func Run(s *options.ServerRunOptions) error {
|
||||
genericvalidation.VerifyEtcdServersList(s.GenericServerRunOptions)
|
||||
if errs := s.Etcd.Validate(); len(errs) > 0 {
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
if err := s.GenericServerRunOptions.DefaultExternalAddress(s.SecureServing, s.InsecureServing); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genericapiserver.DefaultAndValidateRunOptions(s.GenericServerRunOptions)
|
||||
genericConfig := genericapiserver.NewConfig(). // create the new config
|
||||
ApplyOptions(s.GenericServerRunOptions). // apply the options selected
|
||||
Complete() // set default values based on the known values
|
||||
ApplySecureServingOptions(s.SecureServing).
|
||||
ApplyInsecureServingOptions(s.InsecureServing).
|
||||
ApplyAuthenticationOptions(s.Authentication).
|
||||
ApplyRBACSuperUser(s.Authorization.RBACSuperUser)
|
||||
|
||||
serviceIPRange, apiServerServiceIP, err := genericapiserver.DefaultServiceIPRange(s.GenericServerRunOptions.ServiceClusterIPRange)
|
||||
if err != nil {
|
||||
@@ -142,7 +149,7 @@ func Run(s *options.ServerRunOptions) error {
|
||||
// Proxying to pods and services is IP-based... don't expect to be able to verify the hostname
|
||||
proxyTLSClientConfig := &tls.Config{InsecureSkipVerify: true}
|
||||
|
||||
if s.GenericServerRunOptions.StorageConfig.DeserializationCacheSize == 0 {
|
||||
if s.Etcd.StorageConfig.DeserializationCacheSize == 0 {
|
||||
// When size of cache is not explicitly set, estimate its size based on
|
||||
// target memory usage.
|
||||
glog.V(2).Infof("Initalizing deserialization cache size based on %dMB limit", s.GenericServerRunOptions.TargetRAMMB)
|
||||
@@ -158,9 +165,9 @@ func Run(s *options.ServerRunOptions) error {
|
||||
// size to compute its size. We may even go further and measure
|
||||
// collective sizes of the objects in the cache.
|
||||
clusterSize := s.GenericServerRunOptions.TargetRAMMB / 60
|
||||
s.GenericServerRunOptions.StorageConfig.DeserializationCacheSize = 25 * clusterSize
|
||||
if s.GenericServerRunOptions.StorageConfig.DeserializationCacheSize < 1000 {
|
||||
s.GenericServerRunOptions.StorageConfig.DeserializationCacheSize = 1000
|
||||
s.Etcd.StorageConfig.DeserializationCacheSize = 25 * clusterSize
|
||||
if s.Etcd.StorageConfig.DeserializationCacheSize < 1000 {
|
||||
s.Etcd.StorageConfig.DeserializationCacheSize = 1000
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +176,7 @@ func Run(s *options.ServerRunOptions) error {
|
||||
glog.Fatalf("error generating storage version map: %s", err)
|
||||
}
|
||||
storageFactory, err := genericapiserver.BuildDefaultStorageFactory(
|
||||
s.GenericServerRunOptions.StorageConfig, s.GenericServerRunOptions.DefaultStorageMediaType, api.Codecs,
|
||||
s.Etcd.StorageConfig, s.GenericServerRunOptions.DefaultStorageMediaType, api.Codecs,
|
||||
genericapiserver.NewDefaultResourceEncodingConfig(), storageGroupsToEncodingVersion,
|
||||
// FIXME: this GroupVersionResource override should be configurable
|
||||
[]schema.GroupVersionResource{batch.Resource("cronjobs").WithVersion("v2alpha1")},
|
||||
@@ -179,7 +186,7 @@ func Run(s *options.ServerRunOptions) error {
|
||||
}
|
||||
storageFactory.AddCohabitatingResources(batch.Resource("jobs"), extensions.Resource("jobs"))
|
||||
storageFactory.AddCohabitatingResources(autoscaling.Resource("horizontalpodautoscalers"), extensions.Resource("horizontalpodautoscalers"))
|
||||
for _, override := range s.GenericServerRunOptions.EtcdServersOverrides {
|
||||
for _, override := range s.Etcd.EtcdServersOverrides {
|
||||
tokens := strings.Split(override, "#")
|
||||
if len(tokens) != 2 {
|
||||
glog.Errorf("invalid value of etcd server overrides: %s", override)
|
||||
@@ -200,96 +207,49 @@ func Run(s *options.ServerRunOptions) error {
|
||||
}
|
||||
|
||||
// Default to the private server key for service account token signing
|
||||
if len(s.ServiceAccountKeyFiles) == 0 && s.GenericServerRunOptions.TLSPrivateKeyFile != "" {
|
||||
if authenticator.IsValidServiceAccountKeyFile(s.GenericServerRunOptions.TLSPrivateKeyFile) {
|
||||
s.ServiceAccountKeyFiles = []string{s.GenericServerRunOptions.TLSPrivateKeyFile}
|
||||
if len(s.Authentication.ServiceAccounts.KeyFiles) == 0 && s.SecureServing.ServerCert.CertKey.KeyFile != "" {
|
||||
if authenticator.IsValidServiceAccountKeyFile(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.GenericServerRunOptions.ClientCAFile,
|
||||
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)
|
||||
}
|
||||
|
||||
privilegedLoopbackToken := uuid.NewRandom().String()
|
||||
selfClientConfig, err := s.GenericServerRunOptions.NewSelfClientConfig(privilegedLoopbackToken)
|
||||
selfClientConfig, err := genericoptions.NewSelfClientConfig(s.SecureServing, s.InsecureServing, privilegedLoopbackToken)
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to create clientset: %v", err)
|
||||
}
|
||||
client, err := s.GenericServerRunOptions.NewSelfClient(privilegedLoopbackToken)
|
||||
client, err := internalclientset.NewForConfig(selfClientConfig)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to create clientset: %v", err)
|
||||
}
|
||||
sharedInformers := informers.NewSharedInformerFactory(nil, client, 10*time.Minute)
|
||||
|
||||
authorizationConfig := authorizer.AuthorizationConfig{
|
||||
PolicyFile: s.GenericServerRunOptions.AuthorizationPolicyFile,
|
||||
WebhookConfigFile: s.GenericServerRunOptions.AuthorizationWebhookConfigFile,
|
||||
WebhookCacheAuthorizedTTL: s.GenericServerRunOptions.AuthorizationWebhookCacheAuthorizedTTL,
|
||||
WebhookCacheUnauthorizedTTL: s.GenericServerRunOptions.AuthorizationWebhookCacheUnauthorizedTTL,
|
||||
RBACSuperUser: s.GenericServerRunOptions.AuthorizationRBACSuperUser,
|
||||
InformerFactory: sharedInformers,
|
||||
}
|
||||
authorizationModeNames := strings.Split(s.GenericServerRunOptions.AuthorizationMode, ",")
|
||||
apiAuthorizer, err := authorizer.NewAuthorizerFromAuthorizationConfig(authorizationModeNames, authorizationConfig)
|
||||
authorizationConfig := s.Authorization.ToAuthorizationConfig(sharedInformers)
|
||||
apiAuthorizer, err := authorizer.NewAuthorizerFromAuthorizationConfig(authorizationConfig)
|
||||
if err != nil {
|
||||
glog.Fatalf("Invalid Authorization Config: %v", err)
|
||||
}
|
||||
|
||||
admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",")
|
||||
|
||||
// TODO(dims): We probably need to add an option "EnableLoopbackToken"
|
||||
if apiAuthenticator != nil {
|
||||
var uid = uuid.NewRandom().String()
|
||||
tokens := make(map[string]*user.DefaultInfo)
|
||||
tokens[privilegedLoopbackToken] = &user.DefaultInfo{
|
||||
Name: user.APIServerUser,
|
||||
UID: uid,
|
||||
Groups: []string{user.SystemPrivilegedGroup},
|
||||
}
|
||||
|
||||
tokenAuthenticator := authenticator.NewAuthenticatorFromTokens(tokens)
|
||||
apiAuthenticator = authenticatorunion.New(tokenAuthenticator, apiAuthenticator)
|
||||
|
||||
tokenAuthorizer := authorizer.NewPrivilegedGroups(user.SystemPrivilegedGroup)
|
||||
apiAuthorizer = authorizerunion.New(tokenAuthorizer, apiAuthorizer)
|
||||
}
|
||||
|
||||
pluginInitializer := admission.NewPluginInitializer(sharedInformers, apiAuthorizer)
|
||||
|
||||
admissionController, err := admission.NewFromPlugins(client, admissionControlPluginNames, s.GenericServerRunOptions.AdmissionControlConfigFile, pluginInitializer)
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to initialize plugins: %v", err)
|
||||
@@ -314,7 +274,7 @@ func Run(s *options.ServerRunOptions) error {
|
||||
genericConfig.OpenAPIConfig.SecurityDefinitions = securityDefinitions
|
||||
|
||||
config := &master.Config{
|
||||
GenericConfig: genericConfig.Config,
|
||||
GenericConfig: genericConfig,
|
||||
|
||||
StorageFactory: storageFactory,
|
||||
EnableWatchCache: s.GenericServerRunOptions.EnableWatchCache,
|
||||
|
||||
@@ -26,10 +26,9 @@ go_library(
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
"//pkg/apis/componentconfig/v1alpha1:go_default_library",
|
||||
"//pkg/apiserver/authenticator:go_default_library",
|
||||
"//pkg/auth/authenticator:go_default_library",
|
||||
"//pkg/auth/authenticator/bearertoken:go_default_library",
|
||||
"//pkg/auth/authorizer:go_default_library",
|
||||
"//pkg/auth/group:go_default_library",
|
||||
"//pkg/capabilities:go_default_library",
|
||||
"//pkg/client/chaosclient:go_default_library",
|
||||
"//pkg/client/clientset_generated/release_1_5:go_default_library",
|
||||
@@ -99,11 +98,6 @@ go_library(
|
||||
"//pkg/volume/rbd:go_default_library",
|
||||
"//pkg/volume/secret:go_default_library",
|
||||
"//pkg/volume/vsphere_volume:go_default_library",
|
||||
"//plugin/pkg/auth/authenticator/request/anonymous:go_default_library",
|
||||
"//plugin/pkg/auth/authenticator/request/union:go_default_library",
|
||||
"//plugin/pkg/auth/authenticator/request/x509:go_default_library",
|
||||
"//plugin/pkg/auth/authenticator/token/webhook:go_default_library",
|
||||
"//plugin/pkg/auth/authorizer/webhook:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:github.com/spf13/cobra",
|
||||
"//vendor:github.com/spf13/pflag",
|
||||
|
||||
@@ -22,22 +22,16 @@ import (
|
||||
"reflect"
|
||||
|
||||
"k8s.io/kubernetes/pkg/apis/componentconfig"
|
||||
apiserverauthenticator "k8s.io/kubernetes/pkg/apiserver/authenticator"
|
||||
"k8s.io/kubernetes/pkg/auth/authenticator"
|
||||
"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
|
||||
"k8s.io/kubernetes/pkg/auth/authorizer"
|
||||
"k8s.io/kubernetes/pkg/auth/group"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||
authenticationclient "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/authentication/v1beta1"
|
||||
authorizationclient "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/authorization/v1beta1"
|
||||
alwaysallowauthorizer "k8s.io/kubernetes/pkg/genericapiserver/authorizer"
|
||||
apiserverauthorizer "k8s.io/kubernetes/pkg/genericapiserver/authorizer"
|
||||
"k8s.io/kubernetes/pkg/kubelet/server"
|
||||
"k8s.io/kubernetes/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/util/cert"
|
||||
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/anonymous"
|
||||
unionauth "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union"
|
||||
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/x509"
|
||||
webhooktoken "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook"
|
||||
webhooksar "k8s.io/kubernetes/plugin/pkg/auth/authorizer/webhook"
|
||||
)
|
||||
|
||||
func buildAuth(nodeName types.NodeName, client clientset.Interface, config componentconfig.KubeletConfiguration) (server.AuthInterface, error) {
|
||||
@@ -67,43 +61,21 @@ func buildAuth(nodeName types.NodeName, client clientset.Interface, config compo
|
||||
}
|
||||
|
||||
func buildAuthn(client authenticationclient.TokenReviewInterface, authn componentconfig.KubeletAuthentication) (authenticator.Request, error) {
|
||||
authenticators := []authenticator.Request{}
|
||||
|
||||
// x509 client cert auth
|
||||
if len(authn.X509.ClientCAFile) > 0 {
|
||||
clientCAs, err := cert.NewPool(authn.X509.ClientCAFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to load client CA file %s: %v", authn.X509.ClientCAFile, err)
|
||||
}
|
||||
verifyOpts := x509.DefaultVerifyOptions()
|
||||
verifyOpts.Roots = clientCAs
|
||||
authenticators = append(authenticators, x509.New(verifyOpts, x509.CommonNameUserConversion))
|
||||
authenticatorConfig := apiserverauthenticator.DelegatingAuthenticatorConfig{
|
||||
Anonymous: authn.Anonymous.Enabled,
|
||||
CacheTTL: authn.Webhook.CacheTTL.Duration,
|
||||
ClientCAFile: authn.X509.ClientCAFile,
|
||||
}
|
||||
|
||||
// bearer token auth that uses authentication.k8s.io TokenReview to determine userinfo
|
||||
if authn.Webhook.Enabled {
|
||||
if client == nil {
|
||||
return nil, errors.New("no client provided, cannot use webhook authentication")
|
||||
}
|
||||
tokenAuth, err := webhooktoken.NewFromInterface(client, authn.Webhook.CacheTTL.Duration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authenticators = append(authenticators, bearertoken.New(tokenAuth))
|
||||
authenticatorConfig.TokenAccessReviewClient = client
|
||||
}
|
||||
|
||||
if len(authenticators) == 0 {
|
||||
if authn.Anonymous.Enabled {
|
||||
return anonymous.NewAuthenticator(), nil
|
||||
}
|
||||
return nil, errors.New("No authentication method configured")
|
||||
}
|
||||
|
||||
authenticator := group.NewGroupAdder(unionauth.New(authenticators...), []string{"system:authenticated"})
|
||||
if authn.Anonymous.Enabled {
|
||||
authenticator = unionauth.NewFailOnError(authenticator, anonymous.NewAuthenticator())
|
||||
}
|
||||
return authenticator, nil
|
||||
authenticator, _, err := authenticatorConfig.New()
|
||||
return authenticator, err
|
||||
}
|
||||
|
||||
func buildAuthz(client authorizationclient.SubjectAccessReviewInterface, authz componentconfig.KubeletAuthorization) (authorizer.Authorizer, error) {
|
||||
@@ -115,11 +87,12 @@ func buildAuthz(client authorizationclient.SubjectAccessReviewInterface, authz c
|
||||
if client == nil {
|
||||
return nil, errors.New("no client provided, cannot use webhook authorization")
|
||||
}
|
||||
return webhooksar.NewFromInterface(
|
||||
client,
|
||||
authz.Webhook.CacheAuthorizedTTL.Duration,
|
||||
authz.Webhook.CacheUnauthorizedTTL.Duration,
|
||||
)
|
||||
authorizerConfig := apiserverauthorizer.DelegatingAuthorizerConfig{
|
||||
SubjectAccessReviewClient: client,
|
||||
AllowCacheTTL: authz.Webhook.CacheAuthorizedTTL.Duration,
|
||||
DenyCacheTTL: authz.Webhook.CacheUnauthorizedTTL.Duration,
|
||||
}
|
||||
return authorizerConfig.New()
|
||||
|
||||
case "":
|
||||
return nil, fmt.Errorf("No authorization mode specified")
|
||||
|
||||
Reference in New Issue
Block a user