@@ -13,6 +13,7 @@ import (
13
13
"k8s.io/apiserver/pkg/admission/initializer"
14
14
"k8s.io/client-go/kubernetes"
15
15
"k8s.io/client-go/rest"
16
+ "k8s.io/client-go/tools/cache"
16
17
"k8s.io/klog/v2"
17
18
"k8s.io/kubernetes/pkg/apis/rbac"
18
19
@@ -21,14 +22,53 @@ import (
21
22
userclient "github.com/openshift/client-go/user/clientset/versioned"
22
23
userinformer "github.com/openshift/client-go/user/informers/externalversions"
23
24
"github.com/openshift/library-go/pkg/apiserver/admission/admissionrestconfig"
25
+ "github.com/openshift/library-go/pkg/config/helpers"
26
+ restrictusersv1alpha1 "k8s.io/kubernetes/openshift-kube-apiserver/admission/authorization/apis/restrictusers/v1alpha1"
24
27
"k8s.io/kubernetes/openshift-kube-apiserver/admission/authorization/restrictusers/usercache"
25
28
)
26
29
30
+ const RestrictSubjectBindingsPluginName = "authorization.openshift.io/RestrictSubjectBindings"
31
+
27
32
func Register (plugins * admission.Plugins ) {
28
- plugins .Register ("authorization.openshift.io/RestrictSubjectBindings" ,
29
- func (config io.Reader ) (admission.Interface , error ) {
30
- return NewRestrictUsersAdmission ()
31
- })
33
+ plugins .Register (RestrictSubjectBindingsPluginName , pluginForConfig )
34
+ }
35
+
36
+ func pluginForConfig (config io.Reader ) (admission.Interface , error ) {
37
+ cfg , err := readConfig (config )
38
+ if err != nil {
39
+ return nil , err
40
+ }
41
+
42
+ if cfg != nil && cfg .OpenShiftOAuthDesiredState == restrictusersv1alpha1 .OpenShiftOAuthStateNotDesired {
43
+ klog .Infof ("Admission plugin %q configured to expect the OpenShift oauth-apiserver as not being available. This is effectively the same as disabling the plugin, so it will be disabled." , RestrictSubjectBindingsPluginName )
44
+ return nil , nil
45
+ }
46
+
47
+ return NewRestrictUsersAdmission ()
48
+ }
49
+
50
+ func readConfig (reader io.Reader ) (* restrictusersv1alpha1.RestrictSubjectBindingsAdmissionConfig , error ) {
51
+ obj , err := helpers .ReadYAMLToInternal (reader , restrictusersv1alpha1 .Install )
52
+ if err != nil {
53
+ return nil , err
54
+ }
55
+ if obj == nil {
56
+ return nil , nil
57
+ }
58
+ config , ok := obj .(* restrictusersv1alpha1.RestrictSubjectBindingsAdmissionConfig )
59
+ if ! ok {
60
+ return nil , fmt .Errorf ("unexpected config object: %#v" , obj )
61
+ }
62
+
63
+ // validate config
64
+ switch config .OpenShiftOAuthDesiredState {
65
+ case restrictusersv1alpha1 .OpenShiftOAuthStateDesired , restrictusersv1alpha1 .OpenShiftOAuthStateNotDesired :
66
+ // valid, do nothing
67
+ default :
68
+ return nil , fmt .Errorf ("config is invalid, openshiftOAuthDesiredState must be one of Desired,NotDesired but was %s" , config .OpenShiftOAuthDesiredState )
69
+ }
70
+
71
+ return config , nil
32
72
}
33
73
34
74
type GroupCache interface {
@@ -48,19 +88,16 @@ type restrictUsersAdmission struct {
48
88
groupCache GroupCache
49
89
}
50
90
51
- var _ = admissionrestconfig .WantsRESTClientConfig (& restrictUsersAdmission {})
52
- var _ = WantsUserInformer (& restrictUsersAdmission {})
53
- var _ = initializer .WantsExternalKubeClientSet (& restrictUsersAdmission {})
54
- var _ = admission .ValidationInterface (& restrictUsersAdmission {})
91
+ var (
92
+ _ = admissionrestconfig .WantsRESTClientConfig (& restrictUsersAdmission {})
93
+ _ = WantsUserInformer (& restrictUsersAdmission {})
94
+ _ = initializer .WantsExternalKubeClientSet (& restrictUsersAdmission {})
95
+ _ = admission .ValidationInterface (& restrictUsersAdmission {})
96
+ )
55
97
56
98
// NewRestrictUsersAdmission configures an admission plugin that enforces
57
99
// restrictions on adding role bindings in a project.
58
- func NewRestrictUsersAdmission () (admission.Interface , error ) {
59
- return & restrictUsersAdmission {
60
- Handler : admission .NewHandler (admission .Create , admission .Update ),
61
- }, nil
62
- }
63
-
100
+ func NewRestrictUsersAdmission () (admission.Interface , error )
64
101
func (q * restrictUsersAdmission ) SetExternalKubeClientSet (c kubernetes.Interface ) {
65
102
q .kubeClient = c
66
103
}
@@ -87,6 +124,11 @@ func (q *restrictUsersAdmission) SetRESTClientConfig(restClientConfig rest.Confi
87
124
}
88
125
89
126
func (q * restrictUsersAdmission ) SetUserInformer (userInformers userinformer.SharedInformerFactory ) {
127
+ if err := userInformers .User ().V1 ().Groups ().Informer ().AddIndexers (cache.Indexers {
128
+ usercache .ByUserIndexName : usercache .ByUserIndexKeys ,
129
+ }); err != nil {
130
+ return
131
+ }
90
132
q .groupCache = usercache .NewGroupCache (userInformers .User ().V1 ().Groups ())
91
133
}
92
134
@@ -116,7 +158,6 @@ func subjectsDelta(elementsToIgnore, elements []rbac.Subject) []rbac.Subject {
116
158
// each subject in the binding must be matched by some rolebinding restriction
117
159
// in the namespace.
118
160
func (q * restrictUsersAdmission ) Validate (ctx context.Context , a admission.Attributes , _ admission.ObjectInterfaces ) (err error ) {
119
-
120
161
// We only care about rolebindings
121
162
if a .GetResource ().GroupResource () != rbac .Resource ("rolebindings" ) {
122
163
return nil
0 commit comments