@@ -88,6 +88,26 @@ func (t *componentRBACTransformer) Transform(ctx graph.TransformContext, dag *gr
8888 return nil
8989 }
9090
91+ // user managed sa
92+ if serviceAccountName != "" {
93+ return t .handleRBACNewRule (transCtx , dag , serviceAccountName )
94+ }
95+
96+ // check if sa with old naming rule exists
97+ newName := constant .GenerateDefaultServiceAccountNameNew (synthesizedComp .FullCompName )
98+ newNameExists := true
99+ if err := transCtx .Client .Get (transCtx .Context , types.NamespacedName {Namespace : synthesizedComp .Namespace , Name : newName }, sa ); err != nil {
100+ if ! errors .IsNotFound (err ) {
101+ return err
102+ }
103+ newNameExists = false
104+ }
105+
106+ if newNameExists || transCtx .RunningWorkload == nil {
107+ return t .handleRBACNewRule (transCtx , dag , "" )
108+ }
109+
110+ // old code path
91111 var err error
92112 comp := transCtx .Component
93113 lastServiceAccountName := comp .Annotations [constant .ComponentLastServiceAccountNameAnnotationKey ]
@@ -153,6 +173,93 @@ func (t *componentRBACTransformer) Transform(ctx graph.TransformContext, dag *gr
153173 return nil
154174}
155175
176+ func (t * componentRBACTransformer ) handleRBACNewRule (transCtx * componentTransformContext , dag * graph.DAG , userDefinedSAName string ) error {
177+ synthesizedComp := transCtx .SynthesizeComponent
178+ graphCli , _ := transCtx .Client .(model.GraphClient )
179+ saName := userDefinedSAName
180+ var sa * corev1.ServiceAccount
181+ var err error
182+ if userDefinedSAName == "" {
183+ saName = constant .GenerateDefaultServiceAccountNameNew (synthesizedComp .FullCompName )
184+ // if no rolebinding is needed, sa will be created anyway, because other modules may reference it.
185+ sa , err = createOrUpdateServiceAccount (transCtx , saName , graphCli , dag )
186+ if err != nil {
187+ return err
188+ }
189+ }
190+ synthesizedComp .PodSpec .ServiceAccountName = saName
191+ rbs , err := createOrUpdateRoleBindingNew (transCtx , transCtx .CompDef , saName , graphCli , dag )
192+ if err != nil {
193+ return err
194+ }
195+ objs := []client.Object {sa }
196+ if sa != nil {
197+ // serviceAccount should be created before roleBinding and role
198+ for _ , rb := range rbs {
199+ objs = append (objs , rb )
200+ graphCli .DependOn (dag , rb , sa )
201+ }
202+ // serviceAccount should be created before workload
203+ itsList := graphCli .FindAll (dag , & workloads.InstanceSet {})
204+ for _ , its := range itsList {
205+ graphCli .DependOn (dag , its , sa )
206+ }
207+ }
208+
209+ t .rbacInstanceAssistantObjects (graphCli , dag , objs )
210+ return nil
211+ }
212+
213+ func createOrUpdateRoleBindingNew (transCtx * componentTransformContext ,
214+ cmpd * appsv1.ComponentDefinition , serviceAccountName string , graphCli model.GraphClient , dag * graph.DAG ) ([]* rbacv1.RoleBinding , error ) {
215+ cmpRoleBinding := func (old , new * rbacv1.RoleBinding ) bool {
216+ return labelAndAnnotationEqual (old , new ) &&
217+ equality .Semantic .DeepEqual (old .Subjects , new .Subjects ) &&
218+ equality .Semantic .DeepEqual (old .RoleRef , new .RoleRef )
219+ }
220+ res := make ([]* rbacv1.RoleBinding , 0 )
221+
222+ if len (cmpd .Spec .PolicyRules ) != 0 {
223+ // cluster role is handled by cmpd controller
224+ cmpdRoleBinding := factory .BuildRoleBinding (transCtx .SynthesizeComponent , serviceAccountName , & rbacv1.RoleRef {
225+ APIGroup : rbacv1 .GroupName ,
226+ Kind : "ClusterRole" ,
227+ Name : constant .GenerateDefaultRoleName (cmpd .Name ),
228+ }, serviceAccountName )
229+ if err := intctrlutil .SetOwnership (transCtx .Component , cmpdRoleBinding , model .GetScheme (), "" ); err != nil {
230+ return nil , err
231+ }
232+ rb , err := createOrUpdate (transCtx , cmpdRoleBinding , graphCli , dag , cmpRoleBinding )
233+ if err != nil {
234+ return nil , err
235+ }
236+ res = append (res , rb )
237+ }
238+
239+ if isLifecycleActionsEnabled (transCtx .CompDef ) {
240+ clusterPodRoleBinding := factory .BuildRoleBinding (
241+ transCtx .SynthesizeComponent ,
242+ fmt .Sprintf ("%v-pod" , serviceAccountName ),
243+ & rbacv1.RoleRef {
244+ APIGroup : rbacv1 .GroupName ,
245+ Kind : "ClusterRole" ,
246+ Name : constant .RBACRoleName ,
247+ },
248+ serviceAccountName ,
249+ )
250+ if err := intctrlutil .SetOwnership (transCtx .Component , clusterPodRoleBinding , model .GetScheme (), "" ); err != nil {
251+ return nil , err
252+ }
253+ rb , err := createOrUpdate (transCtx , clusterPodRoleBinding , graphCli , dag , cmpRoleBinding )
254+ if err != nil {
255+ return nil , err
256+ }
257+ res = append (res , rb )
258+ }
259+
260+ return res , nil
261+ }
262+
156263func (t * componentRBACTransformer ) rbacInstanceAssistantObjects (graphCli model.GraphClient , dag * graph.DAG , objs []client.Object ) {
157264 itsList := graphCli .FindAll (dag , & workloads.InstanceSet {})
158265 for _ , itsObj := range itsList {
0 commit comments