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,8 @@ package projection
import (
"context"
"github.com/caos/logging"
"github.com/lib/pq"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore"
@@ -12,23 +13,97 @@ import (
"github.com/caos/zitadel/internal/repository/iam"
"github.com/caos/zitadel/internal/repository/idpconfig"
"github.com/caos/zitadel/internal/repository/org"
"github.com/lib/pq"
)
const (
IDPTable = "projections.idps"
IDPOIDCTable = IDPTable + "_" + IDPOIDCSuffix
IDPJWTTable = IDPTable + "_" + IDPJWTSuffix
IDPOIDCSuffix = "oidc_config"
IDPJWTSuffix = "jwt_config"
IDPIDCol = "id"
IDPCreationDateCol = "creation_date"
IDPChangeDateCol = "change_date"
IDPSequenceCol = "sequence"
IDPResourceOwnerCol = "resource_owner"
IDPInstanceIDCol = "instance_id"
IDPStateCol = "state"
IDPNameCol = "name"
IDPStylingTypeCol = "styling_type"
IDPOwnerTypeCol = "owner_type"
IDPAutoRegisterCol = "auto_register"
IDPTypeCol = "type"
OIDCConfigIDPIDCol = "idp_id"
OIDCConfigClientIDCol = "client_id"
OIDCConfigClientSecretCol = "client_secret"
OIDCConfigIssuerCol = "issuer"
OIDCConfigScopesCol = "scopes"
OIDCConfigDisplayNameMappingCol = "display_name_mapping"
OIDCConfigUsernameMappingCol = "username_mapping"
OIDCConfigAuthorizationEndpointCol = "authorization_endpoint"
OIDCConfigTokenEndpointCol = "token_endpoint"
JWTConfigIDPIDCol = "idp_id"
JWTConfigIssuerCol = "issuer"
JWTConfigKeysEndpointCol = "keys_endpoint"
JWTConfigHeaderNameCol = "header_name"
JWTConfigEndpointCol = "endpoint"
)
type IDPProjection struct {
crdb.StatementHandler
}
const (
IDPTable = "zitadel.projections.idps"
IDPOIDCTable = IDPTable + "_" + IDPOIDCSuffix
IDPJWTTable = IDPTable + "_" + IDPJWTSuffix
)
func NewIDPProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IDPProjection {
p := new(IDPProjection)
config.ProjectionName = IDPTable
config.Reducers = p.reducers()
config.InitCheck = crdb.NewMultiTableCheck(
crdb.NewTable([]*crdb.Column{
crdb.NewColumn(IDPIDCol, crdb.ColumnTypeText),
crdb.NewColumn(IDPCreationDateCol, crdb.ColumnTypeTimestamp),
crdb.NewColumn(IDPChangeDateCol, crdb.ColumnTypeTimestamp),
crdb.NewColumn(IDPSequenceCol, crdb.ColumnTypeInt64),
crdb.NewColumn(IDPResourceOwnerCol, crdb.ColumnTypeText),
crdb.NewColumn(IDPInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(IDPStateCol, crdb.ColumnTypeEnum),
crdb.NewColumn(IDPNameCol, crdb.ColumnTypeText),
crdb.NewColumn(IDPStylingTypeCol, crdb.ColumnTypeEnum),
crdb.NewColumn(IDPOwnerTypeCol, crdb.ColumnTypeEnum),
crdb.NewColumn(IDPAutoRegisterCol, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(IDPTypeCol, crdb.ColumnTypeEnum),
},
crdb.NewPrimaryKey(IDPInstanceIDCol, IDPIDCol),
crdb.NewIndex("ro_idx", []string{IDPResourceOwnerCol}),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(OIDCConfigIDPIDCol, crdb.ColumnTypeText, crdb.DeleteCascade(IDPIDCol)),
crdb.NewColumn(OIDCConfigClientIDCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(OIDCConfigClientSecretCol, crdb.ColumnTypeJSONB, crdb.Nullable()),
crdb.NewColumn(OIDCConfigIssuerCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(OIDCConfigScopesCol, crdb.ColumnTypeTextArray, crdb.Nullable()),
crdb.NewColumn(OIDCConfigDisplayNameMappingCol, crdb.ColumnTypeEnum, crdb.Nullable()),
crdb.NewColumn(OIDCConfigUsernameMappingCol, crdb.ColumnTypeEnum, crdb.Nullable()),
crdb.NewColumn(OIDCConfigAuthorizationEndpointCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(OIDCConfigTokenEndpointCol, crdb.ColumnTypeEnum, crdb.Nullable()),
},
crdb.NewPrimaryKey(OIDCConfigIDPIDCol),
IDPOIDCSuffix,
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(JWTConfigIDPIDCol, crdb.ColumnTypeText, crdb.DeleteCascade(IDPIDCol)),
crdb.NewColumn(JWTConfigIssuerCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(JWTConfigKeysEndpointCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(JWTConfigHeaderNameCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(JWTConfigEndpointCol, crdb.ColumnTypeText, crdb.Nullable()),
},
crdb.NewPrimaryKey(JWTConfigIDPIDCol),
IDPJWTSuffix,
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
return p
}
@@ -120,39 +195,6 @@ func (p *IDPProjection) reducers() []handler.AggregateReducer {
}
}
const (
IDPOIDCSuffix = "oidc_config"
IDPJWTSuffix = "jwt_config"
IDPIDCol = "id"
IDPCreationDateCol = "creation_date"
IDPChangeDateCol = "change_date"
IDPSequenceCol = "sequence"
IDPResourceOwnerCol = "resource_owner"
IDPStateCol = "state"
IDPNameCol = "name"
IDPStylingTypeCol = "styling_type"
IDPOwnerTypeCol = "owner_type"
IDPAutoRegisterCol = "auto_register"
IDPTypeCol = "type"
OIDCConfigIDPIDCol = "idp_id"
OIDCConfigClientIDCol = "client_id"
OIDCConfigClientSecretCol = "client_secret"
OIDCConfigIssuerCol = "issuer"
OIDCConfigScopesCol = "scopes"
OIDCConfigDisplayNameMappingCol = "display_name_mapping"
OIDCConfigUsernameMappingCol = "username_mapping"
OIDCConfigAuthorizationEndpointCol = "authorization_endpoint"
OIDCConfigTokenEndpointCol = "token_endpoint"
JWTConfigIDPIDCol = "idp_id"
JWTConfigIssuerCol = "issuer"
JWTConfigKeysEndpointCol = "keys_endpoint"
JWTConfigHeaderNameCol = "header_name"
JWTConfigEndpointCol = "endpoint"
)
func (p *IDPProjection) reduceIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var idpEvent idpconfig.IDPConfigAddedEvent
var idpOwnerType domain.IdentityProviderType
@@ -164,8 +206,7 @@ func (p *IDPProjection) reduceIDPAdded(event eventstore.Event) (*handler.Stateme
idpEvent = e.IDPConfigAddedEvent
idpOwnerType = domain.IdentityProviderTypeSystem
default:
logging.LogWithFields("HANDL-hBriG", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigAddedEventType, iam.IDPConfigAddedEventType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "HANDL-fcUdQ", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-fcUdQ", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigAddedEventType, iam.IDPConfigAddedEventType})
}
return crdb.NewCreateStatement(
@@ -176,6 +217,7 @@ func (p *IDPProjection) reduceIDPAdded(event eventstore.Event) (*handler.Stateme
handler.NewCol(IDPChangeDateCol, idpEvent.CreationDate()),
handler.NewCol(IDPSequenceCol, idpEvent.Sequence()),
handler.NewCol(IDPResourceOwnerCol, idpEvent.Aggregate().ResourceOwner),
handler.NewCol(IDPInstanceIDCol, idpEvent.Aggregate().InstanceID),
handler.NewCol(IDPStateCol, domain.IDPConfigStateActive),
handler.NewCol(IDPNameCol, idpEvent.Name),
handler.NewCol(IDPStylingTypeCol, idpEvent.StylingType),
@@ -193,8 +235,7 @@ func (p *IDPProjection) reduceIDPChanged(event eventstore.Event) (*handler.State
case *iam.IDPConfigChangedEvent:
idpEvent = e.IDPConfigChangedEvent
default:
logging.LogWithFields("HANDL-FFrph", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigChangedEventType, iam.IDPConfigChangedEventType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "HANDL-NVvJD", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-NVvJD", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigChangedEventType, iam.IDPConfigChangedEventType})
}
cols := make([]handler.Column, 0, 5)
@@ -233,8 +274,7 @@ func (p *IDPProjection) reduceIDPDeactivated(event eventstore.Event) (*handler.S
case *iam.IDPConfigDeactivatedEvent:
idpEvent = e.IDPConfigDeactivatedEvent
default:
logging.LogWithFields("HANDL-1s33a", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigDeactivatedEventType, iam.IDPConfigDeactivatedEventType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "HANDL-94O5l", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-94O5l", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigDeactivatedEventType, iam.IDPConfigDeactivatedEventType})
}
return crdb.NewUpdateStatement(
@@ -258,8 +298,7 @@ func (p *IDPProjection) reduceIDPReactivated(event eventstore.Event) (*handler.S
case *iam.IDPConfigReactivatedEvent:
idpEvent = e.IDPConfigReactivatedEvent
default:
logging.LogWithFields("HANDL-Zgzpt", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigReactivatedEventType, iam.IDPConfigReactivatedEventType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "HANDL-I8QyS", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-I8QyS", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigReactivatedEventType, iam.IDPConfigReactivatedEventType})
}
return crdb.NewUpdateStatement(
@@ -283,8 +322,7 @@ func (p *IDPProjection) reduceIDPRemoved(event eventstore.Event) (*handler.State
case *iam.IDPConfigRemovedEvent:
idpEvent = e.IDPConfigRemovedEvent
default:
logging.LogWithFields("HANDL-JJasT", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigRemovedEventType, iam.IDPConfigRemovedEventType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "HANDL-B4zy8", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-B4zy8", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigRemovedEventType, iam.IDPConfigRemovedEventType})
}
return crdb.NewDeleteStatement(
@@ -303,8 +341,7 @@ func (p *IDPProjection) reduceOIDCConfigAdded(event eventstore.Event) (*handler.
case *iam.IDPOIDCConfigAddedEvent:
idpEvent = e.OIDCConfigAddedEvent
default:
logging.LogWithFields("HANDL-DCmeB", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPOIDCConfigAddedEventType, iam.IDPOIDCConfigAddedEventType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "HANDL-2FuAA", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-2FuAA", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPOIDCConfigAddedEventType, iam.IDPOIDCConfigAddedEventType})
}
return crdb.NewMultiStatement(&idpEvent,
@@ -343,8 +380,7 @@ func (p *IDPProjection) reduceOIDCConfigChanged(event eventstore.Event) (*handle
case *iam.IDPOIDCConfigChangedEvent:
idpEvent = e.OIDCConfigChangedEvent
default:
logging.LogWithFields("HANDL-VyBm2", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPOIDCConfigChangedEventType, iam.IDPOIDCConfigChangedEventType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "HANDL-x2IVI", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-x2IVI", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPOIDCConfigChangedEventType, iam.IDPOIDCConfigChangedEventType})
}
cols := make([]handler.Column, 0, 8)
@@ -406,8 +442,7 @@ func (p *IDPProjection) reduceJWTConfigAdded(event eventstore.Event) (*handler.S
case *iam.IDPJWTConfigAddedEvent:
idpEvent = e.JWTConfigAddedEvent
default:
logging.LogWithFields("HANDL-228q7", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPJWTConfigAddedEventType, iam.IDPJWTConfigAddedEventType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "HANDL-qvPdb", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-qvPdb", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPJWTConfigAddedEventType, iam.IDPJWTConfigAddedEventType})
}
return crdb.NewMultiStatement(&idpEvent,
@@ -443,8 +478,7 @@ func (p *IDPProjection) reduceJWTConfigChanged(event eventstore.Event) (*handler
case *iam.IDPJWTConfigChangedEvent:
idpEvent = e.JWTConfigChangedEvent
default:
logging.LogWithFields("HANDL-VyBm2", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPJWTConfigChangedEventType, iam.IDPJWTConfigChangedEventType}).Error("wrong event type")
return nil, errors.ThrowInvalidArgument(nil, "HANDL-x2IVI", "reduce.wrong.event.type")
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-x2IVI", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPJWTConfigChangedEventType, iam.IDPJWTConfigChangedEventType})
}
cols := make([]handler.Column, 0, 4)