Skip to content

Commit 5e081b9

Browse files
committed
wip: working on generator
1 parent 4efce96 commit 5e081b9

File tree

3 files changed

+685
-623
lines changed

3 files changed

+685
-623
lines changed

internal/rules/engine.go

Lines changed: 76 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ type Namespace string
2121

2222
type ServiceAccountName string
2323

24+
type WsaName string
25+
2426
type Scope struct {
2527
Project string `json:"project"`
2628
Environment string `json:"environment"`
@@ -49,7 +51,8 @@ type Engine interface {
4951

5052
type InMemoryEngine struct {
5153
rules map[AgentName]map[Scope]ServiceAccountName
52-
createdRoles map[string]string
54+
createdRoles map[WsaName]*rbacv1.Role
55+
roleBindings map[WsaName][]*rbacv1.RoleBinding
5356
client client.Client
5457
}
5558

@@ -75,7 +78,8 @@ func (i *InMemoryEngine) GetServiceAccountForScope(scope Scope, agentName AgentN
7578

7679
func (i *InMemoryEngine) Reconcile2(ctx context.Context) error {
7780
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)
7983

8084
wsaList, err := getWorkloadServiceAccounts(ctx, i.client)
8185
if err != nil {
@@ -87,9 +91,8 @@ func (i *InMemoryEngine) Reconcile2(ctx context.Context) error {
8791
logger.Error(err, "failed to ensure roles for workload service accounts")
8892
}
8993

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)
9396
}
9497

9598
return nil
@@ -102,19 +105,7 @@ func (i *InMemoryEngine) ensureRoles(wsaList *[]v1beta1.WorkloadServiceAccount)
102105
if role, createErr := i.createRoleIfNeeded(ctx, wsa); createErr != nil {
103106
err = multierr.Append(err, createErr)
104107
} 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
118109
}
119110
}
120111
return err
@@ -127,46 +118,46 @@ func getContextWithTimeout(timeout time.Duration) context.Context {
127118
}
128119

129120
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+
//
170161
return nil
171162
}
172163

@@ -209,7 +200,9 @@ func createServiceAccount(ctx context.Context, c client.Client, namespace string
209200
}
210201

211202
// 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) {
213206
logger := log.FromContext(ctx).WithName("createRoleIfNeeded")
214207

215208
if len(wsa.Spec.Permissions.Permissions) == 0 {
@@ -254,16 +247,16 @@ func (i *InMemoryEngine) createRoleIfNeeded(ctx context.Context, wsa v1beta1.Wor
254247
return role, nil
255248
}
256249

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 {
259251
namespace := wsa.GetNamespace()
252+
roleBindings := make([]*rbacv1.RoleBinding, 0)
260253

261254
if len(wsa.Spec.Permissions.Roles) != 0 {
262255
roleRefs := wsa.Spec.Permissions.Roles
263256

264257
for _, roleRef := range roleRefs {
265258
roleBindingName := fmt.Sprintf("%s-%s-binding", wsa.Name, roleRef.Name)
266-
roleBinding := &rbacv1.RoleBinding{
259+
roleBindings = append(roleBindings, &rbacv1.RoleBinding{
267260
ObjectMeta: metav1.ObjectMeta{
268261
Name: roleBindingName,
269262
Namespace: namespace,
@@ -272,110 +265,45 @@ func (i *InMemoryEngine) generateRoleBindings(ctx context.Context, wsa v1beta1.W
272265
},
273266
},
274267
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+
})
307269
}
308270
}
309271

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
313274

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,
326280
Namespace: namespace,
281+
Labels: map[string]string{
282+
PermissionsKey: "enabled",
283+
},
327284
},
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+
})
342287
}
343288
}
344289

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{
350293
ObjectMeta: metav1.ObjectMeta{
351-
Name: bindingName,
294+
Name: roleBindingName,
352295
Namespace: namespace,
353296
Labels: map[string]string{
354297
PermissionsKey: "enabled",
355298
},
356299
},
357-
Subjects: []rbacv1.Subject{
358-
{
359-
Kind: "ServiceAccount",
360-
Name: string(serviceAccountName),
361-
Namespace: namespace,
362-
},
363-
},
364300
RoleRef: rbacv1.RoleRef{
365-
Kind: "Role",
366-
Name: generatedRoleName,
301+
Kind: role.Kind,
302+
Name: role.Name,
367303
APIGroup: "rbac.authorization.k8s.io",
368304
},
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+
})
378306
}
379307

380-
return nil
308+
return roleBindings
381309
}

0 commit comments

Comments
 (0)