restructure and process additions and deleteions of relationships, roles and memberships
This commit is contained in:
@@ -10,75 +10,67 @@ import (
|
||||
"go.equinixmetal.net/infra9-metal-bridge/internal/permissions"
|
||||
)
|
||||
|
||||
func (s *service) syncMemberships(ctx context.Context, memberships []ResourceMemberships) error {
|
||||
if len(memberships) == 0 {
|
||||
return nil
|
||||
func (s *service) syncMemberships(ctx context.Context, relationships Relationships, skipDeletions bool) (int, int) {
|
||||
if len(relationships.Memberships) == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
resourceMap := make(map[gidx.PrefixedID][]ResourceMemberships)
|
||||
rlogger := s.logger.With("resource.id", relationships.Resource.PrefixedID())
|
||||
|
||||
resourceRoleIDs := make(map[gidx.PrefixedID]map[string]gidx.PrefixedID)
|
||||
|
||||
resourceRoleCreations := make(map[gidx.PrefixedID]map[string][]string)
|
||||
resourceRoleDeletions := make(map[gidx.PrefixedID][]gidx.PrefixedID)
|
||||
|
||||
resourceRoleAssignments := make(map[gidx.PrefixedID]map[string][]gidx.PrefixedID)
|
||||
resourceRoleAssignmentRemovals := make(map[gidx.PrefixedID]map[string][]gidx.PrefixedID)
|
||||
roleIDs := make(map[string]gidx.PrefixedID)
|
||||
|
||||
var (
|
||||
totalRoleCreate, totalRoleDelete int
|
||||
totalRoleAssign, totalRoleUnassign int
|
||||
)
|
||||
|
||||
for _, membership := range memberships {
|
||||
resourceID := membership.Resource.PrefixedID()
|
||||
wantRoles, wantAssignments := s.mapResourceWants(relationships.Memberships)
|
||||
|
||||
resourceMap[resourceID] = append(resourceMap[resourceID], membership)
|
||||
liveRoles, liveAssignments, err := s.mapResourceDetails(ctx, relationships.Resource.PrefixedID())
|
||||
if err != nil {
|
||||
rlogger.Errorw("failed to get membership resource details map",
|
||||
"error", err,
|
||||
)
|
||||
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
for resourceID, memberships := range resourceMap {
|
||||
resourceRoleIDs[resourceID] = make(map[string]gidx.PrefixedID)
|
||||
roleCreations := make(map[string][]string)
|
||||
roleDeletions := make([]gidx.PrefixedID, 0)
|
||||
|
||||
wantRoles, wantAssignments := s.mapResourceWants(memberships)
|
||||
|
||||
liveRoles, liveAssignments, err := s.mapResourceDetails(ctx, resourceID)
|
||||
if err != nil {
|
||||
return err
|
||||
for roleKey, actions := range wantRoles {
|
||||
if _, ok := liveRoles[roleKey]; !ok {
|
||||
roleCreations[roleKey] = actions
|
||||
}
|
||||
}
|
||||
|
||||
roleCreations := make(map[string][]string)
|
||||
roleDeletions := make([]gidx.PrefixedID, 0)
|
||||
|
||||
for roleKey, actions := range wantRoles {
|
||||
if _, ok := liveRoles[roleKey]; !ok {
|
||||
roleCreations[roleKey] = actions
|
||||
}
|
||||
}
|
||||
|
||||
for roleKey, role := range liveRoles {
|
||||
for roleKey, role := range liveRoles {
|
||||
if !skipDeletions {
|
||||
if _, ok := wantRoles[roleKey]; !ok {
|
||||
roleDeletions = append(roleDeletions, role.ID)
|
||||
}
|
||||
|
||||
resourceRoleIDs[resourceID][roleKey] = role.ID
|
||||
}
|
||||
|
||||
roleAssignments := make(map[string][]gidx.PrefixedID)
|
||||
roleAssignmentRemovals := make(map[string][]gidx.PrefixedID)
|
||||
roleIDs[roleKey] = role.ID
|
||||
}
|
||||
|
||||
for roleKey, assignments := range wantAssignments {
|
||||
for memberID := range assignments {
|
||||
if _, ok := liveAssignments[roleKey]; ok {
|
||||
if _, ok := liveAssignments[roleKey][memberID]; ok {
|
||||
continue
|
||||
}
|
||||
roleMembershipsAdd := make(map[string][]gidx.PrefixedID)
|
||||
roleMembershipsRemove := make(map[string][]gidx.PrefixedID)
|
||||
|
||||
for roleKey, assignments := range wantAssignments {
|
||||
for memberID := range assignments {
|
||||
if _, ok := liveAssignments[roleKey]; ok {
|
||||
if _, ok := liveAssignments[roleKey][memberID]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
roleAssignments[roleKey] = append(roleAssignments[roleKey], memberID)
|
||||
totalRoleAssign++
|
||||
}
|
||||
}
|
||||
|
||||
roleMembershipsAdd[roleKey] = append(roleMembershipsAdd[roleKey], memberID)
|
||||
totalRoleAssign++
|
||||
}
|
||||
}
|
||||
|
||||
if !skipDeletions {
|
||||
for roleKey, assignments := range liveAssignments {
|
||||
for memberID := range assignments {
|
||||
if _, ok := wantAssignments[roleKey]; ok {
|
||||
@@ -87,22 +79,16 @@ func (s *service) syncMemberships(ctx context.Context, memberships []ResourceMem
|
||||
}
|
||||
}
|
||||
|
||||
roleAssignmentRemovals[roleKey] = append(roleAssignmentRemovals[roleKey], memberID)
|
||||
roleMembershipsRemove[roleKey] = append(roleMembershipsRemove[roleKey], memberID)
|
||||
totalRoleUnassign++
|
||||
}
|
||||
}
|
||||
|
||||
resourceRoleCreations[resourceID] = roleCreations
|
||||
resourceRoleDeletions[resourceID] = roleDeletions
|
||||
resourceRoleAssignments[resourceID] = roleAssignments
|
||||
resourceRoleAssignmentRemovals[resourceID] = roleAssignmentRemovals
|
||||
|
||||
totalRoleCreate += len(roleCreations)
|
||||
totalRoleDelete += len(roleDeletions)
|
||||
}
|
||||
|
||||
s.logger.Debugw("processing memberships",
|
||||
"resources", len(resourceMap),
|
||||
totalRoleCreate += len(roleCreations)
|
||||
totalRoleDelete += len(roleDeletions)
|
||||
|
||||
rlogger.Debugw("processing memberships",
|
||||
"role.create", totalRoleCreate,
|
||||
"role.delete", totalRoleDelete,
|
||||
"role.assign", totalRoleAssign,
|
||||
@@ -114,78 +100,74 @@ func (s *service) syncMemberships(ctx context.Context, memberships []ResourceMem
|
||||
roleAssignments, roleUnassignments int
|
||||
)
|
||||
|
||||
for resourceID := range resourceMap {
|
||||
rlogger := s.logger.With("resource.id", resourceID.String())
|
||||
for roleKey, actions := range resourceRoleCreations[resourceID] {
|
||||
roleID, err := s.perms.CreateRole(ctx, resourceID, actions)
|
||||
if err != nil {
|
||||
rlogger.Errorw("error creating role", "actions", actions, "error", err)
|
||||
for roleKey, actions := range roleCreations {
|
||||
roleID, err := s.perms.CreateRole(ctx, relationships.Resource.PrefixedID(), actions)
|
||||
if err != nil {
|
||||
rlogger.Errorw("error creating role", "actions", actions, "error", err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
resourceRoleIDs[resourceID][roleKey] = roleID
|
||||
rolesCreated++
|
||||
continue
|
||||
}
|
||||
|
||||
for _, roleID := range resourceRoleDeletions[resourceID] {
|
||||
if err := s.perms.DeleteRole(ctx, roleID); err != nil {
|
||||
rlogger.Errorw("error deleting role", "role.id", roleID, "error", err)
|
||||
roleIDs[roleKey] = roleID
|
||||
rolesCreated++
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
for _, roleID := range roleDeletions {
|
||||
if err := s.perms.DeleteRole(ctx, roleID); err != nil {
|
||||
rlogger.Errorw("error deleting role", "role.id", roleID, "error", err)
|
||||
|
||||
rolesDeleted++
|
||||
continue
|
||||
}
|
||||
|
||||
for roleKey, members := range resourceRoleAssignments[resourceID] {
|
||||
roleID, ok := resourceRoleIDs[resourceID][roleKey]
|
||||
if !ok {
|
||||
rlogger.Errorw("role id not found for role actions key", "role_actions_key", roleKey, "members", len(members))
|
||||
rolesDeleted++
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
for roleKey, members := range roleMembershipsAdd {
|
||||
roleID, ok := roleIDs[roleKey]
|
||||
if !ok {
|
||||
rlogger.Errorw("role id not found for role actions key", "role_actions_key", roleKey, "members", len(members))
|
||||
|
||||
for _, memberID := range members {
|
||||
if err := s.perms.AssignRole(ctx, roleID, memberID); err != nil {
|
||||
rlogger.Errorw("error assigning member to role", "role.id", roleID, "member.id", memberID, "error", err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
roleAssignments++
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
for roleKey, members := range resourceRoleAssignmentRemovals[resourceID] {
|
||||
roleID, ok := resourceRoleIDs[resourceID][roleKey]
|
||||
if !ok {
|
||||
rlogger.Errorw("role id not found for role actions key", "role_actions_key", roleKey, "members", len(members))
|
||||
for _, memberID := range members {
|
||||
if err := s.perms.AssignRole(ctx, roleID, memberID); err != nil {
|
||||
rlogger.Errorw("error assigning member to role", "role.id", roleID, "member.id", memberID, "error", err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
for _, memberID := range members {
|
||||
if err := s.perms.UnassignRole(ctx, roleID, memberID); err != nil {
|
||||
rlogger.Errorw("error removing member from role", "role.id", roleID, "member.id", memberID, "error", err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
roleUnassignments++
|
||||
}
|
||||
roleAssignments++
|
||||
}
|
||||
}
|
||||
|
||||
s.logger.Debugw("memberships processed",
|
||||
"resources", len(resourceMap),
|
||||
for roleKey, members := range roleMembershipsRemove {
|
||||
roleID, ok := roleIDs[roleKey]
|
||||
if !ok {
|
||||
rlogger.Errorw("role id not found for role actions key", "role_actions_key", roleKey, "members", len(members))
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
for _, memberID := range members {
|
||||
if err := s.perms.UnassignRole(ctx, roleID, memberID); err != nil {
|
||||
rlogger.Errorw("error removing member from role", "role.id", roleID, "member.id", memberID, "error", err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
roleUnassignments++
|
||||
}
|
||||
}
|
||||
|
||||
rlogger.Debugw("memberships processed",
|
||||
"role.create", rolesCreated,
|
||||
"role.delete", rolesDeleted,
|
||||
"role.assign", roleAssignments,
|
||||
"role.unassign", roleUnassignments,
|
||||
)
|
||||
|
||||
return nil
|
||||
return rolesCreated + rolesDeleted, roleAssignments + roleUnassignments
|
||||
}
|
||||
|
||||
func (s *service) mapResourceWants(memberships []ResourceMemberships) (map[string][]string, map[string]map[gidx.PrefixedID]bool) {
|
||||
|
||||
Reference in New Issue
Block a user