@@ -3,6 +3,7 @@ package olm
3
3
import (
4
4
"context"
5
5
"fmt"
6
+ "github.com/google/uuid"
6
7
"hash/fnv"
7
8
"reflect"
8
9
"strings"
@@ -978,32 +979,18 @@ func (a *Operator) updateNamespaceList(op *operatorsv1.OperatorGroup) ([]string,
978
979
}
979
980
980
981
func (a * Operator ) ensureOpGroupClusterRole (op * operatorsv1.OperatorGroup , suffix string , apis cache.APISet ) error {
981
- clusterRole := & rbacv1.ClusterRole {
982
- 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" ,
995
- },
996
- })
997
- }
998
- if len (selectors ) > 0 {
999
- clusterRole .AggregationRule = & rbacv1.AggregationRule {
1000
- ClusterRoleSelectors : selectors ,
1001
- }
982
+ clusterRole , err := a .getOpGroupClusterRole (op , suffix , apis )
983
+ if err != nil {
984
+ return err
1002
985
}
1003
- err := ownerutil . AddOwnerLabels ( clusterRole , op )
986
+ aggregationRule , err := a . getClusterRoleAggregationRule ( apis , suffix )
1004
987
if err != nil {
1005
988
return err
1006
989
}
990
+ clusterRole .AggregationRule = aggregationRule
991
+ if err := ownerutil .AddOwnerLabels (clusterRole , op ); err != nil {
992
+ return err
993
+ }
1007
994
1008
995
existingRole , err := a .lister .RbacV1 ().ClusterRoleLister ().Get (clusterRole .Name )
1009
996
if err != nil && ! apierrors .IsNotFound (err ) {
@@ -1031,6 +1018,86 @@ func (a *Operator) ensureOpGroupClusterRole(op *operatorsv1.OperatorGroup, suffi
1031
1018
return nil
1032
1019
}
1033
1020
1021
+ func hash (str string ) (string , error ) {
1022
+ // hash the string with some randomness to help avoid guessing attacks
1023
+ h := fnv .New32a ()
1024
+ rnd := uuid .NewString ()
1025
+ if _ , err := h .Write ([]byte (fmt .Sprintf ("%s.%s" , rnd , str ))); err != nil {
1026
+ return "" , err
1027
+ }
1028
+ return strings .Trim (fmt .Sprintf ("%016x" , h .Sum32 ()), "0" ), nil
1029
+ }
1030
+
1031
+ func (a * Operator ) getOpGroupClusterRole (op * operatorsv1.OperatorGroup , suffix string , apis cache.APISet ) (* rbacv1.ClusterRole , error ) {
1032
+ // oldRoleName := strings.Join([]string{op.GetName(), suffix}, "-")
1033
+ roleNameHash , err := hash (fmt .Sprintf ("%s/%s" , op .GetNamespace (), op .GetName ()))
1034
+ if err != nil {
1035
+ return nil , err
1036
+ }
1037
+ roleName := fmt .Sprintf ("olm.operator-group.role.%s.%s" , roleNameHash , suffix )
1038
+
1039
+ clusterRole := & rbacv1.ClusterRole {
1040
+ ObjectMeta : metav1.ObjectMeta {
1041
+ Name : roleName ,
1042
+ },
1043
+ }
1044
+
1045
+ // check if old role name exists
1046
+ roles , err := a .lister .RbacV1 ().ClusterRoleLister ().List (ownerutil .ClusterRoleSelector (op ))
1047
+ if err != nil && ! apierrors .IsNotFound (err ) {
1048
+ return nil , err
1049
+ }
1050
+ var suffixRoles []* rbacv1.ClusterRole
1051
+ for idx , _ := range roles {
1052
+ role := roles [idx ]
1053
+ if strings .HasSuffix (role .GetName (), suffix ) {
1054
+ suffixRoles = append (suffixRoles , role )
1055
+ }
1056
+ }
1057
+ // todo: finding multiple owned cluster roles with the same suffix is highly unlikely to happen. However,
1058
+ // we need to test and document the manual clean up in case it ever happens
1059
+ if len (suffixRoles ) > 1 {
1060
+ err := fmt .Errorf ("found multiple cluster roles with suffix %s, please clean up manually" , suffix )
1061
+ a .logger .Error (err )
1062
+ return nil , err
1063
+ } else if len (suffixRoles ) == 1 {
1064
+ return suffixRoles [0 ], nil
1065
+ }
1066
+ return clusterRole , nil
1067
+ }
1068
+
1069
+ func (a * Operator ) getClusterRoleAggregationRule (apis cache.APISet , suffix string ) (* rbacv1.AggregationRule , error ) {
1070
+ var selectors []metav1.LabelSelector
1071
+ for api := range apis {
1072
+ aggregationLabel , err := aggregationLabelFromAPIKey (api , suffix )
1073
+ if err != nil {
1074
+ return nil , err
1075
+ }
1076
+ selectors = append (selectors , metav1.LabelSelector {
1077
+ MatchLabels : map [string ]string {
1078
+ aggregationLabel : "true" ,
1079
+ },
1080
+ })
1081
+ }
1082
+ if len (selectors ) > 0 {
1083
+ return & rbacv1.AggregationRule {
1084
+ ClusterRoleSelectors : selectors ,
1085
+ }, nil
1086
+ }
1087
+ return nil , nil
1088
+ }
1089
+
1090
+ func (a * Operator ) clusterRoleExistsAndIsOwnedBy (roleName string , owner ownerutil.Owner ) (bool , error ) {
1091
+ role , err := a .lister .RbacV1 ().ClusterRoleLister ().Get (roleName )
1092
+ if err != nil && ! apierrors .IsNotFound (err ) {
1093
+ return false , err
1094
+ }
1095
+ if apierrors .IsNotFound (err ) {
1096
+ return false , nil
1097
+ }
1098
+ return ownerutil .IsOwnedBy (role , owner ), nil
1099
+ }
1100
+
1034
1101
func (a * Operator ) ensureOpGroupClusterRoles (op * operatorsv1.OperatorGroup , apis cache.APISet ) error {
1035
1102
for _ , suffix := range Suffices {
1036
1103
if err := a .ensureOpGroupClusterRole (op , suffix , apis ); err != nil {
0 commit comments