package migration import ( "context" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/service" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/zerrors" ) func init() { eventstore.RegisterFilterEventMapper(SystemAggregate, StartedType, SetupMapper) eventstore.RegisterFilterEventMapper(SystemAggregate, DoneType, SetupMapper) eventstore.RegisterFilterEventMapper(SystemAggregate, failedType, SetupMapper) eventstore.RegisterFilterEventMapper(SystemAggregate, repeatableDoneType, SetupMapper) } // SetupStep is the command pushed on the eventstore type SetupStep struct { eventstore.BaseEvent `json:"-"` migration Migration Name string `json:"name"` Error any `json:"error,omitempty"` LastRun any `json:"lastRun,omitempty"` } func setupStartedCmd(ctx context.Context, migration Migration) eventstore.Command { ctx = authz.SetCtxData(service.WithService(ctx, "system"), authz.CtxData{UserID: "system", OrgID: "SYSTEM", ResourceOwner: "SYSTEM"}) return &SetupStep{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, eventstore.NewAggregate(ctx, SystemAggregateID, SystemAggregate, "v1"), StartedType), migration: migration, Name: migration.String(), } } func setupDoneCmd(ctx context.Context, migration Migration, err error) eventstore.Command { ctx = authz.SetCtxData(service.WithService(ctx, "system"), authz.CtxData{UserID: "system", OrgID: "SYSTEM", ResourceOwner: "SYSTEM"}) typ := DoneType var lastRun interface{} if repeatable, ok := migration.(RepeatableMigration); ok { typ = repeatableDoneType lastRun = repeatable } s := &SetupStep{ migration: migration, Name: migration.String(), LastRun: lastRun, } if err != nil { typ = failedType s.Error = err.Error() } s.BaseEvent = *eventstore.NewBaseEventForPush( ctx, eventstore.NewAggregate(ctx, SystemAggregateID, SystemAggregate, "v1"), typ) return s } func (s *SetupStep) Payload() interface{} { return s } func (s *SetupStep) UniqueConstraints() []*eventstore.UniqueConstraint { switch s.Type() { case StartedType: return []*eventstore.UniqueConstraint{ eventstore.NewAddGlobalUniqueConstraint("migration_started", s.migration.String(), "Errors.Step.Started.AlreadyExists"), } case failedType, repeatableDoneType: return []*eventstore.UniqueConstraint{ eventstore.NewRemoveGlobalUniqueConstraint("migration_started", s.migration.String()), } default: return []*eventstore.UniqueConstraint{ eventstore.NewAddGlobalUniqueConstraint("migration_done", s.migration.String(), "Errors.Step.Done.AlreadyExists"), } } } func SetupMapper(event eventstore.Event) (eventstore.Event, error) { step := &SetupStep{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := event.Unmarshal(step) if err != nil { return nil, zerrors.ThrowInternal(err, "IAM-hYp7M", "unable to unmarshal step") } return step, nil }