fix: instance remove (#4602)

This commit is contained in:
Livio Spring
2022-10-26 15:06:48 +02:00
committed by GitHub
parent 001636f2b4
commit d721f725fd
89 changed files with 656 additions and 122 deletions

View File

@@ -150,6 +150,12 @@ func (m *Styling) processLabelPolicy(event *models.Event) (err error) {
return err return err
} }
err = m.generateStylingFile(policy) err = m.generateStylingFile(policy)
case instance.InstanceRemovedEventType:
err = m.deleteInstanceFilesFromStorage(event.InstanceID)
if err != nil {
return err
}
return m.view.DeleteInstanceStyling(event)
default: default:
return m.view.ProcessedStylingSequence(event) return m.view.ProcessedStylingSequence(event)
} }
@@ -262,6 +268,10 @@ func (m *Styling) uploadFilesToStorage(instanceID, aggregateID, contentType stri
return err return err
} }
func (m *Styling) deleteInstanceFilesFromStorage(instanceID string) error {
return m.static.RemoveInstanceObjects(context.Background(), instanceID)
}
func (m *Styling) generateColorPaletteRGBA255(hex string) map[string]string { func (m *Styling) generateColorPaletteRGBA255(hex string) map[string]string {
palette := make(map[string]string) palette := make(map[string]string)
defaultColor := gamut.Hex(hex) defaultColor := gamut.Hex(hex)

View File

@@ -23,6 +23,14 @@ func (v *View) PutStyling(policy *model.LabelPolicyView, event *models.Event) er
return v.ProcessedStylingSequence(event) return v.ProcessedStylingSequence(event)
} }
func (v *View) DeleteInstanceStyling(event *models.Event) error {
err := view.DeleteInstanceStyling(v.Db, stylingTyble, event.InstanceID)
if err != nil {
return err
}
return v.ProcessedStylingSequence(event)
}
func (v *View) GetLatestStylingSequence(instanceID string) (*global_view.CurrentSequence, error) { func (v *View) GetLatestStylingSequence(instanceID string) (*global_view.CurrentSequence, error) {
return v.latestSequence(stylingTyble, instanceID) return v.latestSequence(stylingTyble, instanceID)
} }

View File

@@ -63,6 +63,7 @@ func (s *Server) UpdateInstance(ctx context.Context, req *system_pb.UpdateInstan
} }
func (s *Server) RemoveInstance(ctx context.Context, req *system_pb.RemoveInstanceRequest) (*system_pb.RemoveInstanceResponse, error) { func (s *Server) RemoveInstance(ctx context.Context, req *system_pb.RemoveInstanceRequest) (*system_pb.RemoveInstanceResponse, error) {
ctx = authz.WithInstanceID(ctx, req.InstanceId)
details, err := s.command.RemoveInstance(ctx, req.InstanceId) details, err := s.command.RemoveInstance(ctx, req.InstanceId)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -117,6 +117,8 @@ func (i *IDPConfig) processIdpConfig(providerType iam_model.IDPProviderType, eve
return err return err
} }
return i.view.DeleteIDPConfig(idp.IDPConfigID, event) return i.view.DeleteIDPConfig(idp.IDPConfigID, event)
case instance.InstanceRemovedEventType:
return i.view.DeleteInstanceIDPs(event)
default: default:
return i.view.ProcessedIDPConfigSequence(event) return i.view.ProcessedIDPConfigSequence(event)
} }

View File

@@ -138,6 +138,8 @@ func (i *IDPProvider) processIdpProvider(event *models.Event) (err error) {
return i.view.PutIDPProviders(event, providers...) return i.view.PutIDPProviders(event, providers...)
case org.LoginPolicyRemovedEventType: case org.LoginPolicyRemovedEventType:
return i.view.DeleteIDPProvidersByAggregateID(event.AggregateID, event.InstanceID, event) return i.view.DeleteIDPProvidersByAggregateID(event.AggregateID, event.InstanceID, event)
case instance.InstanceRemovedEventType:
return i.view.DeleteInstanceIDPs(event)
default: default:
return i.view.ProcessedIDPProviderSequence(event) return i.view.ProcessedIDPProviderSequence(event)
} }

View File

