Skip to content

Commit d45829f

Browse files
author
Per Goncalves da Silva
committed
refactor operator group cluster role name
Signed-off-by: Per Goncalves da Silva <[email protected]>
1 parent a7e3f3f commit d45829f

File tree

4 files changed

+80
-31
lines changed

4 files changed

+80
-31
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ require (
1414
github.com/go-logr/logr v1.2.4
1515
github.com/golang/mock v1.6.0
1616
github.com/google/go-cmp v0.5.9
17+
github.com/google/uuid v1.3.0
1718
github.com/googleapis/gnostic v0.5.5
1819
github.com/itchyny/gojq v0.11.0
1920
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2
@@ -124,7 +125,6 @@ require (
124125
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
125126
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect
126127
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
127-
github.com/google/uuid v1.3.0 // indirect
128128
github.com/gorilla/mux v1.8.0 // indirect
129129
github.com/gosuri/uitable v0.0.4 // indirect
130130
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect

pkg/controller/operators/olm/operatorgroup.go

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"hash/fnv"
7+
"k8s.io/apiserver/pkg/storage/names"
78
"reflect"
89
"strings"
910

@@ -978,38 +979,34 @@ func (a *Operator) updateNamespaceList(op *operatorsv1.OperatorGroup) ([]string,
978979
}
979980

980981
func (a *Operator) ensureOpGroupClusterRole(op *operatorsv1.OperatorGroup, suffix string, apis cache.APISet) error {
982+
// create target cluster role spec
981983
clusterRole := &rbacv1.ClusterRole{
982984
ObjectMeta: metav1.ObjectMeta{
983-
Name: strings.Join([]string{op.GetName(), suffix}, "-"),
984-
},
985-
}
986-
var selectors []metav1.LabelSelector
987-
for api := range apis {
988-
aggregationLabel, err := aggregationLabelFromAPIKey(api, suffix)
989-
if err != nil {
990-
return err
991-
}
992-
selectors = append(selectors, metav1.LabelSelector{
993-
MatchLabels: map[string]string{
994-
aggregationLabel: "true",
985+
Name: names.SimpleNameGenerator.GenerateName(fmt.Sprintf("olm.operatorgroup.%s-", suffix)),
986+
Labels: map[string]string{
987+
ownerutil.OlmOperatorGroupClusterRoleLevel: suffix,
995988
},
996-
})
997-
}
998-
if len(selectors) > 0 {
999-
clusterRole.AggregationRule = &rbacv1.AggregationRule{
1000-
ClusterRoleSelectors: selectors,
1001-
}
989+
},
1002990
}
1003-
err := ownerutil.AddOwnerLabels(clusterRole, op)
991+
992+
var err error
993+
clusterRole.AggregationRule, err = a.getClusterRoleAggregationRule(apis, suffix)
1004994
if err != nil {
1005995
return err
1006996
}
1007997

1008-
existingRole, err := a.lister.RbacV1().ClusterRoleLister().Get(clusterRole.Name)
1009-
if err != nil && !apierrors.IsNotFound(err) {
998+
if err := ownerutil.AddOwnerLabels(clusterRole, op); err != nil {
1010999
return err
10111000
}
1012-
if apierrors.IsNotFound(err) {
1001+
1002+
// get existing cluster role for this level (suffix: admin, edit, view))
1003+
existingClusterRoleList, err := a.lister.RbacV1().ClusterRoleLister().List(labels.SelectorFromSet(ownerutil.ClusterRoleByOwnerAndLevel(op, suffix)))
1004+
if err != nil {
1005+
return err
1006+
}
1007+
1008+
var existingRole *rbacv1.ClusterRole
1009+
if len(existingClusterRoleList) == 0 {
10131010
existingRole, err = a.opClient.KubernetesInterface().RbacV1().ClusterRoles().Create(context.TODO(), clusterRole, metav1.CreateOptions{})
10141011
if err == nil {
10151012
return nil
@@ -1018,6 +1015,10 @@ func (a *Operator) ensureOpGroupClusterRole(op *operatorsv1.OperatorGroup, suffi
10181015
a.logger.WithError(err).Errorf("Create cluster role failed: %v", clusterRole)
10191016
return err
10201017
}
1018+
} else if len(existingClusterRoleList) == 1 {
1019+
existingRole = existingClusterRoleList[0].DeepCopy()
1020+
} else {
1021+
return fmt.Errorf("found multiple cluster roles at level '%s' for operator group: '%s'", suffix, op.Name)
10211022
}
10221023

10231024
if existingRole != nil && labels.Equals(existingRole.Labels, clusterRole.Labels) && reflect.DeepEqual(existingRole.AggregationRule, clusterRole.AggregationRule) {
@@ -1031,6 +1032,38 @@ func (a *Operator) ensureOpGroupClusterRole(op *operatorsv1.OperatorGroup, suffi
10311032
return nil
10321033
}
10331034

1035+
func (a *Operator) getClusterRoleAggregationRule(apis cache.APISet, suffix string) (*rbacv1.AggregationRule, error) {
1036+
var selectors []metav1.LabelSelector
1037+
for api := range apis {
1038+
aggregationLabel, err := aggregationLabelFromAPIKey(api, suffix)
1039+
if err != nil {
1040+
return nil, err
1041+
}
1042+
selectors = append(selectors, metav1.LabelSelector{
1043+
MatchLabels: map[string]string{
1044+
aggregationLabel: "true",
1045+
},
1046+
})
1047+
}
1048+
if len(selectors) > 0 {
1049+
return &rbacv1.AggregationRule{
1050+
ClusterRoleSelectors: selectors,
1051+
}, nil
1052+
}
1053+
return nil, nil
1054+
}
1055+
1056+
func (a *Operator) clusterRoleExistsAndIsOwnedBy(roleName string, owner ownerutil.Owner) (bool, error) {
1057+
role, err := a.lister.RbacV1().ClusterRoleLister().Get(roleName)
1058+
if err != nil && !apierrors.IsNotFound(err) {
1059+
return false, err
1060+
}
1061+
if apierrors.IsNotFound(err) {
1062+
return false, nil
1063+
}
1064+
return ownerutil.IsOwnedBy(role, owner), nil
1065+
}
1066+
10341067
func (a *Operator) ensureOpGroupClusterRoles(op *operatorsv1.OperatorGroup, apis cache.APISet) error {
10351068
for _, suffix := range Suffices {
10361069
if err := a.ensureOpGroupClusterRole(op, suffix, apis); err != nil {

pkg/lib/ownerutil/util.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ import (
2020
)
2121

2222
const (
23-
OwnerKey = "olm.owner"
24-
OwnerNamespaceKey = "olm.owner.namespace"
25-
OwnerKind = "olm.owner.kind"
26-
OwnerPackageServer = "packageserver"
23+
OwnerKey = "olm.owner"
24+
OwnerNamespaceKey = "olm.owner.namespace"
25+
OwnerKind = "olm.owner.kind"
26+
OlmOperatorGroupClusterRoleLevel = "olm.operatorgroup.rolelevel"
27+
ClusterRoleLevelAdmin = "admin"
28+
ClusterRoleLevelEdit = "edit"
29+
ClusterRoleLevelView = "view"
30+
OwnerPackageServer = "packageserver"
2731
)
2832

2933
var (
@@ -208,12 +212,18 @@ func NonBlockingOwner(owner Owner) metav1.OwnerReference {
208212
// OwnerLabel returns a label added to generated objects for later querying
209213
func OwnerLabel(owner Owner, kind string) map[string]string {
210214
return map[string]string{
211-
OwnerKey: owner.GetName(),
215+
OwnerKey: string(owner.GetUID()),
212216
OwnerNamespaceKey: owner.GetNamespace(),
213217
OwnerKind: kind,
214218
}
215219
}
216220

221+
func ClusterRoleByOwnerAndLevel(owner Owner, level string) map[string]string {
222+
labels := OwnerLabel(owner, "OperatorGroup")
223+
labels[OlmOperatorGroupClusterRoleLevel] = level
224+
return labels
225+
}
226+
217227
// AddOwnerLabels adds ownerref-like labels to an object by inferring the owner kind
218228
func AddOwnerLabels(object metav1.Object, owner Owner) error {
219229
err := InferGroupVersionKind(owner)
@@ -272,6 +282,11 @@ func CSVOwnerSelector(owner *operatorsv1alpha1.ClusterServiceVersion) labels.Sel
272282
return labels.SelectorFromSet(OwnerLabel(owner, operatorsv1alpha1.ClusterServiceVersionKind))
273283
}
274284

285+
// ClusterRoleSelector returns a label selector to find cluster role objects owned by owner
286+
func ClusterRoleSelector(owner *operatorsv1.OperatorGroup) labels.Selector {
287+
return labels.SelectorFromSet(OwnerLabel(owner, operatorsv1.OperatorGroupKind))
288+
}
289+
275290
// AddOwner adds an owner to the ownerref list.
276291
func AddOwner(object metav1.Object, owner Owner, blockOwnerDeletion, isController bool) {
277292
// Most of the time we won't have TypeMeta on the object, so we infer it for types we know about

test/e2e/operator_groups_e2e_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,21 +340,22 @@ var _ = Describe("Operator Group", func() {
340340
})
341341

342342
// validate provided API clusterroles for the operatorgroup
343-
adminRole, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get(context.TODO(), operatorGroup.Name+"-admin", metav1.GetOptions{})
343+
roleNamePrefix := fmt.Sprintf("olm.%s.operator-group.%s.role.", opGroupNamespace, operatorGroup.Name)
344+
adminRole, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get(context.TODO(), roleNamePrefix+"admin", metav1.GetOptions{})
344345
require.NoError(GinkgoT(), err)
345346
adminPolicyRules := []rbacv1.PolicyRule{
346347
{Verbs: []string{"*"}, APIGroups: []string{mainCRD.Spec.Group}, Resources: []string{mainCRDPlural}},
347348
}
348349
require.Equal(GinkgoT(), adminPolicyRules, adminRole.Rules)
349350

350-
editRole, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get(context.TODO(), operatorGroup.Name+"-edit", metav1.GetOptions{})
351+
editRole, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get(context.TODO(), roleNamePrefix+"edit", metav1.GetOptions{})
351352
require.NoError(GinkgoT(), err)
352353
editPolicyRules := []rbacv1.PolicyRule{
353354
{Verbs: []string{"create", "update", "patch", "delete"}, APIGroups: []string{mainCRD.Spec.Group}, Resources: []string{mainCRDPlural}},
354355
}
355356
require.Equal(GinkgoT(), editPolicyRules, editRole.Rules)
356357

357-
viewRole, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get(context.TODO(), operatorGroup.Name+"-view", metav1.GetOptions{})
358+
viewRole, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get(context.TODO(), roleNamePrefix+"view", metav1.GetOptions{})
358359
require.NoError(GinkgoT(), err)
359360
viewPolicyRules := []rbacv1.PolicyRule{
360361
{Verbs: []string{"get"}, APIGroups: []string{"apiextensions.k8s.io"}, Resources: []string{"customresourcedefinitions"}, ResourceNames: []string{mainCRD.Name}},

0 commit comments

Comments
 (0)