Skip to content

Commit a2b5091

Browse files
committed
move authorizer into the construction of the kubeapiserver
1 parent 5898a96 commit a2b5091

File tree

10 files changed

+129
-131
lines changed

10 files changed

+129
-131
lines changed

pkg/cmd/openshift-apiserver/server.go

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
kerrors "k8s.io/apimachinery/pkg/api/errors"
77
utilwait "k8s.io/apimachinery/pkg/util/wait"
88
"k8s.io/client-go/pkg/version"
9-
"k8s.io/client-go/tools/cache"
109
"k8s.io/kubernetes/pkg/capabilities"
1110
kubelettypes "k8s.io/kubernetes/pkg/kubelet/types"
1211

@@ -15,7 +14,6 @@ import (
1514
"github.com/openshift/origin/pkg/cmd/server/origin"
1615
"github.com/openshift/origin/pkg/cmd/util"
1716
"github.com/openshift/origin/pkg/cmd/util/variable"
18-
usercache "github.com/openshift/origin/pkg/user/cache"
1917
)
2018

2119
func RunOpenShiftAPIServer(masterConfig *configapi.MasterConfig) error {
@@ -46,18 +44,8 @@ func RunOpenShiftAPIServer(masterConfig *configapi.MasterConfig) error {
4644
if err != nil {
4745
return err
4846
}
49-
informers, err := origin.NewInformers(clientConfig)
50-
if err != nil {
51-
return err
52-
}
53-
54-
if err := informers.GetOpenshiftUserInformers().User().V1().Groups().Informer().AddIndexers(cache.Indexers{
55-
usercache.ByUserIndexName: usercache.ByUserIndexKeys,
56-
}); err != nil {
57-
return err
58-
}
5947

60-
openshiftConfig, err := origin.BuildMasterConfig(*masterConfig, informers)
48+
openshiftConfig, err := origin.BuildMasterConfig(*masterConfig, clientConfig)
6149
if err != nil {
6250
return err
6351
}

pkg/cmd/openshift-kube-apiserver/server.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ func RunOpenShiftKubeAPIServerServer(masterConfig *configapi.MasterConfig) error
4343
return kerrors.NewInvalid(configapi.Kind("MasterConfig"), "master-config.yaml", validationResults.Errors)
4444
}
4545

46-
informers := origin.InformerAccess(nil) // use real kube-apiserver loopback client with secret token instead of that from masterConfig.MasterClients.OpenShiftLoopbackKubeConfig
47-
openshiftConfig, err := origin.BuildMasterConfig(*masterConfig, informers)
46+
openshiftConfig, err := origin.BuildMasterConfig(*masterConfig, nil)
4847
if err != nil {
4948
return err
5049
}

pkg/cmd/server/apis/config/helpers.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ func GetKubeConfigOrInClusterConfig(kubeConfigFile string, overrides *ClientConn
257257
if err != nil {
258258
return nil, err
259259
}
260-
applyClientConnectionOverrides(overrides, clientConfig)
260+
ApplyClientConnectionOverrides(overrides, clientConfig)
261261
clientConfig.WrapTransport = DefaultClientTransport
262262

263263
return clientConfig, nil
@@ -276,14 +276,14 @@ func GetClientConfig(kubeConfigFile string, overrides *ClientConnectionOverrides
276276
if err != nil {
277277
return nil, err
278278
}
279-
applyClientConnectionOverrides(overrides, clientConfig)
279+
ApplyClientConnectionOverrides(overrides, clientConfig)
280280
clientConfig.WrapTransport = DefaultClientTransport
281281

282282
return clientConfig, nil
283283
}
284284

285285
// applyClientConnectionOverrides updates a kubeConfig with the overrides from the config.
286-
func applyClientConnectionOverrides(overrides *ClientConnectionOverrides, kubeConfig *restclient.Config) {
286+
func ApplyClientConnectionOverrides(overrides *ClientConnectionOverrides, kubeConfig *restclient.Config) {
287287
if overrides == nil {
288288
return
289289
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package master
2+
3+
import (
4+
"k8s.io/apiserver/pkg/authentication/user"
5+
"k8s.io/apiserver/pkg/authorization/authorizer"
6+
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
7+
authorizerunion "k8s.io/apiserver/pkg/authorization/union"
8+
kinformers "k8s.io/client-go/informers"
9+
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
10+
kinternalinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
11+
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/node"
12+
rbacauthorizer "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac"
13+
kbootstrappolicy "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
14+
15+
openshiftauthorizer "github.com/openshift/origin/pkg/authorization/authorizer"
16+
"github.com/openshift/origin/pkg/authorization/authorizer/browsersafe"
17+
"github.com/openshift/origin/pkg/authorization/authorizer/scope"
18+
)
19+
20+
func NewAuthorizer(internalInformers kinternalinformers.SharedInformerFactory, informers kinformers.SharedInformerFactory, projectRequestDenyMessage string) authorizer.Authorizer {
21+
messageMaker := openshiftauthorizer.NewForbiddenMessageResolver(projectRequestDenyMessage)
22+
rbacInformers := informers.Rbac().V1()
23+
24+
scopeLimitedAuthorizer := scope.NewAuthorizer(rbacInformers.ClusterRoles().Lister(), messageMaker)
25+
26+
kubeAuthorizer := rbacauthorizer.New(
27+
&rbacauthorizer.RoleGetter{Lister: rbacInformers.Roles().Lister()},
28+
&rbacauthorizer.RoleBindingLister{Lister: rbacInformers.RoleBindings().Lister()},
29+
&rbacauthorizer.ClusterRoleGetter{Lister: rbacInformers.ClusterRoles().Lister()},
30+
&rbacauthorizer.ClusterRoleBindingLister{Lister: rbacInformers.ClusterRoleBindings().Lister()},
31+
)
32+
33+
graph := node.NewGraph()
34+
node.AddGraphEventHandlers(
35+
graph,
36+
internalInformers.Core().InternalVersion().Nodes(),
37+
internalInformers.Core().InternalVersion().Pods(),
38+
internalInformers.Core().InternalVersion().PersistentVolumes(),
39+
informers.Storage().V1beta1().VolumeAttachments(),
40+
)
41+
nodeAuthorizer := node.NewAuthorizer(graph, nodeidentifier.NewDefaultNodeIdentifier(), kbootstrappolicy.NodeRules())
42+
43+
openshiftAuthorizer := authorizerunion.New(
44+
// Wrap with an authorizer that detects unsafe requests and modifies verbs/resources appropriately so policy can address them separately.
45+
// Scopes are first because they will authoritatively deny and can logically be attached to anyone.
46+
browsersafe.NewBrowserSafeAuthorizer(scopeLimitedAuthorizer, user.AllAuthenticated),
47+
// authorizes system:masters to do anything, just like upstream
48+
authorizerfactory.NewPrivilegedGroups(user.SystemPrivilegedGroup),
49+
nodeAuthorizer,
50+
// Wrap with an authorizer that detects unsafe requests and modifies verbs/resources appropriately so policy can address them separately
51+
browsersafe.NewBrowserSafeAuthorizer(openshiftauthorizer.NewAuthorizer(kubeAuthorizer, messageMaker), user.AllAuthenticated),
52+
)
53+
54+
return openshiftAuthorizer
55+
}

pkg/cmd/server/kubernetes/master/master_config.go

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import (
3232
"k8s.io/apiserver/pkg/audit"
3333
auditpolicy "k8s.io/apiserver/pkg/audit/policy"
3434
"k8s.io/apiserver/pkg/authentication/authenticator"
35-
"k8s.io/apiserver/pkg/authorization/authorizer"
3635
apiserverendpointsopenapi "k8s.io/apiserver/pkg/endpoints/openapi"
3736
apirequest "k8s.io/apiserver/pkg/endpoints/request"
3837
"k8s.io/apiserver/pkg/registry/generic"
@@ -48,6 +47,7 @@ import (
4847
auditlog "k8s.io/apiserver/plugin/pkg/audit/log"
4948
auditwebhook "k8s.io/apiserver/plugin/pkg/audit/webhook"
5049
pluginwebhook "k8s.io/apiserver/plugin/pkg/audit/webhook"
50+
kinformers "k8s.io/client-go/informers"
5151
"k8s.io/client-go/rest"
5252
"k8s.io/kube-aggregator/pkg/apis/apiregistration"
5353
apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1"
@@ -65,6 +65,8 @@ import (
6565
"k8s.io/kubernetes/pkg/apis/policy"
6666
storageapi "k8s.io/kubernetes/pkg/apis/storage"
6767
storageapiv1beta1 "k8s.io/kubernetes/pkg/apis/storage/v1beta1"
68+
kclientsetinternal "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
69+
kinternalinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
6870
"k8s.io/kubernetes/pkg/kubeapiserver"
6971
"k8s.io/kubernetes/pkg/master"
7072
"k8s.io/kubernetes/pkg/registry/cachesize"
@@ -89,6 +91,7 @@ import (
8991
// TODO fix this install, it is required for TestPreferredGroupVersions to pass
9092
"github.com/openshift/api/security"
9193
_ "github.com/openshift/origin/pkg/authorization/apis/authorization/install"
94+
"k8s.io/client-go/kubernetes"
9295
)
9396

9497
// request paths that match this regular expression will be treated as long running
@@ -378,13 +381,16 @@ func buildPublicAddress(masterConfig configapi.MasterConfig) (net.IP, error) {
378381
return publicAddress, nil
379382
}
380383

381-
type incompleteKubeMasterConfig struct {
384+
type IncompleteKubeMasterConfig struct {
382385
options *kapiserveroptions.ServerRunOptions
383-
incompleteConfig *apiserver.Config
386+
IncompleteConfig *apiserver.Config
384387
masterConfig configapi.MasterConfig
388+
389+
InternalKubernetesInformers kinternalinformers.SharedInformerFactory
390+
KubernetesInformers kinformers.SharedInformerFactory
385391
}
386392

387-
func BuildKubernetesMasterConfig(masterConfig configapi.MasterConfig) (*incompleteKubeMasterConfig, error) {
393+
func BuildKubernetesMasterConfig(masterConfig configapi.MasterConfig) (*IncompleteKubeMasterConfig, error) {
388394
apiserverOptions, err := BuildKubeAPIserverOptions(masterConfig)
389395
if err != nil {
390396
return nil, err
@@ -395,19 +401,40 @@ func BuildKubernetesMasterConfig(masterConfig configapi.MasterConfig) (*incomple
395401
return nil, err
396402
}
397403

398-
return &incompleteKubeMasterConfig{apiserverOptions, genericConfig, masterConfig}, nil
404+
configapi.ApplyClientConnectionOverrides(masterConfig.MasterClients.OpenShiftLoopbackClientConnectionOverrides, genericConfig.LoopbackClientConfig)
405+
kubeInternalClient, err := kclientsetinternal.NewForConfig(genericConfig.LoopbackClientConfig)
406+
if err != nil {
407+
return nil, err
408+
}
409+
kubeClient, err := kubernetes.NewForConfig(genericConfig.LoopbackClientConfig)
410+
if err != nil {
411+
return nil, err
412+
}
413+
414+
const defaultInformerResyncPeriod = 10 * time.Minute
415+
internalInformers := kinternalinformers.NewSharedInformerFactory(kubeInternalClient, defaultInformerResyncPeriod)
416+
informers := kinformers.NewSharedInformerFactory(kubeClient, defaultInformerResyncPeriod)
417+
418+
genericConfig.Authorization.Authorizer = NewAuthorizer(internalInformers, informers, masterConfig.ProjectConfig.ProjectRequestMessage)
419+
420+
return &IncompleteKubeMasterConfig{
421+
options: apiserverOptions,
422+
IncompleteConfig: genericConfig,
423+
masterConfig: masterConfig,
424+
InternalKubernetesInformers: internalInformers,
425+
KubernetesInformers: informers,
426+
}, nil
399427
}
400428

401-
func (rc *incompleteKubeMasterConfig) LoopbackConfig() *rest.Config {
402-
return rc.incompleteConfig.LoopbackClientConfig
429+
func (rc *IncompleteKubeMasterConfig) LoopbackConfig() *rest.Config {
430+
return rc.IncompleteConfig.LoopbackClientConfig
403431
}
404432

405-
func (rc *incompleteKubeMasterConfig) Complete(
433+
func (rc *IncompleteKubeMasterConfig) Complete(
406434
admissionControl admission.Interface,
407435
originAuthenticator authenticator.Request,
408-
kubeAuthorizer authorizer.Authorizer,
409436
) (*master.Config, error) {
410-
genericConfig, apiserverOptions, masterConfig := rc.incompleteConfig, rc.options, rc.masterConfig
437+
genericConfig, apiserverOptions, masterConfig := rc.IncompleteConfig, rc.options, rc.masterConfig
411438

412439
proxyClientCerts, err := buildProxyClientCerts(masterConfig)
413440
if err != nil {
@@ -439,7 +466,6 @@ func (rc *incompleteKubeMasterConfig) Complete(
439466
genericConfig.Version = &kubeVersion
440467
genericConfig.PublicAddress = publicAddress
441468
genericConfig.Authentication.Authenticator = originAuthenticator // this is used to fulfill the tokenreviews endpoint which is used by node authentication
442-
genericConfig.Authorization.Authorizer = kubeAuthorizer // this is used to fulfill the kube SAR endpoints
443469
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName)
444470
// This disables the ThirdPartyController which removes handlers from our go-restful containers. The remove functionality is broken and destroys the serve mux.
445471
genericConfig.DisabledPostStartHooks.Insert("extensions/third-party-resources")

pkg/cmd/server/origin/authorizer.go

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,11 @@
11
package origin
22

33
import (
4-
"k8s.io/apiserver/pkg/authentication/user"
5-
"k8s.io/apiserver/pkg/authorization/authorizer"
6-
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
7-
authorizerunion "k8s.io/apiserver/pkg/authorization/union"
84
rbacinformers "k8s.io/client-go/informers/rbac/v1"
9-
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
105
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
11-
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/node"
126
rbacauthorizer "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac"
13-
kbootstrappolicy "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
14-
15-
openshiftauthorizer "github.com/openshift/origin/pkg/authorization/authorizer"
16-
"github.com/openshift/origin/pkg/authorization/authorizer/browsersafe"
17-
"github.com/openshift/origin/pkg/authorization/authorizer/scope"
187
)
198

20-
func NewAuthorizer(informers InformerAccess, projectRequestDenyMessage string) authorizer.Authorizer {
21-
messageMaker := openshiftauthorizer.NewForbiddenMessageResolver(projectRequestDenyMessage)
22-
rbacInformers := informers.GetKubernetesInformers().Rbac().V1()
23-
24-
scopeLimitedAuthorizer := scope.NewAuthorizer(rbacInformers.ClusterRoles().Lister(), messageMaker)
25-
26-
kubeAuthorizer := rbacauthorizer.New(
27-
&rbacauthorizer.RoleGetter{Lister: rbacInformers.Roles().Lister()},
28-
&rbacauthorizer.RoleBindingLister{Lister: rbacInformers.RoleBindings().Lister()},
29-
&rbacauthorizer.ClusterRoleGetter{Lister: rbacInformers.ClusterRoles().Lister()},
30-
&rbacauthorizer.ClusterRoleBindingLister{Lister: rbacInformers.ClusterRoleBindings().Lister()},
31-
)
32-
33-
graph := node.NewGraph()
34-
node.AddGraphEventHandlers(
35-
graph,
36-
informers.GetInternalKubernetesInformers().Core().InternalVersion().Nodes(),
37-
informers.GetInternalKubernetesInformers().Core().InternalVersion().Pods(),
38-
informers.GetInternalKubernetesInformers().Core().InternalVersion().PersistentVolumes(),
39-
informers.GetKubernetesInformers().Storage().V1beta1().VolumeAttachments(),
40-
)
41-
nodeAuthorizer := node.NewAuthorizer(graph, nodeidentifier.NewDefaultNodeIdentifier(), kbootstrappolicy.NodeRules())
42-
43-
openshiftAuthorizer := authorizerunion.New(
44-
// Wrap with an authorizer that detects unsafe requests and modifies verbs/resources appropriately so policy can address them separately.
45-
// Scopes are first because they will authoritatively deny and can logically be attached to anyone.
46-
browsersafe.NewBrowserSafeAuthorizer(scopeLimitedAuthorizer, user.AllAuthenticated),
47-
// authorizes system:masters to do anything, just like upstream
48-
authorizerfactory.NewPrivilegedGroups(user.SystemPrivilegedGroup),
49-
nodeAuthorizer,
50-
// Wrap with an authorizer that detects unsafe requests and modifies verbs/resources appropriately so policy can address them separately
51-
browsersafe.NewBrowserSafeAuthorizer(openshiftauthorizer.NewAuthorizer(kubeAuthorizer, messageMaker), user.AllAuthenticated),
52-
)
53-
54-
return openshiftAuthorizer
55-
}
56-
579
func NewRuleResolver(informers rbacinformers.Interface) rbacregistryvalidation.AuthorizationRuleResolver {
5810
return rbacregistryvalidation.NewDefaultRuleResolver(
5911
&rbacauthorizer.RoleGetter{Lister: informers.Roles().Lister()},

pkg/cmd/server/origin/informers.go

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ import (
66
"k8s.io/apimachinery/pkg/runtime"
77
"k8s.io/apimachinery/pkg/runtime/schema"
88
kexternalinformers "k8s.io/client-go/informers"
9-
kubeclientgoclient "k8s.io/client-go/kubernetes"
109
"k8s.io/client-go/rest"
11-
kclientsetinternal "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
1210
kinternalinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
1311

1412
"github.com/golang/glog"
@@ -138,16 +136,7 @@ type informerHolder struct {
138136
}
139137

140138
// NewInformers is only exposed for the build's integration testing until it can be fixed more appropriately.
141-
func NewInformers(clientConfig *rest.Config) (InformerAccess, error) {
142-
kubeInternal, err := kclientsetinternal.NewForConfig(clientConfig)
143-
if err != nil {
144-
return nil, err
145-
}
146-
kubeExternal, err := kubeclientgoclient.NewForConfig(clientConfig)
147-
if err != nil {
148-
return nil, err
149-
}
150-
139+
func NewInformers(internalKubernetesInformers kinternalinformers.SharedInformerFactory, kubernetesInformers kexternalinformers.SharedInformerFactory, clientConfig *rest.Config) (InformerAccess, error) {
151140
appsClient, err := appsclient.NewForConfig(clientConfig)
152141
if err != nil {
153142
return nil, err
@@ -199,8 +188,8 @@ func NewInformers(clientConfig *rest.Config) (InformerAccess, error) {
199188
const defaultInformerResyncPeriod = 10 * time.Minute
200189

201190
return &informerHolder{
202-
internalKubernetesInformers: kinternalinformers.NewSharedInformerFactory(kubeInternal, defaultInformerResyncPeriod),
203-
kubernetesInformers: kexternalinformers.NewSharedInformerFactory(kubeExternal, defaultInformerResyncPeriod),
191+
internalKubernetesInformers: internalKubernetesInformers,
192+
kubernetesInformers: kubernetesInformers,
204193
appsInformer: appsinformer.NewSharedInformerFactory(appsClient, defaultInformerResyncPeriod),
205194
authorizationInformers: authorizationinformer.NewSharedInformerFactory(authorizationClient, defaultInformerResyncPeriod),
206195
buildInformers: buildinformer.NewSharedInformerFactory(buildClient, defaultInformerResyncPeriod),

0 commit comments

Comments
 (0)