@@ -9,6 +9,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/v1/query" "github.com/zitadel/zitadel/internal/eventstore/v1/query"
"github.com/zitadel/zitadel/internal/eventstore/v1/spooler" "github.com/zitadel/zitadel/internal/eventstore/v1/spooler"
view_model "github.com/zitadel/zitadel/internal/project/repository/view/model" view_model "github.com/zitadel/zitadel/internal/project/repository/view/model"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/project" "github.com/zitadel/zitadel/internal/repository/project"
) )
@@ -51,7 +52,7 @@ func (p *OrgProjectMapping) Subscription() *v1.Subscription {
} }
func (_ *OrgProjectMapping) AggregateTypes() []es_models.AggregateType { func (_ *OrgProjectMapping) AggregateTypes() []es_models.AggregateType {
return []es_models.AggregateType{project.AggregateType} return []es_models.AggregateType{project.AggregateType, instance.AggregateType}
} }
func (p *OrgProjectMapping) CurrentSequence(instanceID string) (uint64, error) { func (p *OrgProjectMapping) CurrentSequence(instanceID string) (uint64, error) {
@@ -96,6 +97,8 @@ func (p *OrgProjectMapping) Reduce(event *es_models.Event) (err error) {
if err == nil { if err == nil {
return p.view.ProcessedOrgProjectMappingSequence(event) return p.view.ProcessedOrgProjectMappingSequence(event)
} }
case instance.InstanceRemovedEventType:
return p.view.DeleteInstanceOrgProjectMappings(event)
default: default:
return p.view.ProcessedOrgProjectMappingSequence(event) return p.view.ProcessedOrgProjectMappingSequence(event)
} }

View File

@@ -11,6 +11,7 @@ import (
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models" es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/eventstore/v1/query" "github.com/zitadel/zitadel/internal/eventstore/v1/query"
"github.com/zitadel/zitadel/internal/eventstore/v1/spooler" "github.com/zitadel/zitadel/internal/eventstore/v1/spooler"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/project" "github.com/zitadel/zitadel/internal/repository/project"
"github.com/zitadel/zitadel/internal/repository/user" "github.com/zitadel/zitadel/internal/repository/user"
view_model "github.com/zitadel/zitadel/internal/user/repository/view/model" view_model "github.com/zitadel/zitadel/internal/user/repository/view/model"
@@ -55,7 +56,7 @@ func (t *RefreshToken) Subscription() *v1.Subscription {
} }
func (t *RefreshToken) AggregateTypes() []es_models.AggregateType { func (t *RefreshToken) AggregateTypes() []es_models.AggregateType {
return []es_models.AggregateType{user.AggregateType, project.AggregateType} return []es_models.AggregateType{user.AggregateType, project.AggregateType, instance.AggregateType}
} }
func (t *RefreshToken) CurrentSequence(instanceID string) (uint64, error) { func (t *RefreshToken) CurrentSequence(instanceID string) (uint64, error) {
@@ -109,6 +110,8 @@ func (t *RefreshToken) Reduce(event *es_models.Event) (err error) {
user.UserDeactivatedType, user.UserDeactivatedType,
user.UserRemovedType: user.UserRemovedType:
return t.view.DeleteUserRefreshTokens(event.AggregateID, event.InstanceID, event) return t.view.DeleteUserRefreshTokens(event.AggregateID, event.InstanceID, event)
case instance.InstanceRemovedEventType:
return t.view.DeleteInstanceRefreshTokens(event)
default: default:
return t.view.ProcessedRefreshTokenSequence(event) return t.view.ProcessedRefreshTokenSequence(event)
} }

View File

@@ -16,6 +16,7 @@ import (
proj_model "github.com/zitadel/zitadel/internal/project/model" proj_model "github.com/zitadel/zitadel/internal/project/model"
project_es_model "github.com/zitadel/zitadel/internal/project/repository/eventsourcing/model" project_es_model "github.com/zitadel/zitadel/internal/project/repository/eventsourcing/model"
proj_view "github.com/zitadel/zitadel/internal/project/repository/view" proj_view "github.com/zitadel/zitadel/internal/project/repository/view"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/project" "github.com/zitadel/zitadel/internal/repository/project"
"github.com/zitadel/zitadel/internal/repository/user" "github.com/zitadel/zitadel/internal/repository/user"
user_repo "github.com/zitadel/zitadel/internal/repository/user" user_repo "github.com/zitadel/zitadel/internal/repository/user"
@@ -61,7 +62,7 @@ func (t *Token) Subscription() *v1.Subscription {
} }
func (_ *Token) AggregateTypes() []es_models.AggregateType { func (_ *Token) AggregateTypes() []es_models.AggregateType {
return []es_models.AggregateType{user.AggregateType, project.AggregateType} return []es_models.AggregateType{user.AggregateType, project.AggregateType, instance.AggregateType}
} }
func (p *Token) CurrentSequence(instanceID string) (uint64, error) { func (p *Token) CurrentSequence(instanceID string) (uint64, error) {
@@ -144,6 +145,8 @@ func (t *Token) Reduce(event *es_models.Event) (err error) {
applicationsIDs = append(applicationsIDs, app.AppID) applicationsIDs = append(applicationsIDs, app.AppID)
} }
return t.view.DeleteApplicationTokens(event, applicationsIDs...) return t.view.DeleteApplicationTokens(event, applicationsIDs...)
case instance.InstanceRemovedEventType:
return t.view.DeleteInstanceTokens(event)
default: default:
return t.view.ProcessedTokenSequence(event) return t.view.ProcessedTokenSequence(event)
} }

View File

@@ -16,6 +16,7 @@ import (
org_es_model "github.com/zitadel/zitadel/internal/org/repository/eventsourcing/model" org_es_model "github.com/zitadel/zitadel/internal/org/repository/eventsourcing/model"
"github.com/zitadel/zitadel/internal/org/repository/view" "github.com/zitadel/zitadel/internal/org/repository/view"
query2 "github.com/zitadel/zitadel/internal/query" query2 "github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org" "github.com/zitadel/zitadel/internal/repository/org"
user_repo "github.com/zitadel/zitadel/internal/repository/user" user_repo "github.com/zitadel/zitadel/internal/repository/user"
usr_view "github.com/zitadel/zitadel/internal/user/repository/view" usr_view "github.com/zitadel/zitadel/internal/user/repository/view"
@@ -63,7 +64,7 @@ func (u *User) Subscription() *v1.Subscription {
return u.subscription return u.subscription
} }
func (_ *User) AggregateTypes() []es_models.AggregateType { func (_ *User) AggregateTypes() []es_models.AggregateType {
return []es_models.AggregateType{user_repo.AggregateType, org.AggregateType} return []es_models.AggregateType{user_repo.AggregateType, org.AggregateType, instance.AggregateType}
} }
func (u *User) CurrentSequence(instanceID string) (uint64, error) { func (u *User) CurrentSequence(instanceID string) (uint64, error) {
@@ -88,6 +89,8 @@ func (u *User) Reduce(event *es_models.Event) (err error) {
return u.ProcessUser(event) return u.ProcessUser(event)
case org.AggregateType: case org.AggregateType:
return u.ProcessOrg(event) return u.ProcessOrg(event)
case instance.AggregateType:
return u.ProcessInstance(event)
default: default:
return nil return nil
} }
@@ -229,6 +232,15 @@ func (u *User) ProcessOrg(event *es_models.Event) (err error) {
} }
} }
func (u *User) ProcessInstance(event *es_models.Event) (err error) {
switch eventstore.EventType(event.Type) {
case instance.InstanceRemovedEventType:
return u.view.DeleteInstanceUsers(event)
default:
return u.view.ProcessedUserSequence(event)
}
}
func (u *User) fillLoginNamesOnOrgUsers(event *es_models.Event) error { func (u *User) fillLoginNamesOnOrgUsers(event *es_models.Event) error {
userLoginMustBeDomain, _, domains, err := u.loginNameInformation(context.Background(), event.ResourceOwner, event.InstanceID) userLoginMustBeDomain, _, domains, err := u.loginNameInformation(context.Background(), event.ResourceOwner, event.InstanceID)
if err != nil { if err != nil {

View File

@@ -150,6 +150,8 @@ func (i *ExternalIDP) processIdpConfig(event *es_models.Event) (err error) {
i.fillConfigData(provider, config) i.fillConfigData(provider, config)
} }
return i.view.PutExternalIDPs(event, exterinalIDPs...) return i.view.PutExternalIDPs(event, exterinalIDPs...)
case instance.InstanceRemovedEventType:
return i.view.DeleteInstanceExternalIDPs(event)
default: default:
return i.view.ProcessedExternalIDPSequence(event) return i.view.ProcessedExternalIDPSequence(event)
} }

View File

@@ -17,6 +17,7 @@ import (
org_es_model "github.com/zitadel/zitadel/internal/org/repository/eventsourcing/model" org_es_model "github.com/zitadel/zitadel/internal/org/repository/eventsourcing/model"
"github.com/zitadel/zitadel/internal/org/repository/view" "github.com/zitadel/zitadel/internal/org/repository/view"
query2 "github.com/zitadel/zitadel/internal/query" query2 "github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org" "github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/user" "github.com/zitadel/zitadel/internal/repository/user"
view_model "github.com/zitadel/zitadel/internal/user/repository/view/model" view_model "github.com/zitadel/zitadel/internal/user/repository/view/model"
@@ -61,7 +62,7 @@ func (u *UserSession) Subscription() *v1.Subscription {
} }
func (_ *UserSession) AggregateTypes() []models.AggregateType { func (_ *UserSession) AggregateTypes() []models.AggregateType {
return []models.AggregateType{user.AggregateType, org.AggregateType} return []models.AggregateType{user.AggregateType, org.AggregateType, instance.AggregateType}
} }
func (u *UserSession) CurrentSequence(instanceID string) (uint64, error) { func (u *UserSession) CurrentSequence(instanceID string) (uint64, error) {
@@ -153,6 +154,8 @@ func (u *UserSession) Reduce(event *models.Event) (err error) {
return u.fillLoginNamesOnOrgUsers(event) return u.fillLoginNamesOnOrgUsers(event)
case user.UserRemovedType: case user.UserRemovedType:
return u.view.DeleteUserSessions(event.AggregateID, event.InstanceID, event) return u.view.DeleteUserSessions(event.AggregateID, event.InstanceID, event)
case instance.InstanceRemovedEventType:
return u.view.DeleteInstanceUserSessions(event)
default: default:
return u.view.ProcessedUserSessionSequence(event) return u.view.ProcessedUserSessionSequence(event)
} }

View File

@@ -56,6 +56,14 @@ func (v *View) DeleteExternalIDPsByUserID(userID, instanceID string, event *mode
return v.ProcessedExternalIDPSequence(event) return v.ProcessedExternalIDPSequence(event)
} }
func (v *View) DeleteInstanceExternalIDPs(event *models.Event) error {
err := view.DeleteInstanceExternalIDPs(v.Db, externalIDPTable, event.InstanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedExternalIDPSequence(event)
}
func (v *View) GetLatestExternalIDPSequence(instanceID string) (*global_view.CurrentSequence, error) { func (v *View) GetLatestExternalIDPSequence(instanceID string) (*global_view.CurrentSequence, error) {
return v.latestSequence(externalIDPTable, instanceID) return v.latestSequence(externalIDPTable, instanceID)
} }

View File

@@ -41,6 +41,14 @@ func (v *View) DeleteIDPConfig(idpID string, event *models.Event) error {
return v.ProcessedIDPConfigSequence(event) return v.ProcessedIDPConfigSequence(event)
} }
func (v *View) DeleteInstanceIDPs(event *models.Event) error {
err := view.DeleteInstanceIDPs(v.Db, idpConfigTable, event.InstanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedIDPConfigSequence(event)
}
func (v *View) GetLatestIDPConfigSequence(instanceID string) (*global_view.CurrentSequence, error) { func (v *View) GetLatestIDPConfigSequence(instanceID string) (*global_view.CurrentSequence, error) {
return v.latestSequence(idpConfigTable, instanceID) return v.latestSequence(idpConfigTable, instanceID)
} }

View File

@@ -61,6 +61,14 @@ func (v *View) DeleteIDPProvidersByAggregateID(aggregateID, instanceID string, e
return v.ProcessedIDPProviderSequence(event) return v.ProcessedIDPProviderSequence(event)
} }
func (v *View) DeleteInstanceIDPProviders(event *models.Event) error {
err := view.DeleteInstanceIDPProviders(v.Db, idpProviderTable, event.InstanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedIDPProviderSequence(event)
}
func (v *View) GetLatestIDPProviderSequence(instanceID string) (*global_view.CurrentSequence, error) { func (v *View) GetLatestIDPProviderSequence(instanceID string) (*global_view.CurrentSequence, error) {
return v.latestSequence(idpProviderTable, instanceID) return v.latestSequence(idpProviderTable, instanceID)
} }

View File

@@ -32,6 +32,14 @@ func (v *View) DeleteOrgProjectMapping(orgID, projectID, instanceID string, even
return v.ProcessedOrgProjectMappingSequence(event) return v.ProcessedOrgProjectMappingSequence(event)
} }
func (v *View) DeleteInstanceOrgProjectMappings(event *models.Event) error {
err := view.DeleteInstanceOrgProjectMappings(v.Db, orgPrgojectMappingTable, event.InstanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedOrgProjectMappingSequence(event)
}
func (v *View) DeleteOrgProjectMappingsByProjectID(projectID, instanceID string) error { func (v *View) DeleteOrgProjectMappingsByProjectID(projectID, instanceID string) error {
return view.DeleteOrgProjectMappingsByProjectID(v.Db, orgPrgojectMappingTable, projectID, instanceID) return view.DeleteOrgProjectMappingsByProjectID(v.Db, orgPrgojectMappingTable, projectID, instanceID)
} }

View File

@@ -65,6 +65,14 @@ func (v *View) DeleteApplicationRefreshTokens(event *models.Event, ids ...string
return v.ProcessedRefreshTokenSequence(event) return v.ProcessedRefreshTokenSequence(event)
} }
func (v *View) DeleteInstanceRefreshTokens(event *models.Event) error {
err := usr_view.DeleteInstanceRefreshTokens(v.Db, refreshTokenTable, event.InstanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedRefreshTokenSequence(event)
}
func (v *View) GetLatestRefreshTokenSequence(instanceID string) (*repository.CurrentSequence, error) { func (v *View) GetLatestRefreshTokenSequence(instanceID string) (*repository.CurrentSequence, error) {
return v.latestSequence(refreshTokenTable, instanceID) return v.latestSequence(refreshTokenTable, instanceID)
} }

View File

@@ -76,6 +76,14 @@ func (v *View) DeleteTokensFromRefreshToken(refreshTokenID, instanceID string, e
return v.ProcessedTokenSequence(event) return v.ProcessedTokenSequence(event)
} }
func (v *View) DeleteInstanceTokens(event *models.Event) error {
err := usr_view.DeleteInstanceTokens(v.Db, tokenTable, event.InstanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedTokenSequence(event)
}
func (v *View) GetLatestTokenSequence(instanceID string) (*repository.CurrentSequence, error) { func (v *View) GetLatestTokenSequence(instanceID string) (*repository.CurrentSequence, error) {
return v.latestSequence(tokenTable, instanceID) return v.latestSequence(tokenTable, instanceID)
} }

View File

@@ -181,6 +181,14 @@ func (v *View) DeleteUser(userID, instanceID string, event *models.Event) error
return v.ProcessedUserSequence(event) return v.ProcessedUserSequence(event)
} }
func (v *View) DeleteInstanceUsers(event *models.Event) error {
err := view.DeleteInstanceUsers(v.Db, userTable, event.InstanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedUserSequence(event)
}
func (v *View) GetLatestUserSequence(instanceID string) (*repository.CurrentSequence, error) { func (v *View) GetLatestUserSequence(instanceID string) (*repository.CurrentSequence, error) {
return v.latestSequence(userTable, instanceID) return v.latestSequence(userTable, instanceID)
} }

View File

@@ -56,6 +56,14 @@ func (v *View) DeleteUserSessions(userID, instanceID string, event *models.Event
return v.ProcessedUserSessionSequence(event) return v.ProcessedUserSessionSequence(event)
} }
func (v *View) DeleteInstanceUserSessions(event *models.Event) error {
err := view.DeleteInstanceUserSessions(v.Db, userSessionTable, event.InstanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedUserSessionSequence(event)
}
func (v *View) GetLatestUserSessionSequence(instanceID string) (*repository.CurrentSequence, error) { func (v *View) GetLatestUserSessionSequence(instanceID string) (*repository.CurrentSequence, error) {
return v.latestSequence(userSessionTable, instanceID) return v.latestSequence(userSessionTable, instanceID)
} }

View File

@@ -550,7 +550,7 @@ func (c *Commands) prepareUpdateInstance(a *instance.Aggregate, name string) pre
if err != nil { if err != nil {
return nil, err return nil, err
} }
if writeModel.State == domain.InstanceStateUnspecified { if !writeModel.State.Exists() {
return nil, errors.ThrowNotFound(nil, "INST-nuso2m", "Errors.Instance.NotFound") return nil, errors.ThrowNotFound(nil, "INST-nuso2m", "Errors.Instance.NotFound")
} }
if writeModel.Name == name { if writeModel.Name == name {
@@ -631,17 +631,16 @@ func (c *Commands) prepareRemoveInstance(a *instance.Aggregate) preparation.Vali
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) { return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
writeModel, err := c.getInstanceWriteModelByID(ctx, a.ID) writeModel, err := c.getInstanceWriteModelByID(ctx, a.ID)
if err != nil { if err != nil {
return nil, errors.ThrowPreconditionFailed(err, "COMMA-pax9m3", "Errors.Instance.NotFound") return nil, errors.ThrowNotFound(err, "COMMA-pax9m3", "Errors.Instance.NotFound")
} }
events := []eventstore.Command{instance.NewInstanceRemovedEvent(ctx, &a.Aggregate, writeModel.Name)} if !writeModel.State.Exists() {
return nil, errors.ThrowNotFound(err, "COMMA-AE3GS", "Errors.Instance.NotFound")
domainsWriteModel, err := c.getInstanceDomainsWriteModel(ctx, a.ID)
if err == nil {
for _, domainName := range domainsWriteModel.Domains {
events = append(events, instance.NewDomainRemovedEvent(ctx, &a.Aggregate, domainName))
} }
} return []eventstore.Command{instance.NewInstanceRemovedEvent(ctx,
return events, nil &a.Aggregate,
writeModel.Name,
writeModel.Domains)},
nil
}, nil }, nil
} }
} }

