diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index 51f4bfd2162..8d6fa30b540 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -443,7 +443,7 @@ func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transp return nil, nil, nil, nil, nil, fmt.Errorf("invalid authentication config: %v", err) } - genericConfig.Authorizer, genericConfig.RuleResolver, err = BuildAuthorizer(s, sharedInformers) + genericConfig.Authorizer, genericConfig.RuleResolver, err = BuildAuthorizer(s, sharedInformers, versionedInformers) if err != nil { return nil, nil, nil, nil, nil, fmt.Errorf("invalid authorization config: %v", err) } @@ -546,8 +546,8 @@ func BuildAuthenticator(s *options.ServerRunOptions, storageFactory serverstorag } // BuildAuthorizer constructs the authorizer -func BuildAuthorizer(s *options.ServerRunOptions, sharedInformers informers.SharedInformerFactory) (authorizer.Authorizer, authorizer.RuleResolver, error) { - authorizationConfig := s.Authorization.ToAuthorizationConfig(sharedInformers) +func BuildAuthorizer(s *options.ServerRunOptions, sharedInformers informers.SharedInformerFactory, versionedInformers clientgoinformers.SharedInformerFactory) (authorizer.Authorizer, authorizer.RuleResolver, error) { + authorizationConfig := s.Authorization.ToAuthorizationConfig(sharedInformers, versionedInformers) return authorizationConfig.New() } diff --git a/pkg/kubeapiserver/authorizer/BUILD b/pkg/kubeapiserver/authorizer/BUILD index d15558e2079..a3597f0dbc5 100644 --- a/pkg/kubeapiserver/authorizer/BUILD +++ b/pkg/kubeapiserver/authorizer/BUILD @@ -33,6 +33,7 @@ go_library( "//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library", "//vendor/k8s.io/apiserver/pkg/authorization/union:go_default_library", "//vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook:go_default_library", + "//vendor/k8s.io/client-go/informers:go_default_library", ], ) diff --git a/pkg/kubeapiserver/authorizer/config.go b/pkg/kubeapiserver/authorizer/config.go index 659f2ae7a05..5131e066ad0 100644 --- a/pkg/kubeapiserver/authorizer/config.go +++ b/pkg/kubeapiserver/authorizer/config.go @@ -25,6 +25,7 @@ import ( "k8s.io/apiserver/pkg/authorization/authorizerfactory" "k8s.io/apiserver/pkg/authorization/union" "k8s.io/apiserver/plugin/pkg/authorizer/webhook" + versionedinformers "k8s.io/client-go/informers" "k8s.io/kubernetes/pkg/auth/authorizer/abac" "k8s.io/kubernetes/pkg/auth/nodeidentifier" informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" @@ -51,7 +52,8 @@ type AuthorizationConfig struct { // TTL for caching of unauthorized responses from the webhook server. WebhookCacheUnauthorizedTTL time.Duration - InformerFactory informers.SharedInformerFactory + InformerFactory informers.SharedInformerFactory + VersionedInformerFactory versionedinformers.SharedInformerFactory } // New returns the right sort of union of multiple authorizer.Authorizer objects @@ -71,6 +73,7 @@ func (config AuthorizationConfig) New() (authorizer.Authorizer, authorizer.RuleR if authorizerMap[authorizationMode] { return nil, nil, fmt.Errorf("Authorization mode %s specified more than once", authorizationMode) } + // Keep cases in sync with constant list above. switch authorizationMode { case modes.ModeNode: diff --git a/pkg/kubeapiserver/options/BUILD b/pkg/kubeapiserver/options/BUILD index 8236765c55e..4286e80804d 100644 --- a/pkg/kubeapiserver/options/BUILD +++ b/pkg/kubeapiserver/options/BUILD @@ -33,6 +33,7 @@ go_library( "//vendor/k8s.io/apiserver/pkg/server:go_default_library", "//vendor/k8s.io/apiserver/pkg/server/options:go_default_library", "//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library", + "//vendor/k8s.io/client-go/informers:go_default_library", ], ) diff --git a/pkg/kubeapiserver/options/authorization.go b/pkg/kubeapiserver/options/authorization.go index 1f69c7d55f7..88c04e7e114 100644 --- a/pkg/kubeapiserver/options/authorization.go +++ b/pkg/kubeapiserver/options/authorization.go @@ -22,6 +22,7 @@ import ( "github.com/spf13/pflag" + versionedinformers "k8s.io/client-go/informers" informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" "k8s.io/kubernetes/pkg/kubeapiserver/authorizer" authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes" @@ -83,7 +84,7 @@ func (s *BuiltInAuthorizationOptions) Modes() []string { return modes } -func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(informerFactory informers.SharedInformerFactory) authorizer.AuthorizationConfig { +func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(informerFactory informers.SharedInformerFactory, versionedInformerFactory versionedinformers.SharedInformerFactory) authorizer.AuthorizationConfig { return authorizer.AuthorizationConfig{ AuthorizationModes: s.Modes(), PolicyFile: s.PolicyFile, @@ -91,5 +92,6 @@ func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(informerFactory info WebhookCacheAuthorizedTTL: s.WebhookCacheAuthorizedTTL, WebhookCacheUnauthorizedTTL: s.WebhookCacheUnauthorizedTTL, InformerFactory: informerFactory, + VersionedInformerFactory: versionedInformerFactory, } } diff --git a/test/integration/auth/BUILD b/test/integration/auth/BUILD index 897557a21a9..092007542eb 100644 --- a/test/integration/auth/BUILD +++ b/test/integration/auth/BUILD @@ -73,6 +73,8 @@ go_test( "//vendor/k8s.io/apiserver/pkg/util/feature/testing:go_default_library", "//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest:go_default_library", "//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library", + "//vendor/k8s.io/client-go/informers:go_default_library", + "//vendor/k8s.io/client-go/kubernetes:go_default_library", "//vendor/k8s.io/client-go/rest:go_default_library", "//vendor/k8s.io/client-go/tools/clientcmd/api/v1:go_default_library", "//vendor/k8s.io/client-go/transport:go_default_library", diff --git a/test/integration/auth/node_test.go b/test/integration/auth/node_test.go index 1199ad9cbb1..276066ce8cf 100644 --- a/test/integration/auth/node_test.go +++ b/test/integration/auth/node_test.go @@ -33,6 +33,7 @@ import ( "k8s.io/apiserver/pkg/authentication/user" utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" + versionedinformers "k8s.io/client-go/informers" restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" @@ -71,13 +72,15 @@ func TestNodeAuthorizer(t *testing.T) { // Build client config, clientset, and informers clientConfig := &restclient.Config{Host: apiServer.URL, ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs}} - superuserClient := clientsetForToken(tokenMaster, clientConfig) + superuserClient, superuserClientExternal := clientsetForToken(tokenMaster, clientConfig) informerFactory := informers.NewSharedInformerFactory(superuserClient, time.Minute) + versionedInformerFactory := versionedinformers.NewSharedInformerFactory(superuserClientExternal, time.Minute) // Set up Node+RBAC authorizer authorizerConfig := &authorizer.AuthorizationConfig{ - AuthorizationModes: []string{"Node", "RBAC"}, - InformerFactory: informerFactory, + AuthorizationModes: []string{"Node", "RBAC"}, + InformerFactory: informerFactory, + VersionedInformerFactory: versionedInformerFactory, } nodeRBACAuthorizer, _, err := authorizerConfig.New() if err != nil { @@ -94,7 +97,6 @@ func TestNodeAuthorizer(t *testing.T) { // Start the server masterConfig := framework.NewIntegrationTestMasterConfig() masterConfig.GenericConfig.Authenticator = authenticator - masterConfig.GenericConfig.Authorizer = nodeRBACAuthorizer masterConfig.GenericConfig.AdmissionControl = nodeRestrictionAdmission _, _, closeFn := framework.RunAMasterUsingServer(masterConfig, apiServer, h) @@ -104,6 +106,7 @@ func TestNodeAuthorizer(t *testing.T) { stopCh := make(chan struct{}) defer close(stopCh) informerFactory.Start(stopCh) + versionedInformerFactory.Start(stopCh) // Wait for a healthy server for { @@ -303,9 +306,9 @@ func TestNodeAuthorizer(t *testing.T) { } } - nodeanonClient := clientsetForToken(tokenNodeUnknown, clientConfig) - node1Client := clientsetForToken(tokenNode1, clientConfig) - node2Client := clientsetForToken(tokenNode2, clientConfig) + nodeanonClient, _ := clientsetForToken(tokenNodeUnknown, clientConfig) + node1Client, _ := clientsetForToken(tokenNode1, clientConfig) + node2Client, _ := clientsetForToken(tokenNode2, clientConfig) // all node requests from node1 and unknown node fail expectForbidden(t, getSecret(nodeanonClient)) diff --git a/test/integration/auth/rbac_test.go b/test/integration/auth/rbac_test.go index 600eb5a4a24..ea5f9594016 100644 --- a/test/integration/auth/rbac_test.go +++ b/test/integration/auth/rbac_test.go @@ -36,6 +36,7 @@ import ( "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/registry/generic" + externalclientset "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" "k8s.io/client-go/transport" "k8s.io/kubernetes/pkg/api/legacyscheme" @@ -65,10 +66,10 @@ func clientForToken(user string) *http.Client { } } -func clientsetForToken(user string, config *restclient.Config) clientset.Interface { +func clientsetForToken(user string, config *restclient.Config) (clientset.Interface, externalclientset.Interface) { configCopy := *config configCopy.BearerToken = user - return clientset.NewForConfigOrDie(&configCopy) + return clientset.NewForConfigOrDie(&configCopy), externalclientset.NewForConfigOrDie(&configCopy) } type testRESTOptionsGetter struct { @@ -431,7 +432,8 @@ func TestRBAC(t *testing.T) { clientConfig := &restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs}} // Bootstrap the API Server with the test case's initial roles. - if err := tc.bootstrapRoles.bootstrap(clientsetForToken(superUser, clientConfig)); err != nil { + superuserClient, _ := clientsetForToken(superUser, clientConfig) + if err := tc.bootstrapRoles.bootstrap(superuserClient); err != nil { t.Errorf("case %d: failed to apply initial roles: %v", i, err) continue }