feat: projections auto create their tables (#3324)

* begin init checks for projections

* first projection checks

* debug notification providers with query fixes

* more projections and first index

* more projections

* more projections

* finish projections

* fix tests (remove db name)

* create tables in setup

* fix logging / error handling

* add tenant to views

* rename tenant to instance_id

* add instance_id to all projections

* add instance_id to all queries

* correct instance_id on projections

* add instance_id to failed_events

* use separate context for instance

* implement features projection

* implement features projection

* remove unique constraint from setup when migration failed

* add error to failed setup event

* add instance_id to primary keys

* fix IAM projection

* remove old migrations folder

* fix keysFromYAML test
This commit is contained in:
Livio Amstutz
2022-03-23 09:02:39 +01:00
committed by GitHub
parent 9e13b70a3d
commit 56b916a2b0
400 changed files with 6508 additions and 8890 deletions

View File

@@ -3,7 +3,6 @@ package projection
import (
"context"
"github.com/caos/logging"
"github.com/lib/pq"
"github.com/caos/zitadel/internal/domain"
@@ -16,18 +15,50 @@ import (
"github.com/caos/zitadel/internal/repository/usergrant"
)
const (
UserGrantProjectionTable = "projections.user_grants"
UserGrantID = "id"
UserGrantCreationDate = "creation_date"
UserGrantChangeDate = "change_date"
UserGrantSequence = "sequence"
UserGrantState = "state"
UserGrantResourceOwner = "resource_owner"
UserGrantInstanceID = "instance_id"
UserGrantUserID = "user_id"
UserGrantProjectID = "project_id"
UserGrantGrantID = "grant_id"
UserGrantRoles = "roles"
)
type UserGrantProjection struct {
crdb.StatementHandler
}
const (
UserGrantProjectionTable = "zitadel.projections.user_grants"
)
func NewUserGrantProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserGrantProjection {
p := new(UserGrantProjection)
config.ProjectionName = UserGrantProjectionTable
config.Reducers = p.reducers()
config.InitCheck = crdb.NewTableCheck(
crdb.NewTable([]*crdb.Column{
crdb.NewColumn(UserGrantID, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantCreationDate, crdb.ColumnTypeTimestamp),
crdb.NewColumn(UserGrantChangeDate, crdb.ColumnTypeTimestamp),
crdb.NewColumn(UserGrantSequence, crdb.ColumnTypeInt64),
crdb.NewColumn(UserGrantState, crdb.ColumnTypeEnum),
crdb.NewColumn(UserGrantResourceOwner, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantInstanceID, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantUserID, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantProjectID, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantGrantID, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantRoles, crdb.ColumnTypeTextArray, crdb.Nullable()),
},
crdb.NewPrimaryKey(UserGrantInstanceID, UserGrantID),
crdb.NewIndex("user_idx", []string{UserGrantUserID}),
crdb.NewIndex("ro_idx", []string{UserGrantResourceOwner}),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
return p
}
@@ -104,32 +135,17 @@ func (p *UserGrantProjection) reducers() []handler.AggregateReducer {
}
}
type UserGrantColumn string
const (
UserGrantID = "id"
UserGrantResourceOwner = "resource_owner"
UserGrantCreationDate = "creation_date"
UserGrantChangeDate = "change_date"
UserGrantSequence = "sequence"
UserGrantUserID = "user_id"
UserGrantProjectID = "project_id"
UserGrantGrantID = "grant_id"
UserGrantRoles = "roles"
UserGrantState = "state"
)
func (p *UserGrantProjection) reduceAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*usergrant.UserGrantAddedEvent)
if !ok {
logging.LogWithFields("PROJE-WYOHD", "seq", event.Sequence(), "expectedType", usergrant.UserGrantAddedType).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "PROJE-MQHVB", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-MQHVB", "reduce.wrong.event.type %s", usergrant.UserGrantAddedType)
}
return crdb.NewCreateStatement(
e,
[]handler.Column{
handler.NewCol(UserGrantID, e.Aggregate().ID),
handler.NewCol(UserGrantResourceOwner, e.Aggregate().ResourceOwner),
handler.NewCol(UserGrantInstanceID, e.Aggregate().InstanceID),
handler.NewCol(UserGrantCreationDate, e.CreationDate()),
handler.NewCol(UserGrantChangeDate, e.CreationDate()),
handler.NewCol(UserGrantSequence, e.Sequence()),
@@ -151,8 +167,7 @@ func (p *UserGrantProjection) reduceChanged(event eventstore.Event) (*handler.St
case *usergrant.UserGrantCascadeChangedEvent:
roles = e.RoleKeys
default:
logging.LogWithFields("PROJE-dIflx", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{usergrant.UserGrantChangedType, usergrant.UserGrantCascadeChangedType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "PROJE-hOr1E", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-hOr1E", "reduce.wrong.event.type %v", []eventstore.EventType{usergrant.UserGrantChangedType, usergrant.UserGrantCascadeChangedType})
}
return crdb.NewUpdateStatement(
@@ -173,8 +188,7 @@ func (p *UserGrantProjection) reduceRemoved(event eventstore.Event) (*handler.St
case *usergrant.UserGrantRemovedEvent, *usergrant.UserGrantCascadeRemovedEvent:
// ok
default:
logging.LogWithFields("PROJE-Nw0cR", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{usergrant.UserGrantRemovedType, usergrant.UserGrantCascadeRemovedType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "PROJE-7OBEC", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-7OBEC", "reduce.wrong.event.type %v", []eventstore.EventType{usergrant.UserGrantRemovedType, usergrant.UserGrantCascadeRemovedType})
}
return crdb.NewDeleteStatement(
@@ -187,8 +201,7 @@ func (p *UserGrantProjection) reduceRemoved(event eventstore.Event) (*handler.St
func (p *UserGrantProjection) reduceDeactivated(event eventstore.Event) (*handler.Statement, error) {
if _, ok := event.(*usergrant.UserGrantDeactivatedEvent); !ok {
logging.LogWithFields("PROJE-V3txf", "seq", event.Sequence(), "expectedType", usergrant.UserGrantDeactivatedType).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "PROJE-oP7Gm", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-oP7Gm", "reduce.wrong.event.type %s", usergrant.UserGrantDeactivatedType)
}
return crdb.NewUpdateStatement(
@@ -206,8 +219,7 @@ func (p *UserGrantProjection) reduceDeactivated(event eventstore.Event) (*handle
func (p *UserGrantProjection) reduceReactivated(event eventstore.Event) (*handler.Statement, error) {
if _, ok := event.(*usergrant.UserGrantDeactivatedEvent); !ok {
logging.LogWithFields("PROJE-ly6oe", "seq", event.Sequence(), "expectedType", usergrant.UserGrantReactivatedType).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "PROJE-DGsKh", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-DGsKh", "reduce.wrong.event.type %s", usergrant.UserGrantReactivatedType)
}
return crdb.NewUpdateStatement(
@@ -225,8 +237,7 @@ func (p *UserGrantProjection) reduceReactivated(event eventstore.Event) (*handle
func (p *UserGrantProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) {
if _, ok := event.(*user.UserRemovedEvent); !ok {
logging.LogWithFields("PROJE-Vfeg3", "seq", event.Sequence(), "expectedType", user.UserRemovedType).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "PROJE-Bner2a", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Bner2a", "reduce.wrong.event.type %s", user.UserRemovedType)
}
return crdb.NewDeleteStatement(
@@ -239,8 +250,7 @@ func (p *UserGrantProjection) reduceUserRemoved(event eventstore.Event) (*handle
func (p *UserGrantProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) {
if _, ok := event.(*project.ProjectRemovedEvent); !ok {
logging.LogWithFields("PROJE-Vfeg3", "seq", event.Sequence(), "expectedType", project.ProjectRemovedType).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "PROJE-Bne2a", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Bne2a", "reduce.wrong.event.type %s", project.ProjectRemovedType)
}
return crdb.NewDeleteStatement(
@@ -254,8 +264,7 @@ func (p *UserGrantProjection) reduceProjectRemoved(event eventstore.Event) (*han
func (p *UserGrantProjection) reduceProjectGrantRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.GrantRemovedEvent)
if !ok {
logging.LogWithFields("PROJE-DGfe2", "seq", event.Sequence(), "expectedType", project.GrantRemovedType).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "PROJE-dGr2a", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-dGr2a", "reduce.wrong.event.type %s", project.GrantRemovedType)
}
return crdb.NewDeleteStatement(
@@ -269,8 +278,7 @@ func (p *UserGrantProjection) reduceProjectGrantRemoved(event eventstore.Event)
func (p *UserGrantProjection) reduceRoleRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.RoleRemovedEvent)
if !ok {
logging.LogWithFields("PROJE-Edg22", "seq", event.Sequence(), "expectedType", project.RoleRemovedType).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "PROJE-dswg2", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-dswg2", "reduce.wrong.event.type %s", project.RoleRemovedType)
}
return crdb.NewUpdateStatement(
@@ -295,8 +303,7 @@ func (p *UserGrantProjection) reduceProjectGrantChanged(event eventstore.Event)
grantID = e.GrantID
keys = e.RoleKeys
default:
logging.LogWithFields("PROJE-FGgw2", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{project.GrantChangedType, project.GrantCascadeChangedType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "PROJE-Fh3gw", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Fh3gw", "reduce.wrong.event.type %v", []eventstore.EventType{project.GrantChangedType, project.GrantCascadeChangedType})
}
return crdb.NewUpdateStatement(