View File

@@ -14,6 +14,7 @@ type InstanceWriteModel struct {
Name string Name string
State domain.InstanceState State domain.InstanceState
GeneratedDomain string GeneratedDomain string
Domains []string
DefaultOrgID string DefaultOrgID string
ProjectID string ProjectID string
@@ -41,10 +42,16 @@ func (wm *InstanceWriteModel) Reduce() error {
case *instance.InstanceRemovedEvent: case *instance.InstanceRemovedEvent:
wm.State = domain.InstanceStateRemoved wm.State = domain.InstanceStateRemoved
case *instance.DomainAddedEvent: case *instance.DomainAddedEvent:
if !e.Generated { if e.Generated {
continue
}
wm.GeneratedDomain = e.Domain wm.GeneratedDomain = e.Domain
}
wm.Domains = append(wm.Domains, e.Domain)
case *instance.DomainRemovedEvent:
for _, customDomain := range wm.Domains {
if customDomain == e.Domain {
wm.Domains = removeDomainFromDomains(wm.Domains, e.Domain)
}
}
case *instance.ProjectSetEvent: case *instance.ProjectSetEvent:
wm.ProjectID = e.ProjectID wm.ProjectID = e.ProjectID
case *instance.DefaultOrgSetEvent: case *instance.DefaultOrgSetEvent:

View File

@@ -14,14 +14,13 @@ import (
"github.com/zitadel/zitadel/internal/repository/instance" "github.com/zitadel/zitadel/internal/repository/instance"
) )
func TestCommandSide_ChangeInstance(t *testing.T) { func TestCommandSide_UpdateInstance(t *testing.T) {
type fields struct { type fields struct {
eventstore *eventstore.Eventstore eventstore *eventstore.Eventstore
} }
type args struct { type args struct {
ctx context.Context ctx context.Context
name string name string
instanceID string
} }
type res struct { type res struct {
want *domain.ObjectDetails want *domain.ObjectDetails
@@ -42,7 +41,6 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
}, },
args: args{ args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"), ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
instanceID: "INSTANCE",
name: "", name: "",
}, },
res: res{ res: res{
@@ -59,16 +57,14 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
}, },
args: args{ args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"), ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
instanceID: "INSTANCE",
name: "INSTANCE_CHANGED", name: "INSTANCE_CHANGED",
}, },
res: res{ res: res{
err: caos_errs.IsNotFound, err: caos_errs.IsNotFound,
}, },
}, },
/* instance removed is not yet implemented
{ {
name: "generator removed, not found error", name: "instance removed, not found error",
fields: fields{ fields: fields{
eventstore: eventstoreExpect( eventstore: eventstoreExpect(
t, t,
@@ -84,6 +80,7 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
instance.NewInstanceRemovedEvent(context.Background(), instance.NewInstanceRemovedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate, &instance.NewAggregate("INSTANCE").Aggregate,
"INSTANCE", "INSTANCE",
nil,
), ),
), ),
), ),
@@ -96,7 +93,7 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
res: res{ res: res{
err: caos_errs.IsNotFound, err: caos_errs.IsNotFound,
}, },
},*/ },
{ {
name: "no changes, precondition error", name: "no changes, precondition error",
fields: fields{ fields: fields{
@@ -115,7 +112,6 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
}, },
args: args{ args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"), ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
instanceID: "INSTANCE",
name: "INSTANCE", name: "INSTANCE",
}, },
res: res{ res: res{
@@ -178,3 +174,148 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
}) })
} }
} }
func TestCommandSide_RemoveInstance(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
instanceID string
}
type res struct {
want *domain.ObjectDetails
err func(error) bool
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
name: "instance not existing, not found error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
instanceID: "INSTANCE",
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "instance removed, not found error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
instance.NewInstanceAddedEvent(
context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"INSTANCE",
),
),
eventFromEventPusher(
instance.NewInstanceRemovedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"INSTANCE",
nil,
),
),
),
),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
instanceID: "INSTANCE",
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "instance remove, ok",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusherWithInstanceID(
"INSTANCE",
instance.NewInstanceAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"INSTANCE",
),
),
eventFromEventPusherWithInstanceID(
"INSTANCE",
instance.NewDomainAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"instance.domain",
true,
),
),
eventFromEventPusherWithInstanceID(
"INSTANCE",
instance.NewDomainAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"custom.domain",
false,
),
),
),
expectPush(
[]*repository.Event{
eventFromEventPusherWithInstanceID(
"INSTANCE",
instance.NewInstanceRemovedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"INSTANCE",
[]string{
"instance.domain",
"custom.domain",
},
),
),
},
uniqueConstraintsFromEventConstraint(instance.NewRemoveInstanceDomainUniqueConstraint("instance.domain")),
uniqueConstraintsFromEventConstraint(instance.NewRemoveInstanceDomainUniqueConstraint("custom.domain")),
uniqueConstraintsFromEventConstraintWithInstanceID("INSTANCE", eventstore.NewRemoveInstanceUniqueConstraints()),
),
),
},
args: args{
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
instanceID: "INSTANCE",
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "INSTANCE",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
}
got, err := r.RemoveInstance(tt.args.ctx, tt.args.instanceID)
if tt.res.err == nil {
assert.NoError(t, err)
}
if tt.res.err != nil && !tt.res.err(err) {
t.Errorf("got wrong err: %v ", err)
}
if tt.res.err == nil {
assert.Equal(t, tt.res.want, got)
}
})
}
}

