Skip to content

Commit 11c3769

Browse files
authored
Merge pull request #52 from fxiang1/feng-existingrole
Support existing roles for ClusterPermission
2 parents dddde5d + 0c673ff commit 11c3769

7 files changed

+312
-18
lines changed

api/v1alpha1/clusterpermission_types.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ type ClusterRoleBinding struct {
5858
// Besides the typical subject for a binding, a ManagedServiceAccount can be used as a subject as well.
5959
// +required
6060
rbacv1.Subject `json:"subject"`
61+
62+
// Name of the ClusterRoleBinding if a name different than the ClusterPermission name is used
63+
// +optional
64+
Name string `json:"name,omitempty" protobuf:"bytes,4,opt,name=name"`
65+
66+
// RoleRef contains information that points to the ClusterRole being used
67+
// +optional
68+
RoleRef *rbacv1.RoleRef `json:"roleRef,omitempty"`
6169
}
6270

6371
// Role represents the Role that is being created on the managed cluster
@@ -95,13 +103,25 @@ type RoleBinding struct {
95103
// Note: the namespace must exists on the hub cluster
96104
// +optional
97105
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"`
106+
107+
// Name of the RoleBinding if a name different than the ClusterPermission name is used
108+
// +optional
109+
Name string `json:"name,omitempty" protobuf:"bytes,4,opt,name=name"`
98110
}
99111

100112
// RoleRef contains information that points to the role being used
101113
type RoleRef struct {
102114
// Kind is the type of resource being referenced
103115
// +required
104116
Kind string `json:"kind"`
117+
118+
// APIGroup is the group for the resource being referenced
119+
// +optional
120+
APIGroup string `json:"apiGroup" protobuf:"bytes,1,opt,name=apiGroup"`
121+
122+
// Name is the name of resource being referenced
123+
// +optional
124+
Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
105125
}
106126

107127
// ClusterPermissionStatus defines the observed state of ClusterPermission

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chart/crds/rbac.open-cluster-management.io_clusterpermissions.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,30 @@ spec:
101101
description: ClusterRoleBinding represents the ClusterRoleBinding
102102
that is being created on the managed cluster
103103
properties:
104+
name:
105+
description: Name of the ClusterRoleBinding if a name different
106+
than the ClusterPermission name is used
107+
type: string
108+
roleRef:
109+
description: RoleRef contains information that points to the ClusterRole
110+
being used
111+
properties:
112+
apiGroup:
113+
description: APIGroup is the group for the resource being
114+
referenced
115+
type: string
116+
kind:
117+
description: Kind is the type of resource being referenced
118+
type: string
119+
name:
120+
description: Name is the name of resource being referenced
121+
type: string
122+
required:
123+
- apiGroup
124+
- kind
125+
- name
126+
type: object
127+
x-kubernetes-map-type: atomic
104128
subject:
105129
description: |-
106130
Subject contains a reference to the object or user identities a ClusterPermission binding applies to.
@@ -140,6 +164,10 @@ spec:
140164
description: RoleBinding represents the RoleBinding that is being
141165
created on the managed cluster
142166
properties:
167+
name:
168+
description: Name of the RoleBinding if a name different than
169+
the ClusterPermission name is used
170+
type: string
143171
namespace:
144172
description: Namespace of the Role for that is being created
145173
on the managed cluster
@@ -196,9 +224,16 @@ spec:
196224
description: RoleRef contains information that points to the
197225
role being used
198226
properties:
227+
apiGroup:
228+
description: APIGroup is the group for the resource being
229+
referenced
230+
type: string
199231
kind:
200232
description: Kind is the type of resource being referenced
201233
type: string
234+
name:
235+
description: Name is the name of resource being referenced
236+
type: string
202237
required:
203238
- kind
204239
type: object

