mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-08-25 16:07:24 +00:00
feat(controllers/tenant): ensure per-tenant owners roles
add gitops ready cluster roles per tenant owners. Signed-off-by: Massimiliano Giovagnoli <me@maxgio.it>
This commit is contained in:
@@ -105,6 +105,14 @@ func (r Manager) Reconcile(ctx context.Context, request ctrl.Request) (result ct
|
||||
|
||||
return
|
||||
}
|
||||
// Ensuring Roles resources
|
||||
r.Log.Info("Ensuring Roles for Owners and Tenant")
|
||||
|
||||
if err = r.syncRoles(ctx, instance); err != nil {
|
||||
r.Log.Error(err, "Cannot sync Roles items")
|
||||
|
||||
return
|
||||
}
|
||||
// Ensuring RoleBinding resources
|
||||
r.Log.Info("Ensuring RoleBindings for Owners and Tenant")
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package tenant
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
)
|
||||
|
||||
const (
|
||||
ImpersonatorRoleName = "capsule-tenant-impersonator"
|
||||
)
|
||||
|
||||
// Sync the Tenant Owner specific cluster-roles.
|
||||
// When the Tenant is configured GitOpsReady additional (Cluster)Roles are created, then bound.
|
||||
func (r *Manager) syncRoles(ctx context.Context, tenant *capsulev1beta1.Tenant) (err error) {
|
||||
|
||||
// If the Tenant will be reconciled the GitOps-way,
|
||||
// Tenant Owners might be machine GitOps reconciler identities.
|
||||
if tenant.Spec.GitOpsReady {
|
||||
for _, owner := range tenant.Spec.Owners {
|
||||
if err = r.ensureOwnerRole(ctx, tenant, &owner, ImpersonatorRoleName); err != nil {
|
||||
r.Log.Error(err, "Reconciliation for ClusterRole failed", "ClusterRole", ImpersonatorRoleName)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (r *Manager) ensureOwnerRole(ctx context.Context, tenant *capsulev1beta1.Tenant, owner *capsulev1beta1.OwnerSpec, roleName string) (err error) {
|
||||
switch roleName {
|
||||
case ImpersonatorRoleName:
|
||||
clusterRole := &rbacv1.ClusterRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: roleName + "-" + tenant.Name + "-" + owner.Name,
|
||||
},
|
||||
}
|
||||
|
||||
resource := "users"
|
||||
if owner.Kind == capsulev1beta1.GroupOwner {
|
||||
resource = "groups"
|
||||
}
|
||||
|
||||
resourceName := owner.Name
|
||||
if owner.Kind == capsulev1beta1.ServiceAccountOwner {
|
||||
resourceName = "system:serviceaccount:" + tenant.Namespace + ":" + owner.Name
|
||||
}
|
||||
|
||||
_, err = controllerutil.CreateOrUpdate(ctx, r.Client, clusterRole, func() error {
|
||||
clusterRole.Rules = []rbacv1.PolicyRule{
|
||||
{
|
||||
APIGroups: []string{""},
|
||||
Resources: []string{resource},
|
||||
Verbs: []string{"impersonate"},
|
||||
ResourceNames: []string{resourceName},
|
||||
},
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user