View File

@@ -14,6 +14,10 @@ const (
instanceStateCount instanceStateCount
) )
func (f InstanceState) Valid() bool { func (s InstanceState) Valid() bool {
return f >= 0 && f < instanceStateCount return s >= 0 && s < instanceStateCount
}
func (s InstanceState) Exists() bool {
return s != InstanceStateUnspecified && s != InstanceStateRemoved
} }

View File

@@ -12,7 +12,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/repository" "github.com/zitadel/zitadel/internal/eventstore/repository"
) )
//Eventstore abstracts all functions needed to store valid events // Eventstore abstracts all functions needed to store valid events
// and filters the stored events // and filters the stored events
type Eventstore struct { type Eventstore struct {
repo repository.Repository repo repository.Repository
@@ -32,13 +32,13 @@ func NewEventstore(repo repository.Repository) *Eventstore {
} }
} }
//Health checks if the eventstore can properly work // Health checks if the eventstore can properly work
// It checks if the repository can serve load // It checks if the repository can serve load
func (es *Eventstore) Health(ctx context.Context) error { func (es *Eventstore) Health(ctx context.Context) error {
return es.repo.Health(ctx) return es.repo.Health(ctx)
} }
//Push pushes the events in a single transaction // Push pushes the events in a single transaction
// an event needs at least an aggregate // an event needs at least an aggregate
func (es *Eventstore) Push(ctx context.Context, cmds ...Command) ([]Event, error) { func (es *Eventstore) Push(ctx context.Context, cmds ...Command) ([]Event, error) {
events, constraints, err := commandsToRepository(authz.GetInstance(ctx).InstanceID(), cmds) events, constraints, err := commandsToRepository(authz.GetInstance(ctx).InstanceID(), cmds)
@@ -119,7 +119,7 @@ func uniqueConstraintsToRepository(instanceID string, constraints []*EventUnique
return uniqueConstraints return uniqueConstraints
} }
//Filter filters the stored events based on the searchQuery // Filter filters the stored events based on the searchQuery
// and maps the events to the defined event structs // and maps the events to the defined event structs
func (es *Eventstore) Filter(ctx context.Context, queryFactory *SearchQueryBuilder) ([]Event, error) { func (es *Eventstore) Filter(ctx context.Context, queryFactory *SearchQueryBuilder) ([]Event, error) {
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID()) query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
@@ -165,7 +165,7 @@ type reducer interface {
AppendEvents(...Event) AppendEvents(...Event)
} }
//FilterToReducer filters the events based on the search query, appends all events to the reducer and calls it's reduce function // FilterToReducer filters the events based on the search query, appends all events to the reducer and calls it's reduce function
func (es *Eventstore) FilterToReducer(ctx context.Context, searchQuery *SearchQueryBuilder, r reducer) error { func (es *Eventstore) FilterToReducer(ctx context.Context, searchQuery *SearchQueryBuilder, r reducer) error {
events, err := es.Filter(ctx, searchQuery) events, err := es.Filter(ctx, searchQuery)
if err != nil { if err != nil {
@@ -177,7 +177,7 @@ func (es *Eventstore) FilterToReducer(ctx context.Context, searchQuery *SearchQu
return r.Reduce() return r.Reduce()
} }
//LatestSequence filters the latest sequence for the given search query // LatestSequence filters the latest sequence for the given search query
func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQueryBuilder) (uint64, error) { func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQueryBuilder) (uint64, error) {
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID()) query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
if err != nil { if err != nil {
@@ -186,7 +186,7 @@ func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQu
return es.repo.LatestSequence(ctx, query) return es.repo.LatestSequence(ctx, query)
} }
//InstanceIDs returns the instance ids found by the search query // InstanceIDs returns the instance ids found by the search query
func (es *Eventstore) InstanceIDs(ctx context.Context, queryFactory *SearchQueryBuilder) ([]string, error) { func (es *Eventstore) InstanceIDs(ctx context.Context, queryFactory *SearchQueryBuilder) ([]string, error) {
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID()) query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
if err != nil { if err != nil {
@@ -201,7 +201,7 @@ type QueryReducer interface {
Query() *SearchQueryBuilder Query() *SearchQueryBuilder
} }
//FilterToQueryReducer filters the events based on the search query of the query function, // FilterToQueryReducer filters the events based on the search query of the query function,
// appends all events to the reducer and calls it's reduce function // appends all events to the reducer and calls it's reduce function
func (es *Eventstore) FilterToQueryReducer(ctx context.Context, r QueryReducer) error { func (es *Eventstore) FilterToQueryReducer(ctx context.Context, r QueryReducer) error {
events, err := es.Filter(ctx, r.Query()) events, err := es.Filter(ctx, r.Query())
@@ -213,7 +213,7 @@ func (es *Eventstore) FilterToQueryReducer(ctx context.Context, r QueryReducer)
return r.Reduce() return r.Reduce()
} }
//RegisterFilterEventMapper registers a function for mapping an eventstore event to an event // RegisterFilterEventMapper registers a function for mapping an eventstore event to an event
func (es *Eventstore) RegisterFilterEventMapper(eventType EventType, mapper func(*repository.Event) (Event, error)) *Eventstore { func (es *Eventstore) RegisterFilterEventMapper(eventType EventType, mapper func(*repository.Event) (Event, error)) *Eventstore {
if mapper == nil || eventType == "" { if mapper == nil || eventType == "" {
return es return es
@@ -258,6 +258,8 @@ func uniqueConstraintActionToRepository(action UniqueConstraintAction) repositor
return repository.UniqueConstraintAdd return repository.UniqueConstraintAdd
case UniqueConstraintRemove: case UniqueConstraintRemove:
return repository.UniqueConstraintRemoved return repository.UniqueConstraintRemoved
case UniqueConstraintInstanceRemove:
return repository.UniqueConstraintInstanceRemoved
default: default:
return repository.UniqueConstraintAdd return repository.UniqueConstraintAdd
} }

View File

@@ -92,6 +92,8 @@ const (
uniqueDelete = `DELETE FROM eventstore.unique_constraints uniqueDelete = `DELETE FROM eventstore.unique_constraints
WHERE unique_type = $1 and unique_field = $2 and instance_id = $3` WHERE unique_type = $1 and unique_field = $2 and instance_id = $3`
uniqueDeleteInstance = `DELETE FROM eventstore.unique_constraints
WHERE instance_id = $1`
) )
type CRDB struct { type CRDB struct {
@@ -193,7 +195,7 @@ func (db *CRDB) handleUniqueConstraints(ctx context.Context, tx *sql.Tx, uniqueC
return caos_errs.ThrowAlreadyExists(err, "SQL-M0dsf", uniqueConstraint.ErrorMessage) return caos_errs.ThrowAlreadyExists(err, "SQL-M0dsf", uniqueConstraint.ErrorMessage)
} }
return caos_errs.ThrowInternal(err, "SQL-dM9ds", "unable to create unique constraint ") return caos_errs.ThrowInternal(err, "SQL-dM9ds", "unable to create unique constraint")
} }
case repository.UniqueConstraintRemoved: case repository.UniqueConstraintRemoved:
_, err := tx.ExecContext(ctx, uniqueDelete, uniqueConstraint.UniqueType, uniqueConstraint.UniqueField, uniqueConstraint.InstanceID) _, err := tx.ExecContext(ctx, uniqueDelete, uniqueConstraint.UniqueType, uniqueConstraint.UniqueField, uniqueConstraint.InstanceID)
@@ -201,7 +203,14 @@ func (db *CRDB) handleUniqueConstraints(ctx context.Context, tx *sql.Tx, uniqueC
logging.WithFields( logging.WithFields(
"unique_type", uniqueConstraint.UniqueType, "unique_type", uniqueConstraint.UniqueType,
"unique_field", uniqueConstraint.UniqueField).WithError(err).Info("delete unique constraint failed") "unique_field", uniqueConstraint.UniqueField).WithError(err).Info("delete unique constraint failed")
return caos_errs.ThrowInternal(err, "SQL-6n88i", "unable to remove unique constraint ") return caos_errs.ThrowInternal(err, "SQL-6n88i", "unable to remove unique constraint")
}
case repository.UniqueConstraintInstanceRemoved:
_, err := tx.ExecContext(ctx, uniqueDeleteInstance, uniqueConstraint.InstanceID)
if err != nil {
logging.WithFields(
"instance_id", uniqueConstraint.InstanceID).WithError(err).Info("delete instance unique constraints failed")
return caos_errs.ThrowInternal(err, "SQL-6n88i", "unable to remove unique constraints of instance")
} }
} }
} }