config/crds/rbac.open-cluster-management.io_clusterpermissions.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,30 @@ spec:
101101
description: ClusterRoleBinding represents the ClusterRoleBinding
102102
that is being created on the managed cluster
103103
properties:
104+
name:
105+
description: Name of the ClusterRoleBinding if a name different
106+
than the ClusterPermission name is used
107+
type: string
108+
roleRef:
109+
description: RoleRef contains information that points to the ClusterRole
110+
being used
111+
properties:
112+
apiGroup:
113+
description: APIGroup is the group for the resource being
114+
referenced
115+
type: string
116+
kind:
117+
description: Kind is the type of resource being referenced
118+
type: string
119+
name:
120+
description: Name is the name of resource being referenced
121+
type: string
122+
required:
123+
- apiGroup
124+
- kind
125+
- name
126+
type: object
127+
x-kubernetes-map-type: atomic
104128
subject:
105129
description: |-
106130
Subject contains a reference to the object or user identities a ClusterPermission binding applies to.
@@ -140,6 +164,10 @@ spec:
140164
description: RoleBinding represents the RoleBinding that is being
141165
created on the managed cluster
142166
properties:
167+
name:
168+
description: Name of the RoleBinding if a name different than
169+
the ClusterPermission name is used
170+
type: string
143171
namespace:
144172
description: Namespace of the Role for that is being created
145173
on the managed cluster
@@ -196,9 +224,16 @@ spec:
196224
description: RoleRef contains information that points to the
197225
role being used
198226
properties:
227+
apiGroup:
228+
description: APIGroup is the group for the resource being
229+
referenced
230+
type: string
199231
kind:
200232
description: Kind is the type of resource being referenced
201233
type: string
234+
name:
235+
description: Name is the name of resource being referenced
236+
type: string
202237
required:
203238
- kind
204239
type: object
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
apiVersion: rbac.open-cluster-management.io/v1alpha1
2+
kind: ClusterPermission
3+
metadata:
4+
name: clusterpermission-existing-role-sample
5+
spec:
6+
roleBindings:
7+
- name: default-rb-cluster1
8+
namespace: default
9+
roleRef:
10+
apiGroup: rbac.authorization.k8s.io
11+
kind: ClusterRole
12+
name: argocd-application-controller-1
13+
subject:
14+
namespace: openshift-gitops
15+
kind: ServiceAccount
16+
name: sa-sample-existing
17+
- name: kubevirt-rb-cluster1
18+
namespace: kubevirt
19+
roleRef:
20+
apiGroup: rbac.authorization.k8s.io
21+
kind: Role
22+
name: argocd-application-controller-2
23+
subject:
24+
apiGroup: rbac.authorization.k8s.io
25+
kind: User
26+
name: user1
27+
clusterRoleBinding:
28+
name: crb-cluster1-argo-app-con-3
29+
roleRef:
30+
apiGroup: rbac.authorization.k8s.io
31+
kind: ClusterRole
32+
name: argocd-application-controller-3
33+
subject:
34+
apiGroup: rbac.authorization.k8s.io
35+
kind: Group
36+
name: group1

