Merge branch 'main' into clean-transactional-propsal

This commit is contained in:
adlerhurst
2025-07-25 18:16:20 +02:00
987 changed files with 106221 additions and 36435 deletions

View File

@@ -20,12 +20,13 @@ import (
)
type FirstInstance struct {
InstanceName string
DefaultLanguage language.Tag
Org command.InstanceOrgSetup
MachineKeyPath string
PatPath string
Features *command.InstanceFeatures
InstanceName string
DefaultLanguage language.Tag
Org command.InstanceOrgSetup
MachineKeyPath string
PatPath string
LoginClientPatPath string
Features *command.InstanceFeatures
Skip bool
@@ -121,16 +122,18 @@ func (mig *FirstInstance) Execute(ctx context.Context, _ eventstore.Event) error
}
}
_, token, key, _, err := cmd.SetUpInstance(ctx, &mig.instanceSetup)
_, token, key, loginClientToken, _, err := cmd.SetUpInstance(ctx, &mig.instanceSetup)
if err != nil {
return err
}
if mig.instanceSetup.Org.Machine != nil &&
if (mig.instanceSetup.Org.Machine != nil &&
((mig.instanceSetup.Org.Machine.Pat != nil && token == "") ||
(mig.instanceSetup.Org.Machine.MachineKey != nil && key == nil)) {
(mig.instanceSetup.Org.Machine.MachineKey != nil && key == nil))) ||
(mig.instanceSetup.Org.LoginClient != nil &&
(mig.instanceSetup.Org.LoginClient.Pat != nil && loginClientToken == "")) {
return err
}
return mig.outputMachineAuthentication(key, token)
return mig.outputMachineAuthentication(key, token, loginClientToken)
}
func (mig *FirstInstance) verifyEncryptionKeys(ctx context.Context) (*crypto_db.Database, error) {
@@ -150,7 +153,7 @@ func (mig *FirstInstance) verifyEncryptionKeys(ctx context.Context) (*crypto_db.
return keyStorage, nil
}
func (mig *FirstInstance) outputMachineAuthentication(key *command.MachineKey, token string) error {
func (mig *FirstInstance) outputMachineAuthentication(key *command.MachineKey, token, loginClientToken string) error {
if key != nil {
keyDetails, err := key.Detail()
if err != nil {
@@ -165,6 +168,11 @@ func (mig *FirstInstance) outputMachineAuthentication(key *command.MachineKey, t
return err
}
}
if loginClientToken != "" {
if err := outputStdoutOrPath(mig.LoginClientPatPath, loginClientToken); err != nil {
return err
}
}
return nil
}

View File

@@ -2,31 +2,53 @@ package setup
import (
"context"
_ "embed"
"fmt"
"github.com/zitadel/zitadel/backend/v3/storage/database/dialect/postgres"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/instance"
)
type TransactionalTables struct {
dbClient *database.DB
type SetupWebkeys struct {
eventstore *eventstore.Eventstore
commands *command.Commands
}
func (mig *TransactionalTables) Execute(ctx context.Context, _ eventstore.Event) error {
config := &postgres.Config{Pool: mig.dbClient.Pool}
pool, err := config.Connect(ctx)
func (mig *SetupWebkeys) Execute(ctx context.Context, _ eventstore.Event) error {
instances, err := mig.eventstore.InstanceIDs(
ctx,
eventstore.NewSearchQueryBuilder(eventstore.ColumnsInstanceIDs).
OrderDesc().
AddQuery().
AggregateTypes(instance.AggregateType).
EventTypes(instance.InstanceAddedEventType).
Builder().ExcludeAggregateIDs().
AggregateTypes(instance.AggregateType).
EventTypes(instance.InstanceRemovedEventType).
Builder(),
)
if err != nil {
return err
return fmt.Errorf("%s get instance IDs: %w", mig, err)
}
conf := &crypto.WebKeyRSAConfig{
Bits: crypto.RSABits2048,
Hasher: crypto.RSAHasherSHA256,
}
return pool.Migrate(ctx)
for _, instance := range instances {
ctx := authz.WithInstanceID(ctx, instance)
logging.Info("prepare initial webkeys for instance", "instance_id", instance, "migration", mig)
if err := mig.commands.GenerateInitialWebKeys(ctx, conf); err != nil {
return fmt.Errorf("%s generate initial webkeys: %w", mig, err)
}
}
return nil
}
func (mig *TransactionalTables) String() string {
return "59_repeatable_transactional_tables"
}
func (mig *TransactionalTables) Check(lastRun map[string]interface{}) bool {
return true
func (mig *SetupWebkeys) String() string {
return "59_setup_webkeys"
}

27
cmd/setup/60.go Normal file
View File

@@ -0,0 +1,27 @@
package setup
import (
"context"
_ "embed"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/serviceping"
"github.com/zitadel/zitadel/internal/v2/system"
)
type GenerateSystemID struct {
eventstore *eventstore.Eventstore
}
func (mig *GenerateSystemID) Execute(ctx context.Context, _ eventstore.Event) error {
id, err := serviceping.GenerateSystemID()
if err != nil {
return err
}
_, err = mig.eventstore.Push(ctx, system.NewIDGeneratedEvent(ctx, id))
return err
}
func (mig *GenerateSystemID) String() string {
return "60_generate_system_id"
}

View File

@@ -155,6 +155,8 @@ type Steps struct {
s56IDPTemplate6SAMLFederatedLogout *IDPTemplate6SAMLFederatedLogout
s57CreateResourceCounts *CreateResourceCounts
s58ReplaceLoginNames3View *ReplaceLoginNames3View
s59SetupWebkeys *SetupWebkeys
s60GenerateSystemID *GenerateSystemID
}
func MustNewSteps(v *viper.Viper) *Steps {

View File

@@ -36,8 +36,6 @@ func TestMustNewConfig(t *testing.T) {
DefaultInstance:
Features:
LoginDefaultOrg: true
LegacyIntrospection: true
TriggerIntrospectionProjections: true
UserSchema: true
Log:
Level: info
@@ -47,10 +45,8 @@ Actions:
`},
want: func(t *testing.T, config *Config) {
assert.Equal(t, config.DefaultInstance.Features, &command.InstanceFeatures{
LoginDefaultOrg: gu.Ptr(true),
LegacyIntrospection: gu.Ptr(true),
TriggerIntrospectionProjections: gu.Ptr(true),
UserSchema: gu.Ptr(true),
LoginDefaultOrg: gu.Ptr(true),
UserSchema: gu.Ptr(true),
})
},
}, {

View File

@@ -217,6 +217,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
steps.s56IDPTemplate6SAMLFederatedLogout = &IDPTemplate6SAMLFederatedLogout{dbClient: dbClient}
steps.s57CreateResourceCounts = &CreateResourceCounts{dbClient: dbClient}
steps.s58ReplaceLoginNames3View = &ReplaceLoginNames3View{dbClient: dbClient}
steps.s60GenerateSystemID = &GenerateSystemID{eventstore: eventstoreClient}
err = projection.Create(ctx, dbClient, eventstoreClient, config.Projections, nil, nil, nil)
logging.OnError(err).Fatal("unable to start projections")
@@ -264,6 +265,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
steps.s56IDPTemplate6SAMLFederatedLogout,
steps.s57CreateResourceCounts,
steps.s58ReplaceLoginNames3View,
steps.s60GenerateSystemID,
} {
setupErr = executeMigration(ctx, eventstoreClient, step, "migration failed")
if setupErr != nil {
@@ -272,6 +274,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
}
commands, _, _, _ := startCommandsQueries(ctx, eventstoreClient, eventstoreV4, dbClient, masterKey, config)
steps.s59SetupWebkeys = &SetupWebkeys{eventstore: eventstoreClient, commands: commands}
repeatableSteps := []migration.RepeatableMigration{
&externalConfigChange{
@@ -324,6 +327,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
steps.s42Apps7OIDCConfigsLoginVersion,
steps.s43CreateFieldsDomainIndex,
steps.s48Apps7SAMLConfigsLoginVersion,
steps.s59SetupWebkeys, // this step needs commands.
} {
setupErr = executeMigration(ctx, eventstoreClient, step, "migration failed")
if setupErr != nil {

View File

@@ -6,6 +6,7 @@ FirstInstance:
MachineKeyPath: # ZITADEL_FIRSTINSTANCE_MACHINEKEYPATH
# The personal access token from the section FirstInstance.Org.Machine.Pat is written to the PatPath.
PatPath: # ZITADEL_FIRSTINSTANCE_PATPATH
LoginClientPatPath: # ZITADEL_FIRSTINSTANCE_LOGINCLIENTPATPATH
InstanceName: ZITADEL # ZITADEL_FIRSTINSTANCE_INSTANCENAME
DefaultLanguage: en # ZITADEL_FIRSTINSTANCE_DEFAULTLANGUAGE
Org:
@@ -46,6 +47,13 @@ FirstInstance:
Pat:
# date format: 2023-01-01T00:00:00Z
ExpirationDate: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_PAT_EXPIRATIONDATE
LoginClient:
Machine:
Username: # ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_USERNAME
Name: # ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_NAME
Pat:
# date format: 2023-01-01T00:00:00Z
ExpirationDate: # ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_PAT_EXPIRATIONDATE
CorrectCreationDate:
FailAfter: 5m # ZITADEL_CORRECTCREATIONDATE_FAILAFTER

View File

@@ -0,0 +1,32 @@
package setup
import (
"context"
_ "embed"
"github.com/zitadel/zitadel/backend/v3/storage/database/dialect/postgres"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
)
type TransactionalTables struct {
dbClient *database.DB
}
func (mig *TransactionalTables) Execute(ctx context.Context, _ eventstore.Event) error {
config := &postgres.Config{Pool: mig.dbClient.Pool}
pool, err := config.Connect(ctx)
if err != nil {
return err
}
return pool.Migrate(ctx)
}
func (mig *TransactionalTables) String() string {
return "repeatable_transactional_tables"
}
func (mig *TransactionalTables) Check(lastRun map[string]interface{}) bool {
return true
}