View File

@@ -379,24 +379,28 @@ func TestCRDB_Push_OneAggregate(t *testing.T) {
}}, }},
}, },
{ {
name: "push 1 event and add asset", name: "push 1 event and remove instance unique constraints",
args: args{ args: args{
ctx: context.Background(), ctx: context.Background(),
events: []*repository.Event{ events: []*repository.Event{
generateEvent(t, "12"), generateEvent(t, "12"),
}, },
uniqueConstraints: generateRemoveInstanceUniqueConstraints(t, "instanceID"),
uniqueDataType: "usernames",
uniqueDataField: "testremove",
uniqueDataInstanceID: "instanceID",
}, },
res: res{ res: res{
wantErr: false, wantErr: false,
eventsRes: eventsRes{ eventsRes: eventsRes{
pushedEventsCount: 1, pushedEventsCount: 1,
assetCount: 1, uniqueCount: 0,
aggID: []string{"12"}, aggID: []string{"12"},
aggType: repository.AggregateType(t.Name()), aggType: repository.AggregateType(t.Name()),
}}, }},
}, },
{ {
name: "push 1 event and remove asset", name: "push 1 event and add asset",
args: args{ args: args{
ctx: context.Background(), ctx: context.Background(),
events: []*repository.Event{ events: []*repository.Event{
@@ -407,11 +411,28 @@ func TestCRDB_Push_OneAggregate(t *testing.T) {
wantErr: false, wantErr: false,
eventsRes: eventsRes{ eventsRes: eventsRes{
pushedEventsCount: 1, pushedEventsCount: 1,
assetCount: 0, assetCount: 1,
aggID: []string{"13"}, aggID: []string{"13"},
aggType: repository.AggregateType(t.Name()), aggType: repository.AggregateType(t.Name()),
}}, }},
}, },
{
name: "push 1 event and remove asset",
args: args{
ctx: context.Background(),
events: []*repository.Event{
generateEvent(t, "14"),
},
},
res: res{
wantErr: false,
eventsRes: eventsRes{
pushedEventsCount: 1,
assetCount: 0,
aggID: []string{"14"},
aggType: repository.AggregateType(t.Name()),
}},
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@@ -1201,3 +1222,13 @@ func generateRemoveUniqueConstraint(t *testing.T, table, uniqueField string) *re
return e return e
} }
func generateRemoveInstanceUniqueConstraints(t *testing.T, instanceID string) *repository.UniqueConstraint {
t.Helper()
e := &repository.UniqueConstraint{
InstanceID: instanceID,
Action: repository.UniqueConstraintInstanceRemoved,
}
return e
}

View File

@@ -1,6 +1,6 @@
package repository package repository
//UniqueCheck represents all information about a unique attribute // UniqueCheck represents all information about a unique attribute
type UniqueConstraint struct { type UniqueConstraint struct {
//UniqueField is the field which should be unique //UniqueField is the field which should be unique
UniqueField string UniqueField string
@@ -23,6 +23,7 @@ type UniqueConstraintAction int32
const ( const (
UniqueConstraintAdd UniqueConstraintAction = iota UniqueConstraintAdd UniqueConstraintAction = iota
UniqueConstraintRemoved UniqueConstraintRemoved
UniqueConstraintInstanceRemoved
uniqueConstraintActionCount uniqueConstraintActionCount
) )

View File

@@ -18,6 +18,7 @@ type UniqueConstraintAction int32
const ( const (
UniqueConstraintAdd UniqueConstraintAction = iota UniqueConstraintAdd UniqueConstraintAction = iota
UniqueConstraintRemove UniqueConstraintRemove
UniqueConstraintInstanceRemove
) )
func NewAddEventUniqueConstraint( func NewAddEventUniqueConstraint(
@@ -42,6 +43,12 @@ func NewRemoveEventUniqueConstraint(
} }
} }
func NewRemoveInstanceUniqueConstraints() *EventUniqueConstraint {
return &EventUniqueConstraint{
Action: UniqueConstraintInstanceRemove,
}
}
func NewAddGlobalEventUniqueConstraint( func NewAddGlobalEventUniqueConstraint(
uniqueType, uniqueType,
uniqueField, uniqueField,

View File

@@ -112,3 +112,8 @@ func DeleteIDPProvidersByAggregateID(db *gorm.DB, table, aggregateID, instanceID
) )
return delete(db) return delete(db)
} }
func DeleteInstanceIDPProviders(db *gorm.DB, table, instanceID string) error {
delete := repository.PrepareDeleteByKey(table, model.IDPProviderSearchKey(iam_model.IDPProviderSearchKeyInstanceID), instanceID)
return delete(db)
}

View File

@@ -63,6 +63,10 @@ func DeleteIDP(db *gorm.DB, table, idpID, instanceID string) error {
repository.Key{model.IDPConfigSearchKey(iam_model.IDPConfigSearchKeyIdpConfigID), idpID}, repository.Key{model.IDPConfigSearchKey(iam_model.IDPConfigSearchKeyIdpConfigID), idpID},
repository.Key{model.IDPConfigSearchKey(iam_model.IDPConfigSearchKeyInstanceID), instanceID}, repository.Key{model.IDPConfigSearchKey(iam_model.IDPConfigSearchKeyInstanceID), instanceID},
) )
return delete(db)
}
func DeleteInstanceIDPs(db *gorm.DB, table, instanceID string) error {
delete := repository.PrepareDeleteByKey(table, model.IDPConfigSearchKey(iam_model.IDPConfigSearchKeyInstanceID), instanceID)
return delete(db) return delete(db)
} }

