Skip to content

Commit 75d7d5a

Browse files
OpenShift Botsimo5
OpenShift Bot
authored andcommitted
Proxy Cluster Roles to Native Kube RBAC Cluster Roles
Store ClusterRoles as native RBAC Objects via Kubernetes. Provides backwards compatible API for the old policy based roles.
1 parent fc34104 commit 75d7d5a

File tree

6 files changed

+120
-78
lines changed

6 files changed

+120
-78
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,150 @@
1-
package proxy
1+
package rbac
22

33
import (
4+
apierrors "k8s.io/apimachinery/pkg/api/errors"
45
metainternal "k8s.io/apimachinery/pkg/apis/meta/internalversion"
56
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
67
"k8s.io/apimachinery/pkg/runtime"
78
apirequest "k8s.io/apiserver/pkg/endpoints/request"
89
"k8s.io/apiserver/pkg/registry/rest"
10+
"k8s.io/kubernetes/pkg/api"
11+
"k8s.io/kubernetes/pkg/apis/rbac"
12+
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion"
913

10-
authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization"
11-
clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
12-
"github.com/openshift/origin/pkg/authorization/registry/clusterrole"
13-
roleregistry "github.com/openshift/origin/pkg/authorization/registry/role"
14-
rolestorage "github.com/openshift/origin/pkg/authorization/registry/role/policybased"
15-
"github.com/openshift/origin/pkg/authorization/rulevalidation"
14+
authzapi "github.com/openshift/origin/pkg/authorization/apis/authorization"
1615
)
1716