controllers/clusterpermission_controller.go

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,19 @@ func (r *ClusterPermissionReconciler) Reconcile(ctx context.Context, req ctrl.Re
8282
log.Info("validating ClusterPermission")
8383

8484
/* Validations */
85-
if clusterPermission.Spec.ClusterRole == nil && clusterPermission.Spec.Roles == nil {
86-
log.Info("no roles defined for ClusterPermission")
85+
if clusterPermission.Spec.ClusterRoleBinding == nil && clusterPermission.Spec.RoleBindings == nil {
86+
log.Info("no bindings defined for ClusterPermission")
8787

8888
err := r.updateStatus(ctx, &clusterPermission, &metav1.Condition{
8989
Type: cpv1alpha1.ConditionTypeValidation,
9090
Status: metav1.ConditionFalse,
91-
Reason: "FailedValidationNoRolesDefined",
92-
Message: "no roles defined",
91+
Reason: "FailedValidationNoBindingsDefined",
92+
Message: "no bindings defined",
9393
})
9494

9595
return ctrl.Result{}, err
9696
}
97+
9798
// verify the ClusterPermission namespace is in a ManagedCluster namespace
9899
var managedCluster clusterv1.ManagedCluster
99100
if err := r.Get(ctx, types.NamespacedName{Name: clusterPermission.Namespace}, &managedCluster); err != nil {
@@ -260,19 +261,31 @@ func (r *ClusterPermissionReconciler) generateManifestWorkPayload(ctx context.Co
260261
return nil, nil, nil, nil, err
261262
}
262263

264+
// default to ClusterPermission name unless using custom name
265+
clusterRoleBindingName := clusterPermission.Name
266+
if clusterPermission.Spec.ClusterRoleBinding.Name != "" {
267+
clusterRoleBindingName = clusterPermission.Spec.ClusterRoleBinding.Name
268+
}
269+
270+
// default to creating a ClusterRole unless using existing ClusterRole
271+
clusterRoleBindingRoleRef := rbacv1.RoleRef{
272+
APIGroup: rbacv1.GroupName,
273+
Kind: "ClusterRole",
274+
Name: clusterPermission.Name,
275+
}
276+
if clusterPermission.Spec.ClusterRoleBinding.RoleRef != nil {
277+
clusterRoleBindingRoleRef = *clusterPermission.Spec.ClusterRoleBinding.RoleRef
278+
}
279+
263280
clusterRoleBinding = &rbacv1.ClusterRoleBinding{
264281
TypeMeta: metav1.TypeMeta{
265282
APIVersion: rbacv1.SchemeGroupVersion.String(),
266283
Kind: "ClusterRoleBinding",
267284
},
268285
ObjectMeta: metav1.ObjectMeta{
269-
Name: clusterPermission.Name,
270-
},
271-
RoleRef: rbacv1.RoleRef{
272-
APIGroup: rbacv1.GroupName,
273-
Kind: "ClusterRole",
274-
Name: clusterPermission.Name,
286+
Name: clusterRoleBindingName,
275287
},
288+
RoleRef: clusterRoleBindingRoleRef,
276289
Subjects: []rbacv1.Subject{subject},
277290
}
278291
}
@@ -398,20 +411,40 @@ func (r *ClusterPermissionReconciler) generateManifestWorkPayload(ctx context.Co
398411
return nil, nil, nil, nil, err
399412
}
400413

414+
roleBindingName := clusterPermission.Name
415+
if roleBinding.Name != "" {
416+
roleBindingName = roleBinding.Name
417+
}
418+
419+
roleBindingRoleRef := rbacv1.RoleRef{
420+
APIGroup: rbacv1.GroupName,
421+
Kind: roleBinding.RoleRef.Kind,
422+
Name: clusterPermission.Name,
423+
}
424+
if roleBinding.RoleRef.APIGroup != "" && roleBinding.RoleRef.Name != "" {
425+
roleBindingRoleRef = rbacv1.RoleRef{
426+
APIGroup: roleBinding.RoleRef.APIGroup,
427+
Kind: roleBinding.RoleRef.Kind,
428+
Name: roleBinding.RoleRef.Name,
429+
}
430+
} else if roleBinding.RoleRef.APIGroup == "" && roleBinding.RoleRef.Name != "" {
431+
return nil, nil, nil, nil,
432+
errors.New("the RoleBinding for Namespace " + roleBinding.Namespace + " missing APIGroup for the RoleRef")
433+
} else if roleBinding.RoleRef.APIGroup != "" && roleBinding.RoleRef.Name == "" {
434+
return nil, nil, nil, nil,
435+
errors.New("the RoleBinding for Namespace " + roleBinding.Namespace + " missing Name for the RoleRef")
436+
}
437+
401438
roleBindings = append(roleBindings, rbacv1.RoleBinding{
402439
TypeMeta: metav1.TypeMeta{
403440
APIVersion: rbacv1.SchemeGroupVersion.String(),
404441
Kind: "RoleBinding",
405442
},
406443
ObjectMeta: metav1.ObjectMeta{
407-
Name: clusterPermission.Name,
444+
Name: roleBindingName,
408445
Namespace: roleBinding.Namespace,
409446
},
410-
RoleRef: rbacv1.RoleRef{
411-
APIGroup: rbacv1.GroupName,
412-
Kind: roleBinding.RoleRef.Kind,
413-
Name: clusterPermission.Name,
414-
},
447+
RoleRef: roleBindingRoleRef,
415448
Subjects: []rbacv1.Subject{subject},
416449
})
417450
}

0 commit comments

Comments
 (0)