View File

@@ -28,8 +28,7 @@ func PutStyling(db *gorm.DB, table string, policy *model.LabelPolicyView) error
return save(db, policy) return save(db, policy)
} }
func DeleteStyling(db *gorm.DB, table, aggregateID string) error { func DeleteInstanceStyling(db *gorm.DB, table, instanceID string) error {
delete := repository.PrepareDeleteByKey(table, model.LabelPolicySearchKey(iam_model.LabelPolicySearchKeyAggregateID), aggregateID) delete := repository.PrepareDeleteByKey(table, model.LabelPolicySearchKey(iam_model.LabelPolicySearchKeyInstanceID), instanceID)
return delete(db) return delete(db)
} }

View File

@@ -37,6 +37,11 @@ func DeleteOrgProjectMapping(db *gorm.DB, table, orgID, projectID, instanceID st
return delete(db) return delete(db)
} }
func DeleteInstanceOrgProjectMappings(db *gorm.DB, table, instanceID string) error {
delete := repository.PrepareDeleteByKey(table, model.OrgProjectMappingSearchKey(proj_model.OrgProjectMappingSearchKeyInstanceID), instanceID)
return delete(db)
}
func DeleteOrgProjectMappingsByProjectID(db *gorm.DB, table, projectID, instanceID string) error { func DeleteOrgProjectMappingsByProjectID(db *gorm.DB, table, projectID, instanceID string) error {
delete := repository.PrepareDeleteByKeys(table, delete := repository.PrepareDeleteByKeys(table,
repository.Key{model.OrgProjectMappingSearchKey(proj_model.OrgProjectMappingSearchKeyProjectID), projectID}, repository.Key{model.OrgProjectMappingSearchKey(proj_model.OrgProjectMappingSearchKeyProjectID), projectID},

View File

@@ -179,7 +179,7 @@ func TestActionProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(ActionInstanceIDCol), reduce: reduceInstanceRemovedHelper(ActionInstanceIDCol),

View File

@@ -220,7 +220,7 @@ func TestAppProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(AppColumnInstanceID), reduce: reduceInstanceRemovedHelper(AppColumnInstanceID),

View File

@@ -226,7 +226,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(AuthNKeyInstanceIDCol), reduce: reduceInstanceRemovedHelper(AuthNKeyInstanceIDCol),

View File

@@ -132,7 +132,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(CustomTextInstanceIDCol), reduce: reduceInstanceRemovedHelper(CustomTextInstanceIDCol),

View File

@@ -217,7 +217,7 @@ func TestDebugNotificationProviderProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(DebugNotificationProviderInstanceIDCol), reduce: reduceInstanceRemovedHelper(DebugNotificationProviderInstanceIDCol),

View File

@@ -129,7 +129,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(DomainPolicyInstanceIDCol), reduce: reduceInstanceRemovedHelper(DomainPolicyInstanceIDCol),

View File

@@ -109,7 +109,7 @@ func TestFlowProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(FlowInstanceIDCol), reduce: reduceInstanceRemovedHelper(FlowInstanceIDCol),

View File

@@ -190,7 +190,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(IDPUserLinkInstanceIDCol), reduce: reduceInstanceRemovedHelper(IDPUserLinkInstanceIDCol),

View File

@@ -201,7 +201,7 @@ func TestIDPProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(IDPInstanceIDCol), reduce: reduceInstanceRemovedHelper(IDPInstanceIDCol),

View File

@@ -154,7 +154,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(IDPUserLinkInstanceIDCol), reduce: reduceInstanceRemovedHelper(IDPUserLinkInstanceIDCol),

View File

@@ -85,7 +85,7 @@ func TestInstanceDomainProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(InstanceDomainInstanceIDCol), reduce: reduceInstanceRemovedHelper(InstanceDomainInstanceIDCol),

View File

@@ -178,7 +178,7 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(MemberInstanceID), reduce: reduceInstanceRemovedHelper(MemberInstanceID),

View File

@@ -56,7 +56,7 @@ func TestInstanceProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(InstanceColumnID), reduce: reduceInstanceRemovedHelper(InstanceColumnID),

View File

@@ -106,7 +106,7 @@ func TestKeyProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(KeyColumnInstanceID), reduce: reduceInstanceRemovedHelper(KeyColumnInstanceID),

View File

@@ -131,7 +131,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(LabelPolicyInstanceIDCol), reduce: reduceInstanceRemovedHelper(LabelPolicyInstanceIDCol),

View File

@@ -125,7 +125,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(LockoutPolicyInstanceIDCol), reduce: reduceInstanceRemovedHelper(LockoutPolicyInstanceIDCol),

View File

@@ -213,7 +213,7 @@ func (p *loginNameProjection) reducers() []handler.AggregateReducer {
}, },
{ {
Event: instance.InstanceRemovedEventType, Event: instance.InstanceRemovedEventType,
Reduce: reduceInstanceRemovedHelper(LoginNameUserInstanceIDCol), Reduce: p.reduceInstanceRemoved,
}, },
}, },
}, },
@@ -432,3 +432,32 @@ func (p *loginNameProjection) reduceDomainRemoved(event eventstore.Event) (*hand
crdb.WithTableSuffix(loginNameDomainSuffix), crdb.WithTableSuffix(loginNameDomainSuffix),
), nil ), nil
} }
func (p *loginNameProjection) reduceInstanceRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.InstanceRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-ASeg3", "reduce.wrong.event.type %s", instance.InstanceRemovedEventType)
}
return crdb.NewMultiStatement(
event,
crdb.AddDeleteStatement(
[]handler.Condition{
handler.NewCond(LoginNameDomainInstanceIDCol, e.Aggregate().ID),
},
crdb.WithTableSuffix(loginNameDomainSuffix),
),
crdb.AddDeleteStatement(
[]handler.Condition{
handler.NewCond(LoginNamePoliciesInstanceIDCol, e.Aggregate().ID),
},
crdb.WithTableSuffix(loginNamePolicySuffix),
),
crdb.AddDeleteStatement(
[]handler.Condition{
handler.NewCond(LoginNameUserInstanceIDCol, e.Aggregate().ID),
},
crdb.WithTableSuffix(loginNameUserSuffix),
),
), nil
}

View File

@@ -486,10 +486,10 @@ func TestLoginNameProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(LoginNameUserInstanceIDCol), reduce: (&loginNameProjection{}).reduceInstanceRemoved,
want: wantReduce{ want: wantReduce{
aggregateType: eventstore.AggregateType("instance"), aggregateType: eventstore.AggregateType("instance"),
sequence: 15, sequence: 15,
@@ -497,7 +497,19 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "DELETE FROM projections.login_names WHERE (instance_id = $1)", expectedStmt: "DELETE FROM projections.login_names_domains WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
},
{
expectedStmt: "DELETE FROM projections.login_names_policies WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
},
{
expectedStmt: "DELETE FROM projections.login_names_users WHERE (instance_id = $1)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
}, },