18-
type ClusterRoleStorage struct {
19-
roleStorage rolestorage.VirtualStorage
17+
func rbacToClusterRole(in *rbac.ClusterRole) (authzapi.ClusterRole, error) {
18+
var out authzapi.ClusterRole
19+
err := authzapi.Convert_rbac_ClusterRole_To_authorization_ClusterRole(in, &out, nil)
20+
return out, err
2021
}
2122

22-
func NewClusterRoleStorage(clusterPolicyRegistry clusterpolicyregistry.Registry, liveRuleResolver, cachedRuleResolver rulevalidation.AuthorizationRuleResolver) clusterrole.Storage {
23-
return &ClusterRoleStorage{
24-
roleStorage: rolestorage.VirtualStorage{
25-
PolicyStorage: clusterpolicyregistry.NewSimulatedRegistry(clusterPolicyRegistry),
23+
func rbacFromClusterRole(in *authzapi.ClusterRole) (rbac.ClusterRole, error) {
24+
var out rbac.ClusterRole
25+
err := authzapi.Convert_authorization_ClusterRole_To_rbac_ClusterRole(in, &out, nil)
26+
return out, err
27+
}
2628

27-
RuleResolver: liveRuleResolver,
28-
CachedRuleResolver: cachedRuleResolver,
29+
type ClusterRoleStorage struct {
30+
client internalversion.ClusterRoleInterface
31+
}
2932

30-
CreateStrategy: roleregistry.ClusterStrategy,
31-
UpdateStrategy: roleregistry.ClusterStrategy,
32-
Resource: authorizationapi.Resource("clusterrole"),
33-
},
34-
}
33+
func NewREST(client internalversion.ClusterRoleInterface) *ClusterRoleStorage {
34+
return &ClusterRoleStorage{client}
3535
}
3636

3737
func (s *ClusterRoleStorage) New() runtime.Object {
38-
return &authorizationapi.ClusterRole{}
38+
return &authzapi.ClusterRole{}
3939
}
4040
func (s *ClusterRoleStorage) NewList() runtime.Object {
41-
return &authorizationapi.ClusterRoleList{}
41+
return &authzapi.ClusterRoleList{}
4242
}
4343

4444
func (s *ClusterRoleStorage) List(ctx apirequest.Context, options *metainternal.ListOptions) (runtime.Object, error) {
45-
ret, err := s.roleStorage.List(ctx, options)
46-
if ret == nil {
45+
optv1 := metav1.ListOptions{}
46+
if err := metainternal.Convert_internalversion_ListOptions_To_v1_ListOptions(options, &optv1, nil); err != nil {
4747
return nil, err
4848
}
49-
return authorizationapi.ToClusterRoleList(ret.(*authorizationapi.RoleList)), err
49+
roles, err := s.client.List(optv1)
50+
if roles == nil {
51+
return nil, err
52+
}
53+
ret := &authzapi.ClusterRoleList{}
54+
for _, curr := range roles.Items {
55+
role, err := rbacToClusterRole(&curr)
56+
if err != nil {
57+
return nil, err
58+
}
59+
ret.Items = append(ret.Items, role)
60+
}
61+
return ret, err
5062
}
5163

5264
func (s *ClusterRoleStorage) Get(ctx apirequest.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
53-
ret, err := s.roleStorage.Get(ctx, name, options)
54-
if ret == nil {
65+
ret, err := s.client.Get(name, *options)
66+
if err != nil {
5567
return nil, err
5668
}
57-
58-
return authorizationapi.ToClusterRole(ret.(*authorizationapi.Role)), err
69+
role, err := rbacToClusterRole(ret)
70+
if err != nil {
71+
return nil, err
72+
}
73+
return &role, err
5974
}
75+
6076
func (s *ClusterRoleStorage) Delete(ctx apirequest.Context, name string, options *metav1.DeleteOptions) (runtime.Object, bool, error) {
61-
ret, immediate, err := s.roleStorage.Delete(ctx, name, options)
62-
if ret == nil {
63-
return nil, immediate, err
77+
if err := s.client.Delete(name, options); err != nil {
78+
return nil, false, err
6479
}
6580

66-
return ret.(*metav1.Status), false, err
81+
return &metav1.Status{Status: metav1.StatusSuccess}, true, nil
6782
}
6883

6984
func (s *ClusterRoleStorage) Create(ctx apirequest.Context, obj runtime.Object) (runtime.Object, error) {
70-
clusterObj := obj.(*authorizationapi.ClusterRole)
71-
convertedObj := authorizationapi.ToRole(clusterObj)
85+
clusterObj := obj.(*authzapi.ClusterRole)
86+
convertedObj, err := rbacFromClusterRole(clusterObj)
7287

73-
ret, err := s.roleStorage.Create(ctx, convertedObj)
74-
if ret == nil {
88+
ret, err := s.client.Create(&convertedObj)
89+
if err != nil {
7590
return nil, err
7691
}
77-
78-
return authorizationapi.ToClusterRole(ret.(*authorizationapi.Role)), err
79-
}
80-
81-
type convertingObjectInfo struct {
82-
rest.UpdatedObjectInfo
83-
}
84-
85-
func (i convertingObjectInfo) UpdatedObject(ctx apirequest.Context, old runtime.Object) (runtime.Object, error) {
86-
oldObj := old.(*authorizationapi.Role)
87-
convertedOldObj := authorizationapi.ToClusterRole(oldObj)
88-
obj, err := i.UpdatedObjectInfo.UpdatedObject(ctx, convertedOldObj)
92+
role, err := rbacToClusterRole(ret)
8993
if err != nil {
9094
return nil, err
9195
}
92-
clusterObj := obj.(*authorizationapi.ClusterRole)
93-
convertedObj := authorizationapi.ToRole(clusterObj)
94-
return convertedObj, nil
96+
return &role, err
9597
}
9698

9799
func (s *ClusterRoleStorage) Update(ctx apirequest.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
98-
ret, created, err := s.roleStorage.Update(ctx, name, convertingObjectInfo{objInfo})
99-
if ret == nil {
100-
return nil, created, err
100+
old, err := s.client.Get(name, metav1.GetOptions{})
101+
if err != nil {
102+
if apierrors.IsNotFound(err) {
103+
err = apierrors.NewNotFound(rbac.Resource("clusterrole"), name)
104+
}
105+
return nil, false, err
101106
}
102107

103-
return authorizationapi.ToClusterRole(ret.(*authorizationapi.Role)), created, err
104-
}
108+
oldRole, err := rbacToClusterRole(old)
109+
if err != nil {
110+
return nil, false, err
111+
}
105112

106-
func (m *ClusterRoleStorage) CreateClusterRoleWithEscalation(ctx apirequest.Context, obj *authorizationapi.ClusterRole) (*authorizationapi.ClusterRole, error) {
107-
in := authorizationapi.ToRole(obj)
108-
ret, err := m.roleStorage.CreateRoleWithEscalation(ctx, in)
109-
return authorizationapi.ToClusterRole(ret), err
110-
}
113+
obj, err := objInfo.UpdatedObject(ctx, &oldRole)
114+
if err != nil {
115+
return nil, false, err
116+
}
117+
118+
updatedRole, err := rbacFromClusterRole(obj.(*authzapi.ClusterRole))
119+
if err != nil {
120+
return nil, false, err
121+
}
111122

112-
func (m *ClusterRoleStorage) UpdateClusterRoleWithEscalation(ctx apirequest.Context, obj *authorizationapi.ClusterRole) (*authorizationapi.ClusterRole, bool, error) {
113-
in := authorizationapi.ToRole(obj)
114-
ret, created, err := m.roleStorage.UpdateRoleWithEscalation(ctx, in)
115-
return authorizationapi.ToClusterRole(ret), created, err
123+
ret, err := s.client.Update(&updatedRole)
124+
if err != nil {
125+
return nil, false, err
126+
}
127+
128+
role, err := rbacToClusterRole(ret)
129+
if err != nil {
130+
return nil, false, err
131+
}
132+
return &role, false, err
116133
}
117134

118-
func (m *ClusterRoleStorage) CreateRoleWithEscalation(ctx apirequest.Context, obj *authorizationapi.Role) (*authorizationapi.Role, error) {
119-
return m.roleStorage.CreateRoleWithEscalation(ctx, obj)
135+
// FIXME: what's escalation exactly ?
136+
func (m *ClusterRoleStorage) CreateClusterRoleWithEscalation(ctx apirequest.Context, obj *authzapi.ClusterRole) (*authzapi.ClusterRole, error) {
137+
ret, err := m.Create(ctx, obj)
138+
if err != nil {
139+
return nil, err
140+
}
141+
return ret.(*authzapi.ClusterRole), err
120142
}
121143

122-
func (m *ClusterRoleStorage) UpdateRoleWithEscalation(ctx apirequest.Context, obj *authorizationapi.Role) (*authorizationapi.Role, bool, error) {
123-
return m.roleStorage.UpdateRoleWithEscalation(ctx, obj)
144+
func (m *ClusterRoleStorage) UpdateClusterRoleWithEscalation(ctx apirequest.Context, obj *authzapi.ClusterRole) (*authzapi.ClusterRole, bool, error) {
145+
ret, ignored, err := m.Update(ctx, obj.Name, rest.DefaultUpdatedObjectInfo(obj, api.Scheme))
146+
if err != nil {
147+
return nil, false, err
148+
}
149+
return ret.(*authzapi.ClusterRole), ignored, err
124150
}

pkg/authorization/util/util.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"k8s.io/apimachinery/pkg/runtime/schema"
88
"k8s.io/apiserver/pkg/authentication/user"
99
"k8s.io/kubernetes/pkg/apis/authorization"
10+
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
1011
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authorization/internalversion"
1112

1213
clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
@@ -83,7 +84,7 @@ func NewLiveRuleResolver(policyRegistry policyregistry.Registry, policyBindingRe
8384
)
8485
}
8586

86-
func GetAuthorizationStorage(optsGetter restoptions.Getter, cachedRuleResolver rulevalidation.AuthorizationRuleResolver) (*AuthorizationStorage, error) {
87+
func GetAuthorizationStorage(optsGetter restoptions.Getter, kubeClient internalclientset.Interface, cachedRuleResolver rulevalidation.AuthorizationRuleResolver) (*AuthorizationStorage, error) {
8788
policyStorage, err := policyetcd.NewREST(optsGetter)
8889
if err != nil {
8990
return nil, err
@@ -112,7 +113,7 @@ func GetAuthorizationStorage(optsGetter restoptions.Getter, cachedRuleResolver r
112113

113114
roleStorage := rolestorage.NewVirtualStorage(policyRegistry, liveRuleResolver, cachedRuleResolver)
114115
roleBindingStorage := rolebindingstorage.NewVirtualStorage(policyBindingRegistry, liveRuleResolver, cachedRuleResolver)
115-
clusterRoleStorage := clusterrolestorage.NewClusterRoleStorage(clusterPolicyRegistry, liveRuleResolver, cachedRuleResolver)
116+
clusterRoleStorage := clusterrolestorage.NewREST(kubeClient.Rbac().ClusterRoles())
116117
clusterRoleBindingStorage := clusterrolebindingstorage.NewClusterRoleBindingStorage(clusterPolicyBindingRegistry, liveRuleResolver, cachedRuleResolver)
117118

118119
return &AuthorizationStorage{

pkg/cmd/server/admin/overwrite_bootstrappolicy.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/openshift/origin/pkg/authorization/util"
2222

2323
"github.com/openshift/origin/pkg/cmd/cli/describe"
24+
configapi "github.com/openshift/origin/pkg/cmd/server/api"
2425
configapilatest "github.com/openshift/origin/pkg/cmd/server/api/latest"
2526
originrest "github.com/openshift/origin/pkg/cmd/server/origin/rest"
2627
templateapi "github.com/openshift/origin/pkg/template/apis/template"
@@ -95,10 +96,11 @@ func (o OverwriteBootstrapPolicyOptions) OverwriteBootstrapPolicy() error {
9596
return err
9697
}
9798

98-
return OverwriteBootstrapPolicy(optsGetter, o.File, o.CreateBootstrapPolicyCommand, o.Force, o.Out)
99+
return OverwriteBootstrapPolicy(optsGetter, o.File, o.MasterConfigFile, o.CreateBootstrapPolicyCommand, o.Force, o.Out)
99100
}
100101

101-
func OverwriteBootstrapPolicy(optsGetter restoptions.Getter, policyFile, createBootstrapPolicyCommand string, change bool, out io.Writer) error {
102+
func OverwriteBootstrapPolicy(optsGetter restoptions.Getter, policyFile, kubeConfigFile, createBootstrapPolicyCommand string, change bool, out io.Writer) error {
103+
102104
if !change {
103105
fmt.Fprintf(out, "Performing a dry run of policy overwrite:\n\n")
104106
}
@@ -118,7 +120,12 @@ func OverwriteBootstrapPolicy(optsGetter restoptions.Getter, policyFile, createB
118120
return r.Err()
119121
}
120122

121-
authStorage, err := util.GetAuthorizationStorage(optsGetter, nil)
123+
kubeClient, _, err := configapi.GetInternalKubeClient(kubeConfigFile, nil)
124+
if err != nil {
125+
return err
126+
}
127+
128+
authStorage, err := util.GetAuthorizationStorage(optsGetter, kubeClient, nil)
122129
if err != nil {
123130
return err
124131
}

pkg/cmd/server/origin/ensure.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,11 @@ func (c *MasterConfig) ensureComponentAuthorizationRules() {
182182
if _, err := clusterPolicyRegistry.GetClusterPolicy(ctx, authorizationapi.PolicyName, &metav1.GetOptions{}); kapierror.IsNotFound(err) {
183183
glog.Infof("No cluster policy found. Creating bootstrap policy based on: %v", c.Options.PolicyConfig.BootstrapPolicyFile)
184184

185-
if err := admin.OverwriteBootstrapPolicy(c.RESTOptionsGetter, c.Options.PolicyConfig.BootstrapPolicyFile, admin.CreateBootstrapPolicyFileFullCommand, true, ioutil.Discard); err != nil {
185+
if err := admin.OverwriteBootstrapPolicy(c.RESTOptionsGetter,
186+
c.Options.PolicyConfig.BootstrapPolicyFile,
187+
c.Options.MasterClients.OpenShiftLoopbackKubeConfig,
188+
admin.CreateBootstrapPolicyFileFullCommand,
189+
true, ioutil.Discard); err != nil {
186190
glog.Errorf("Error creating bootstrap policy: %v", err)
187191
}
188192

pkg/cmd/server/origin/storage.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func (c OpenshiftAPIConfig) GetRestStorage() (map[schema.GroupVersion]map[string
204204
selfSubjectRulesReviewStorage := selfsubjectrulesreview.NewREST(c.RuleResolver, clusterPolicies)
205205
subjectRulesReviewStorage := subjectrulesreview.NewREST(c.RuleResolver, clusterPolicies)
206206

207-
authStorage, err := util.GetAuthorizationStorage(c.GenericConfig.RESTOptionsGetter, c.RuleResolver)
207+
authStorage, err := util.GetAuthorizationStorage(c.GenericConfig.RESTOptionsGetter, c.KubeClientInternal, c.RuleResolver)
208208
if err != nil {
209209
return nil, fmt.Errorf("error building authorization REST storage: %v", err)
210210
}

test/integration/bootstrap_policy_test.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ func TestBootstrapPolicyOverwritePolicyCommand(t *testing.T) {
115115
t.Errorf("unexpected error: %v", err)
116116
}
117117

118-
if err := admin.OverwriteBootstrapPolicy(optsGetter, masterConfig.PolicyConfig.BootstrapPolicyFile, admin.CreateBootstrapPolicyFileFullCommand, true, ioutil.Discard); err != nil {
118+
if err := admin.OverwriteBootstrapPolicy(optsGetter,
119+
masterConfig.PolicyConfig.BootstrapPolicyFile,
120+
masterConfig.MasterClients.OpenShiftLoopbackKubeConfig,
121+
admin.CreateBootstrapPolicyFileFullCommand,
122+
true, ioutil.Discard); err != nil {
119123
t.Errorf("unexpected error: %v", err)
120124
}
121125

0 commit comments

Comments
 (0)