mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 19:47:23 +00:00

# Which Problems Are Solved Setup fails to push all role permission events when running Zitadel with CockroachDB. `TransactionRetryError`s were visible in logs which finally times out the setup job with `timeout: context deadline exceeded` # How the Problems Are Solved As suggested in the [Cockroach documentation](timeout: context deadline exceeded), _"break down larger transactions"_. The commands to be pushed for the role permissions are chunked in 50 events per push. This chunking is only done with CockroachDB. # Additional Changes - gci run fixed some unrelated imports - access to `command.Commands` for the setup job, so we can reuse the sync logic. # Additional Context Closes #9293 --------- Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
77 lines
2.5 KiB
Go
77 lines
2.5 KiB
Go
package setup
|
|
|
|
import (
|
|
"context"
|
|
_ "embed"
|
|
"fmt"
|
|
|
|
"github.com/zitadel/logging"
|
|
|
|
"github.com/zitadel/zitadel/internal/api/authz"
|
|
"github.com/zitadel/zitadel/internal/command"
|
|
"github.com/zitadel/zitadel/internal/eventstore"
|
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
|
)
|
|
|
|
// SyncRolePermissions is a repeatable step which synchronizes the InternalAuthZ
|
|
// RolePermissionMappings from the configuration to the database.
|
|
// This is needed until role permissions are manageable over the API.
|
|
type SyncRolePermissions struct {
|
|
commands *command.Commands
|
|
eventstore *eventstore.Eventstore
|
|
rolePermissionMappings []authz.RoleMapping
|
|
}
|
|
|
|
func (mig *SyncRolePermissions) Execute(ctx context.Context, _ eventstore.Event) error {
|
|
if err := mig.executeSystem(ctx); err != nil {
|
|
return err
|
|
}
|
|
return mig.executeInstances(ctx)
|
|
}
|
|
|
|
func (mig *SyncRolePermissions) executeSystem(ctx context.Context) error {
|
|
logging.WithFields("migration", mig.String()).Info("prepare system role permission sync events")
|
|
details, err := mig.commands.SynchronizeRolePermission(ctx, "SYSTEM", mig.rolePermissionMappings)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logging.WithFields("migration", mig.String(), "sequence", details.Sequence).Info("pushed system role permission sync events")
|
|
return nil
|
|
}
|
|
|
|
func (mig *SyncRolePermissions) executeInstances(ctx context.Context) error {
|
|
instances, err := mig.eventstore.InstanceIDs(
|
|
ctx,
|
|
eventstore.NewSearchQueryBuilder(eventstore.ColumnsInstanceIDs).
|
|
OrderDesc().
|
|
AddQuery().
|
|
AggregateTypes(instance.AggregateType).
|
|
EventTypes(instance.InstanceAddedEventType).
|
|
Builder().
|
|
ExcludeAggregateIDs().
|
|
AggregateTypes(instance.AggregateType).
|
|
EventTypes(instance.InstanceRemovedEventType).
|
|
Builder(),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for i, instanceID := range instances {
|
|
logging.WithFields("instance_id", instanceID, "migration", mig.String(), "progress", fmt.Sprintf("%d/%d", i+1, len(instances))).Info("prepare instance role permission sync events")
|
|
details, err := mig.commands.SynchronizeRolePermission(ctx, instanceID, mig.rolePermissionMappings)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logging.WithFields("instance_id", instanceID, "migration", mig.String(), "sequence", details.Sequence).Info("pushed instance role permission sync events")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (*SyncRolePermissions) String() string {
|
|
return "repeatable_sync_role_permissions"
|
|
}
|
|
|
|
func (*SyncRolePermissions) Check(lastRun map[string]interface{}) bool {
|
|
return true
|
|
}
|