View File

@@ -543,7 +543,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(LoginPolicyInstanceIDCol), reduce: reduceInstanceRemovedHelper(LoginPolicyInstanceIDCol),

View File

@@ -82,11 +82,6 @@ func (p *mailTemplateProjection) reducers() []handler.AggregateReducer {
Event: instance.MailTemplateChangedEventType, Event: instance.MailTemplateChangedEventType,
Reduce: p.reduceChanged, Reduce: p.reduceChanged,
}, },
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
{ {
Event: instance.InstanceRemovedEventType, Event: instance.InstanceRemovedEventType,
Reduce: reduceInstanceRemovedHelper(MailTemplateInstanceIDCol), Reduce: reduceInstanceRemovedHelper(MailTemplateInstanceIDCol),

View File

@@ -120,7 +120,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(MailTemplateInstanceIDCol), reduce: reduceInstanceRemovedHelper(MailTemplateInstanceIDCol),

View File

@@ -336,7 +336,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(MessageTextInstanceIDCol), reduce: reduceInstanceRemovedHelper(MessageTextInstanceIDCol),

View File

@@ -66,11 +66,6 @@ func (p *oidcSettingsProjection) reducers() []handler.AggregateReducer {
Event: instance.OIDCSettingsChangedEventType, Event: instance.OIDCSettingsChangedEventType,
Reduce: p.reduceOIDCSettingsChanged, Reduce: p.reduceOIDCSettingsChanged,
}, },
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
{ {
Event: instance.InstanceRemovedEventType, Event: instance.InstanceRemovedEventType,
Reduce: reduceInstanceRemovedHelper(OIDCSettingsColumnInstanceID), Reduce: reduceInstanceRemovedHelper(OIDCSettingsColumnInstanceID),

View File

@@ -94,7 +94,7 @@ func TestOIDCSettingsProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(OIDCSettingsColumnInstanceID), reduce: reduceInstanceRemovedHelper(OIDCSettingsColumnInstanceID),

View File

@@ -194,7 +194,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(OrgDomainInstanceIDCol), reduce: reduceInstanceRemovedHelper(OrgDomainInstanceIDCol),

View File

@@ -208,7 +208,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(MemberInstanceID), reduce: reduceInstanceRemovedHelper(MemberInstanceID),

View File

@@ -7,6 +7,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler" "github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb" "github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org" "github.com/zitadel/zitadel/internal/repository/org"
) )
@@ -73,6 +74,15 @@ func (p *orgMetadataProjection) reducers() []handler.AggregateReducer {
}, },
}, },
}, },
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: instance.InstanceRemovedEventType,
Reduce: reduceInstanceRemovedHelper(OrgMetadataColumnInstanceID),
},
},
},
} }
} }

View File

@@ -7,6 +7,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler" "github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/repository" "github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org" "github.com/zitadel/zitadel/internal/repository/org"
) )
@@ -137,6 +138,32 @@ func TestOrgMetadataProjection_reduces(t *testing.T) {
}, },
}, },
}, },
{
name: "reduceInstanceRemoved",
args: args{
event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType,
nil,
), instance.InstanceRemovedEventMapper),
},
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_metadata WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
},
},
},
},
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {

View File

@@ -194,7 +194,7 @@ func TestOrgProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(OrgColumnInstanceID), reduce: reduceInstanceRemovedHelper(OrgColumnInstanceID),

View File

@@ -125,7 +125,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(AgePolicyInstanceIDCol), reduce: reduceInstanceRemovedHelper(AgePolicyInstanceIDCol),

View File

@@ -137,7 +137,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(ComplexityPolicyInstanceIDCol), reduce: reduceInstanceRemovedHelper(ComplexityPolicyInstanceIDCol),

View File

@@ -128,7 +128,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(PrivacyPolicyInstanceIDCol), reduce: reduceInstanceRemovedHelper(PrivacyPolicyInstanceIDCol),

View File

@@ -216,7 +216,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(MemberInstanceID), reduce: reduceInstanceRemovedHelper(MemberInstanceID),

View File

@@ -55,7 +55,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(ProjectGrantColumnInstanceID), reduce: reduceInstanceRemovedHelper(ProjectGrantColumnInstanceID),

View File

@@ -209,7 +209,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(MemberInstanceID), reduce: reduceInstanceRemovedHelper(MemberInstanceID),

View File

@@ -53,7 +53,7 @@ func TestProjectRoleProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(ProjectRoleColumnInstanceID), reduce: reduceInstanceRemovedHelper(ProjectRoleColumnInstanceID),

View File

@@ -54,7 +54,7 @@ func TestProjectProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(ProjectColumnInstanceID), reduce: reduceInstanceRemovedHelper(ProjectColumnInstanceID),

View File

@@ -76,6 +76,10 @@ func (p *secretGeneratorProjection) reducers() []handler.AggregateReducer {
Event: instance.SecretGeneratorRemovedEventType, Event: instance.SecretGeneratorRemovedEventType,
Reduce: p.reduceSecretGeneratorRemoved, Reduce: p.reduceSecretGeneratorRemoved,
}, },
{
Event: instance.InstanceRemovedEventType,
Reduce: reduceInstanceRemovedHelper(SecretGeneratorColumnInstanceID),
},
}, },
}, },
} }

View File

@@ -122,6 +122,32 @@ func TestSecretGeneratorProjection_reduces(t *testing.T) {
}, },
}, },
}, },
{
name: "reduceInstanceRemoved",
args: args{
event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType,
nil,
), instance.InstanceRemovedEventMapper),
},
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.secret_generators2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
},
},
},
},
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {

View File

@@ -271,7 +271,7 @@ func TestSMSProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(SMSColumnInstanceID), reduce: reduceInstanceRemovedHelper(SMSColumnInstanceID),

View File

@@ -151,7 +151,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(SMTPConfigColumnInstanceID), reduce: reduceInstanceRemovedHelper(SMTPConfigColumnInstanceID),

View File

@@ -244,7 +244,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(UserAuthMethodInstanceIDCol), reduce: reduceInstanceRemovedHelper(UserAuthMethodInstanceIDCol),

View File

@@ -159,7 +159,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(UserGrantInstanceID), reduce: reduceInstanceRemovedHelper(UserGrantInstanceID),

View File

@@ -144,7 +144,7 @@ func TestUserMetadataProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(UserMetadataColumnInstanceID), reduce: reduceInstanceRemovedHelper(UserMetadataColumnInstanceID),

View File

@@ -115,7 +115,7 @@ func TestPersonalAccessTokenProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(PersonalAccessTokenColumnInstanceID), reduce: reduceInstanceRemovedHelper(PersonalAccessTokenColumnInstanceID),

View File

@@ -1623,7 +1623,7 @@ func TestUserProjection_reduces(t *testing.T) {
event: getEvent(testEvent( event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType), repository.EventType(instance.InstanceRemovedEventType),
instance.AggregateType, instance.AggregateType,
[]byte(`{"name": "Name"}`), nil,
), instance.InstanceRemovedEventMapper), ), instance.InstanceRemovedEventMapper),
}, },
reduce: reduceInstanceRemovedHelper(UserInstanceIDCol), reduce: reduceInstanceRemovedHelper(UserInstanceIDCol),

View File

@@ -92,17 +92,23 @@ func InstanceChangedEventMapper(event *repository.Event) (eventstore.Event, erro
type InstanceRemovedEvent struct { type InstanceRemovedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
name string name string
domains []string
} }
func (e *InstanceRemovedEvent) Data() interface{} { func (e *InstanceRemovedEvent) Data() interface{} {
return e
}
func (e *InstanceRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil return nil
} }
func NewInstanceRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate, name string) *InstanceRemovedEvent { func (e *InstanceRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
constraints := make([]*eventstore.EventUniqueConstraint, len(e.domains)+1)
for i, domain := range e.domains {
constraints[i] = NewRemoveInstanceDomainUniqueConstraint(domain)
}
constraints[len(e.domains)] = eventstore.NewRemoveInstanceUniqueConstraints()
return constraints
}
func NewInstanceRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate, name string, domains []string) *InstanceRemovedEvent {
return &InstanceRemovedEvent{ return &InstanceRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
@@ -110,17 +116,12 @@ func NewInstanceRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregat
InstanceRemovedEventType, InstanceRemovedEventType,
), ),
name: name, name: name,
domains: domains,
} }
} }
func InstanceRemovedEventMapper(event *repository.Event) (eventstore.Event, error) { func InstanceRemovedEventMapper(event *repository.Event) (eventstore.Event, error) {
instanceRemoved := &InstanceRemovedEvent{ return &InstanceRemovedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }, nil
err := json.Unmarshal(event.Data, instanceRemoved)
if err != nil {
return nil, errors.ThrowInternal(err, "INSTANCE-39jlW", "unable to unmarshal instance removed")
}
return instanceRemoved, nil
} }

