@@ -21,6 +21,8 @@ type Namespace string
21
21
22
22
type ServiceAccountName string
23
23
24
+ type WsaName string
25
+
24
26
type Scope struct {
25
27
Project string `json:"project"`
26
28
Environment string `json:"environment"`
@@ -49,7 +51,8 @@ type Engine interface {
49
51
50
52
type InMemoryEngine struct {
51
53
rules map [AgentName ]map [Scope ]ServiceAccountName
52
- createdRoles map [string ]string
54
+ createdRoles map [WsaName ]* rbacv1.Role
55
+ roleBindings map [WsaName ][]* rbacv1.RoleBinding
53
56
client client.Client
54
57
}
55
58
@@ -75,7 +78,8 @@ func (i *InMemoryEngine) GetServiceAccountForScope(scope Scope, agentName AgentN
75
78
76
79
func (i * InMemoryEngine ) Reconcile2 (ctx context.Context ) error {
77
80
logger := log .FromContext (ctx ).WithName ("engine" )
78
- i .createdRoles = make (map [string ]string )
81
+ i .createdRoles = make (map [WsaName ]* rbacv1.Role )
82
+ i .roleBindings = make (map [WsaName ][]* rbacv1.RoleBinding )
79
83
80
84
wsaList , err := getWorkloadServiceAccounts (ctx , i .client )
81
85
if err != nil {
@@ -87,9 +91,8 @@ func (i *InMemoryEngine) Reconcile2(ctx context.Context) error {
87
91
logger .Error (err , "failed to ensure roles for workload service accounts" )
88
92
}
89
93
90
- err = i .generateRoleBindings (& wsaList )
91
- if err != nil {
92
- logger .Error (err , "failed to ensure role bindings for workload service accounts" )
94
+ for _ , wsa := range wsaList {
95
+ i .roleBindings [WsaName (wsa .Name )] = i .generateRoleBindings (& wsa )
93
96
}
94
97
95
98
return nil
@@ -102,19 +105,7 @@ func (i *InMemoryEngine) ensureRoles(wsaList *[]v1beta1.WorkloadServiceAccount)
102
105
if role , createErr := i .createRoleIfNeeded (ctx , wsa ); createErr != nil {
103
106
err = multierr .Append (err , createErr )
104
107
} else if role != nil {
105
- i .createdRoles [wsa .Name ] = role .Name
106
- }
107
- }
108
- return err
109
- }
110
-
111
- func (i * InMemoryEngine ) generateRoleBindings (wsaList * []v1beta1.WorkloadServiceAccount ) error {
112
- var err error
113
- for _ , wsa := range * wsaList {
114
- if role , createErr := i .createRoleIfNeeded (ctx , wsa ); createErr != nil {
115
- err = multierr .Append (err , createErr )
116
- } else if role != nil {
117
- i .createdRoles [wsa .Name ] = role .Name
108
+ i .createdRoles [WsaName (wsa .Name )] = role
118
109
}
119
110
}
120
111
return err
@@ -127,46 +118,46 @@ func getContextWithTimeout(timeout time.Duration) context.Context {
127
118
}
128
119
129
120
func (i * InMemoryEngine ) Reconcile (ctx context.Context , namespace string ) error {
130
- logger := log .FromContext (ctx ).WithName ("engine" )
131
-
132
- wsas , err := getWorkloadServiceAccounts (ctx , i .client )
133
- if err != nil {
134
- return err
135
- }
136
-
137
- scopePermissionsMap := generateAllScopesWithPermissions (wsas )
138
- logger .Info ("Generated scope permissions mapping from workload service accounts" )
139
-
140
- for scope , permissions := range scopePermissionsMap {
141
- if err := createServiceAccount (ctx , i .client , namespace , scope ); err != nil {
142
- logger .Error (err , "failed to create ServiceAccount for scope" , "scope" , scope .String ())
143
- continue
144
- }
145
-
146
- generatedRoleName , err := createRoleIfNeeded (ctx , i .client , namespace , permissions .Permissions )
147
- if err != nil {
148
- logger .Error (err , "failed to create Role for scope" , "scope" , scope .String ())
149
- continue
150
- }
151
-
152
- serviceAccountName := generateServiceAccountName (scope )
153
- if err := createRoleBindings (ctx , i .client , namespace , serviceAccountName , permissions , generatedRoleName ); err != nil {
154
- logger .Error (err , "failed to create RoleBindings for scope" , "scope" , scope .String ())
155
- continue
156
- }
157
-
158
- logger .Info ("Successfully created Kubernetes resources for scope" , "scope" , scope .String (), "serviceAccount" , serviceAccountName )
159
- }
160
-
161
- // TODO: Support scoping WSAs to specific agents
162
- const defaultAgent = AgentName ("default" )
163
- i .rules [defaultAgent ] = make (map [Scope ]ServiceAccountName )
164
-
165
- for scope := range scopePermissionsMap {
166
- serviceAccountName := generateServiceAccountName (scope )
167
- i.rules [defaultAgent ][scope ] = serviceAccountName
168
- }
169
-
121
+ // logger := log.FromContext(ctx).WithName("engine")
122
+ //
123
+ // wsas, err := getWorkloadServiceAccounts(ctx, i.client)
124
+ // if err != nil {
125
+ // return err
126
+ // }
127
+ //
128
+ // scopePermissionsMap := generateAllScopesWithPermissions(wsas)
129
+ // logger.Info("Generated scope permissions mapping from workload service accounts")
130
+ //
131
+ // for scope, permissions := range scopePermissionsMap {
132
+ // if err := createServiceAccount(ctx, i.client, namespace, scope); err != nil {
133
+ // logger.Error(err, "failed to create ServiceAccount for scope", "scope", scope.String())
134
+ // continue
135
+ // }
136
+ //
137
+ // generatedRoleName, err := createRoleIfNeeded(ctx, i.client, namespace, permissions.Permissions)
138
+ // if err != nil {
139
+ // logger.Error(err, "failed to create Role for scope", "scope", scope.String())
140
+ // continue
141
+ // }
142
+ //
143
+ // serviceAccountName := generateServiceAccountName(scope)
144
+ // if err := createRoleBindings(ctx, i.client, namespace, serviceAccountName, permissions, generatedRoleName); err != nil {
145
+ // logger.Error(err, "failed to create RoleBindings for scope", "scope", scope.String())
146
+ // continue
147
+ // }
148
+ //
149
+ // logger.Info("Successfully created Kubernetes resources for scope", "scope", scope.String(), "serviceAccount", serviceAccountName)
150
+ // }
151
+
152
+ //// TODO: Support scoping WSAs to specific agents
153
+ // const defaultAgent = AgentName("default")
154
+ // i.rules[defaultAgent] = make(map[Scope]ServiceAccountName)
155
+ //
156
+ // for scope := range scopePermissionsMap {
157
+ // serviceAccountName := generateServiceAccountName(scope)
158
+ // i.rules[defaultAgent][scope] = serviceAccountName
159
+ // }
160
+ //
170
161
return nil
171
162
}
172
163
@@ -209,7 +200,9 @@ func createServiceAccount(ctx context.Context, c client.Client, namespace string
209
200
}
210
201
211
202
// createRoleIfNeeded creates a Role for inline permissions if they exist
212
- func (i * InMemoryEngine ) createRoleIfNeeded (ctx context.Context , wsa v1beta1.WorkloadServiceAccount ) (* rbacv1.Role , error ) {
203
+ func (i * InMemoryEngine ) createRoleIfNeeded (
204
+ ctx context.Context , wsa v1beta1.WorkloadServiceAccount ,
205
+ ) (* rbacv1.Role , error ) {
213
206
logger := log .FromContext (ctx ).WithName ("createRoleIfNeeded" )
214
207
215
208
if len (wsa .Spec .Permissions .Permissions ) == 0 {
@@ -254,16 +247,16 @@ func (i *InMemoryEngine) createRoleIfNeeded(ctx context.Context, wsa v1beta1.Wor
254
247
return role , nil
255
248
}
256
249
257
- func (i * InMemoryEngine ) generateRoleBindings (ctx context.Context , wsa v1beta1.WorkloadServiceAccount ) []* rbacv1.RoleBinding {
258
- logger := log .FromContext (ctx ).WithName ("generateRoleBindings" )
250
+ func (i * InMemoryEngine ) generateRoleBindings (wsa * v1beta1.WorkloadServiceAccount ) []* rbacv1.RoleBinding {
259
251
namespace := wsa .GetNamespace ()
252
+ roleBindings := make ([]* rbacv1.RoleBinding , 0 )
260
253
261
254
if len (wsa .Spec .Permissions .Roles ) != 0 {
262
255
roleRefs := wsa .Spec .Permissions .Roles
263
256
264
257
for _ , roleRef := range roleRefs {
265
258
roleBindingName := fmt .Sprintf ("%s-%s-binding" , wsa .Name , roleRef .Name )
266
- roleBinding := & rbacv1.RoleBinding {
259
+ roleBindings = append ( roleBindings , & rbacv1.RoleBinding {
267
260
ObjectMeta : metav1.ObjectMeta {
268
261
Name : roleBindingName ,
269
262
Namespace : namespace ,
@@ -272,110 +265,45 @@ func (i *InMemoryEngine) generateRoleBindings(ctx context.Context, wsa v1beta1.W
272
265
},
273
266
},
274
267
RoleRef : roleRef ,
275
- }
276
- }
277
- }
278
-
279
- // Bind to existing Roles
280
- for _ , roleRef := range permissions .Roles {
281
- bindingName := fmt .Sprintf ("%s-%s-binding" , serviceAccountName , roleRef .Name )
282
-
283
- roleBinding := & rbacv1.RoleBinding {
284
- ObjectMeta : metav1.ObjectMeta {
285
- Name : bindingName ,
286
- Namespace : namespace ,
287
- Labels : map [string ]string {
288
- PermissionsKey : "enabled" ,
289
- },
290
- },
291
- Subjects : []rbacv1.Subject {
292
- {
293
- Kind : "ServiceAccount" ,
294
- Name : string (serviceAccountName ),
295
- Namespace : namespace ,
296
- },
297
- },
298
- RoleRef : roleRef ,
299
- }
300
-
301
- err := c .Create (ctx , roleBinding )
302
- if err != nil && ! errors .IsAlreadyExists (err ) {
303
- return fmt .Errorf ("failed to create RoleBinding %s: %w" , bindingName , err )
304
- }
305
- if err == nil {
306
- logger .Info ("Created RoleBinding" , "name" , bindingName , "role" , roleRef .Name )
268
+ })
307
269
}
308
270
}
309
271
310
- // Bind to existing ClusterRoles
311
- for _ , clusterRoleRef := range permissions .ClusterRoles {
312
- bindingName := fmt .Sprintf ("%s-%s-binding" , serviceAccountName , clusterRoleRef .Name )
272
+ if len (wsa .Spec .Permissions .ClusterRoles ) != 0 {
273
+ roleRefs := wsa .Spec .Permissions .ClusterRoles
313
274
314
- roleBinding := & rbacv1.RoleBinding {
315
- ObjectMeta : metav1.ObjectMeta {
316
- Name : bindingName ,
317
- Namespace : namespace ,
318
- Labels : map [string ]string {
319
- PermissionsKey : "enabled" ,
320
- },
321
- },
322
- Subjects : []rbacv1.Subject {
323
- {
324
- Kind : "ServiceAccount" ,
325
- Name : string (serviceAccountName ),
275
+ for _ , roleRef := range roleRefs {
276
+ roleBindingName := fmt .Sprintf ("%s-%s-binding" , wsa .Name , roleRef .Name )
277
+ roleBindings = append (roleBindings , & rbacv1.RoleBinding {
278
+ ObjectMeta : metav1.ObjectMeta {
279
+ Name : roleBindingName ,
326
280
Namespace : namespace ,
281
+ Labels : map [string ]string {
282
+ PermissionsKey : "enabled" ,
283
+ },
327
284
},
328
- },
329
- RoleRef : rbacv1.RoleRef {
330
- Kind : "ClusterRole" ,
331
- Name : clusterRoleRef .Name ,
332
- APIGroup : "rbac.authorization.k8s.io" ,
333
- },
334
- }
335
-
336
- err := c .Create (ctx , roleBinding )
337
- if err != nil && ! errors .IsAlreadyExists (err ) {
338
- return fmt .Errorf ("failed to create RoleBinding for ClusterRole %s: %w" , bindingName , err )
339
- }
340
- if err == nil {
341
- logger .Info ("Created RoleBinding for ClusterRole" , "name" , bindingName , "clusterRole" , clusterRoleRef .Name )
285
+ RoleRef : roleRef ,
286
+ })
342
287
}
343
288
}
344
289
345
- // Bind to generated Role if it exists
346
- if generatedRoleName != "" {
347
- bindingName := fmt .Sprintf ("%s-%s-binding" , serviceAccountName , generatedRoleName )
348
-
349
- roleBinding := & rbacv1.RoleBinding {
290
+ if role , ok := i .createdRoles [WsaName (wsa .Name )]; ok {
291
+ roleBindingName := fmt .Sprintf ("%s-%s-binding" , wsa .Name , role .Name )
292
+ roleBindings = append (roleBindings , & rbacv1.RoleBinding {
350
293
ObjectMeta : metav1.ObjectMeta {
351
- Name : bindingName ,
294
+ Name : roleBindingName ,
352
295
Namespace : namespace ,
353
296
Labels : map [string ]string {
354
297
PermissionsKey : "enabled" ,
355
298
},
356
299
},
357
- Subjects : []rbacv1.Subject {
358
- {
359
- Kind : "ServiceAccount" ,
360
- Name : string (serviceAccountName ),
361
- Namespace : namespace ,
362
- },
363
- },
364
300
RoleRef : rbacv1.RoleRef {
365
- Kind : "Role" ,
366
- Name : generatedRoleName ,
301
+ Kind : role . Kind ,
302
+ Name : role . Name ,
367
303
APIGroup : "rbac.authorization.k8s.io" ,
368
304
},
369
- }
370
-
371
- err := c .Create (ctx , roleBinding )
372
- if err != nil && ! errors .IsAlreadyExists (err ) {
373
- return fmt .Errorf ("failed to create RoleBinding for generated Role %s: %w" , bindingName , err )
374
- }
375
- if err == nil {
376
- logger .Info ("Created RoleBinding for generated Role" , "name" , bindingName , "role" , generatedRoleName )
377
- }
305
+ })
378
306
}
379
307
380
- return nil
308
+ return roleBindings
381
309
}
0 commit comments