View File

@@ -180,3 +180,20 @@ func (c *crdbStorage) RemoveObjects(ctx context.Context, instanceID, resourceOwn
} }
return nil return nil
} }
func (c *crdbStorage) RemoveInstanceObjects(ctx context.Context, instanceID string) error {
stmt, args, err := squirrel.Delete(assetsTable).
Where(squirrel.Eq{
AssetColInstanceID: instanceID,
}).
PlaceholderFormat(squirrel.Dollar).
ToSql()
if err != nil {
return caos_errors.ThrowInternal(err, "DATAB-Sfgeq", "Errors.Internal")
}
_, err = c.client.ExecContext(ctx, stmt, args...)
if err != nil {
return caos_errors.ThrowInternal(err, "DATAB-Efgt2", "Errors.Assets.Object.RemoveFailed")
}
return nil
}

View File

@@ -35,6 +35,8 @@ const (
" WHERE asset_type = $1" + " WHERE asset_type = $1" +
" AND instance_id = $2" + " AND instance_id = $2" +
" AND resource_owner = $3" " AND resource_owner = $3"
removeInstanceObjectsStmt = "DELETE FROM system.assets" +
" WHERE instance_id = $1"
) )
func Test_crdbStorage_CreateObject(t *testing.T) { func Test_crdbStorage_CreateObject(t *testing.T) {
@@ -224,6 +226,50 @@ func Test_crdbStorage_RemoveObjects(t *testing.T) {
}) })
} }
} }
func Test_crdbStorage_RemoveInstanceObjects(t *testing.T) {
type fields struct {
client db
}
type args struct {
ctx context.Context
instanceID string
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
"remove ok",
fields{
client: prepareDB(t,
expectExec(
removeInstanceObjectsStmt,
nil,
"instanceID",
)),
},
args{
ctx: context.Background(),
instanceID: "instanceID",
},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &crdbStorage{
client: tt.fields.client.db,
}
err := c.RemoveInstanceObjects(tt.args.ctx, tt.args.instanceID)
if (err != nil) != tt.wantErr {
t.Errorf("RemoveInstanceObjects() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}
type db struct { type db struct {
mock sqlmock.Sqlmock mock sqlmock.Sqlmock

View File

@@ -82,6 +82,20 @@ func (mr *MockStorageMockRecorder) PutObject(ctx, instanceID, location, resource
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObject", reflect.TypeOf((*MockStorage)(nil).PutObject), ctx, instanceID, location, resourceOwner, name, contentType, objectType, object, objectSize) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObject", reflect.TypeOf((*MockStorage)(nil).PutObject), ctx, instanceID, location, resourceOwner, name, contentType, objectType, object, objectSize)
} }
// RemoveInstanceObjects mocks base method.
func (m *MockStorage) RemoveInstanceObjects(ctx context.Context, instanceID string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RemoveInstanceObjects", ctx, instanceID)
ret0, _ := ret[0].(error)
return ret0
}
// RemoveInstanceObjects indicates an expected call of RemoveInstanceObjects.
func (mr *MockStorageMockRecorder) RemoveInstanceObjects(ctx, instanceID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveInstanceObjects", reflect.TypeOf((*MockStorage)(nil).RemoveInstanceObjects), ctx, instanceID)
}
// RemoveObject mocks base method. // RemoveObject mocks base method.
func (m *MockStorage) RemoveObject(ctx context.Context, instanceID, resourceOwner, name string) error { func (m *MockStorage) RemoveObject(ctx context.Context, instanceID, resourceOwner, name string) error {
m.ctrl.T.Helper() m.ctrl.T.Helper()

View File

@@ -136,6 +136,11 @@ func (m *Minio) RemoveObjects(ctx context.Context, instanceID, resourceOwner str
return g.Wait() return g.Wait()
} }
func (m *Minio) RemoveInstanceObjects(ctx context.Context, instanceID string) error {
bucketName := m.prefixBucketName(instanceID)
return m.Client.RemoveBucket(ctx, bucketName)
}
func (m *Minio) createBucket(ctx context.Context, name, location string) error { func (m *Minio) createBucket(ctx context.Context, name, location string) error {
if location == "" { if location == "" {
location = m.Location location = m.Location

View File

@@ -15,6 +15,7 @@ type Storage interface {
GetObjectInfo(ctx context.Context, instanceID, resourceOwner, name string) (*Asset, error) GetObjectInfo(ctx context.Context, instanceID, resourceOwner, name string) (*Asset, error)
RemoveObject(ctx context.Context, instanceID, resourceOwner, name string) error RemoveObject(ctx context.Context, instanceID, resourceOwner, name string) error
RemoveObjects(ctx context.Context, instanceID, resourceOwner string, objectType ObjectType) error RemoveObjects(ctx context.Context, instanceID, resourceOwner string, objectType ObjectType) error
RemoveInstanceObjects(ctx context.Context, instanceID string) error
//TODO: add functionality to move asset location //TODO: add functionality to move asset location
} }

View File

@@ -115,3 +115,8 @@ func DeleteExternalIDPsByUserID(db *gorm.DB, table, userID, instanceID string) e
) )
return delete(db) return delete(db)
} }
func DeleteInstanceExternalIDPs(db *gorm.DB, table, instanceID string) error {
delete := repository.PrepareDeleteByKey(table, model.ExternalIDPSearchKey(usr_model.ExternalIDPSearchKeyInstanceID), instanceID)
return delete(db)
}

View File

@@ -94,3 +94,8 @@ func DeleteApplicationRefreshTokens(db *gorm.DB, table string, appIDs []string)
delete := repository.PrepareDeleteByKey(table, usr_model.RefreshTokenSearchKey(model.RefreshTokenSearchKeyApplicationID), appIDs) delete := repository.PrepareDeleteByKey(table, usr_model.RefreshTokenSearchKey(model.RefreshTokenSearchKeyApplicationID), appIDs)
return delete(db) return delete(db)
} }
func DeleteInstanceRefreshTokens(db *gorm.DB, table string, instanceID string) error {
delete := repository.PrepareDeleteByKey(table, usr_model.RefreshTokenSearchKey(model.RefreshTokenSearchKeyInstanceID), instanceID)
return delete(db)
}

View File

@@ -97,3 +97,8 @@ func DeleteApplicationTokens(db *gorm.DB, table, instanceID string, appIDs []str
) )
return delete(db) return delete(db)
} }
func DeleteInstanceTokens(db *gorm.DB, table, instanceID string) error {
delete := repository.PrepareDeleteByKey(table, usr_model.TokenSearchKey(model.TokenSearchKeyInstanceID), instanceID)
return delete(db)
}

View File

@@ -125,3 +125,8 @@ func DeleteUserSessions(db *gorm.DB, table, userID, instanceID string) error {
) )
return delete(db) return delete(db)
} }
func DeleteInstanceUserSessions(db *gorm.DB, table, instanceID string) error {
delete := repository.PrepareDeleteByKey(table, model.UserSessionSearchKey(usr_model.UserSessionSearchKeyInstanceID), instanceID)
return delete(db)
}

View File

@@ -204,3 +204,8 @@ func DeleteUser(db *gorm.DB, table, userID, instanceID string) error {
) )
return delete(db) return delete(db)
} }
func DeleteInstanceUsers(db *gorm.DB, table, instanceID string) error {
delete := repository.PrepareDeleteByKey(table, model.UserSearchKey(usr_model.UserSearchKeyInstanceID), instanceID)
return delete(db)
}