mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-06 13:57:41 +00:00
feat: setup as separate command (#604)
* feat: separate setup from startup * health * move setup config * add env vars to caos_local.sh * fix domain and set devMode explicit
This commit is contained in:
parent
1a00faf132
commit
8830896199
@ -65,4 +65,9 @@ export ZITADEL_CONSOLE_ENV_DIR=../../console/src/assets/
|
||||
export ZITADEL_DEFAULT_DOMAIN=zitadel.ch
|
||||
|
||||
#Tracing
|
||||
export TRACING_TYPE=google
|
||||
export TRACING_TYPE=google
|
||||
|
||||
#Setup
|
||||
export ZITADEL_CONSOLE_RESPONSE_TYPE=ID_TOKEN TOKEN
|
||||
export ZITADEL_CONSOLE_GRANT_TYPE=IMPLICIT
|
||||
export ZITADEL_CONSOLE_DEV_MODE=true
|
@ -18,8 +18,10 @@ import (
|
||||
authz_repo "github.com/caos/zitadel/internal/authz/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/config"
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
mgmt_es "github.com/caos/zitadel/internal/management/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/notification"
|
||||
"github.com/caos/zitadel/internal/setup"
|
||||
tracing "github.com/caos/zitadel/internal/tracing/config"
|
||||
"github.com/caos/zitadel/internal/ui"
|
||||
"github.com/caos/zitadel/internal/ui/console"
|
||||
@ -43,8 +45,17 @@ type Config struct {
|
||||
Notification notification.Config
|
||||
}
|
||||
|
||||
type setupConfig struct {
|
||||
Log logging.Config
|
||||
|
||||
Eventstore es_int.Config
|
||||
SystemDefaults sd.SystemDefaults
|
||||
SetUp setup.IAMSetUp
|
||||
}
|
||||
|
||||
var (
|
||||
configPaths = config.NewArrayFlags("authz.yaml", "startup.yaml", "system-defaults.yaml")
|
||||
setupPaths = config.NewArrayFlags("system-defaults.yaml", "setup.yaml")
|
||||
adminEnabled = flag.Bool("admin", true, "enable admin api")
|
||||
managementEnabled = flag.Bool("management", true, "enable management api")
|
||||
authEnabled = flag.Bool("auth", true, "enable auth api")
|
||||
@ -55,12 +66,29 @@ var (
|
||||
localDevMode = flag.Bool("localDevMode", false, "enable local development specific configs")
|
||||
)
|
||||
|
||||
const (
|
||||
cmdStart = "start"
|
||||
cmdSetup = "setup"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Var(configPaths, "config-files", "paths to the config files")
|
||||
flag.Var(configPaths, "setup-files", "paths to the setup files")
|
||||
flag.Parse()
|
||||
arg := flag.Arg(0)
|
||||
switch arg {
|
||||
case cmdStart:
|
||||
startZitadel(configPaths.Values())
|
||||
case cmdSetup:
|
||||
startSetup(setupPaths.Values(), *localDevMode)
|
||||
default:
|
||||
logging.Log("MAIN-afEQ2").Fatal("please provide an valid argument [start, setup]")
|
||||
}
|
||||
}
|
||||
|
||||
func startZitadel(configPaths []string) {
|
||||
conf := new(Config)
|
||||
err := config.Read(conf, configPaths.Values()...)
|
||||
err := config.Read(conf, configPaths...)
|
||||
logging.Log("MAIN-FaF2r").OnError(err).Fatal("cannot read config")
|
||||
|
||||
ctx := context.Background()
|
||||
@ -125,3 +153,16 @@ func startAPI(ctx context.Context, conf *Config, authZRepo *authz_repo.EsReposit
|
||||
}
|
||||
apis.Start(ctx)
|
||||
}
|
||||
|
||||
func startSetup(configPaths []string, localDevMode bool) {
|
||||
conf := new(setupConfig)
|
||||
err := config.Read(conf, configPaths...)
|
||||
logging.Log("MAIN-FaF2r").OnError(err).Fatal("cannot read config")
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
setup, err := setup.StartSetup(conf.Eventstore, conf.SystemDefaults)
|
||||
logging.Log("SERVE-fD252").OnError(err).Panic("failed to start setup")
|
||||
err = setup.Execute(ctx, conf.SetUp)
|
||||
logging.Log("SERVE-djs3R").OnError(err).Panic("failed to execute setup")
|
||||
}
|
||||
|
70
cmd/zitadel/setup.yaml
Normal file
70
cmd/zitadel/setup.yaml
Normal file
@ -0,0 +1,70 @@
|
||||
Log:
|
||||
Level: $ZITADEL_LOG_LEVEL
|
||||
Formatter:
|
||||
Format: text
|
||||
|
||||
Eventstore:
|
||||
ServiceName: 'Admin'
|
||||
Repository:
|
||||
SQL:
|
||||
Host: $ZITADEL_EVENTSTORE_HOST
|
||||
Port: $ZITADEL_EVENTSTORE_PORT
|
||||
User: 'adminapi'
|
||||
Database: 'eventstore'
|
||||
Password: $CR_ADMINAPI_PASSWORD
|
||||
SSL:
|
||||
Mode: $CR_SSL_MODE
|
||||
RootCert: $CR_ROOT_CERT
|
||||
Cert: $CR_ADMINAPI_CERT
|
||||
Key: $CR_ADMINAPI_KEY
|
||||
Cache:
|
||||
Type: 'fastcache'
|
||||
Config:
|
||||
MaxCacheSizeInByte: 10485760 #10mb
|
||||
|
||||
SetUp:
|
||||
GlobalOrg: 'Global'
|
||||
IAMProject: 'Zitadel'
|
||||
Orgs:
|
||||
- Name: 'Global'
|
||||
Domain: 'global.caos.ch'
|
||||
Default: true
|
||||
OrgIamPolicy: true
|
||||
Users:
|
||||
- FirstName: 'Global Org'
|
||||
LastName: 'Administrator'
|
||||
UserName: 'zitadel-global-org-admin@caos.ch'
|
||||
Email: 'zitadel-global-org-admin@caos.ch'
|
||||
Password: 'Password1!'
|
||||
Owners:
|
||||
- 'zitadel-global-org-admin@caos.ch'
|
||||
- Name: 'CAOS AG'
|
||||
Domain: 'caos.ch'
|
||||
Users:
|
||||
- FirstName: 'Zitadel'
|
||||
LastName: 'Administrator'
|
||||
UserName: 'zitadel-admin'
|
||||
Email: 'zitadel-admin@caos.ch'
|
||||
Password: 'Password1!'
|
||||
Owners:
|
||||
- 'zitadel-admin@caos.ch'
|
||||
Projects:
|
||||
- Name: 'Zitadel'
|
||||
OIDCApps:
|
||||
- Name: 'Management-API'
|
||||
- Name: 'Auth-API'
|
||||
- Name: 'Admin-API'
|
||||
- Name: 'Zitadel Console'
|
||||
RedirectUris:
|
||||
- '$ZITADEL_CONSOLE/auth/callback'
|
||||
PostLogoutRedirectUris:
|
||||
- '$ZITADEL_CONSOLE/signedout'
|
||||
ResponseTypes:
|
||||
- '$ZITADEL_CONSOLE_RESPONSE_TYPE'
|
||||
GrantTypes:
|
||||
- '$ZITADEL_CONSOLE_GRANT_TYPE'
|
||||
ApplicationType: 'USER_AGENT'
|
||||
AuthMethodType: 'NONE'
|
||||
DevMode: '$ZITADEL_CONSOLE_DEV_MODE'
|
||||
Owners:
|
||||
- 'zitadel-admin@caos.ch'
|
@ -1,6 +1,6 @@
|
||||
SystemDefaults:
|
||||
DefaultLanguage: 'de'
|
||||
DefaultDomain: $ZITADEL_DEFAULT_DOMAIN
|
||||
Domain: $ZITADEL_DEFAULT_DOMAIN
|
||||
ZitadelDocs:
|
||||
Issuer: $ZITADEL_ISSUER
|
||||
DiscoveryEndpoint: '$ZITADEL_ISSUER/.well-known/openid-configuration'
|
||||
@ -81,51 +81,6 @@ SystemDefaults:
|
||||
IncludeUpperLetters: true
|
||||
IncludeDigits: true
|
||||
IncludeSymbols: false
|
||||
SetUp:
|
||||
GlobalOrg: 'Global'
|
||||
IAMProject: 'Zitadel'
|
||||
Orgs:
|
||||
- Name: 'Global'
|
||||
Domain: 'global.caos.ch'
|
||||
Default: true
|
||||
OrgIamPolicy: true
|
||||
Users:
|
||||
- FirstName: 'Global Org'
|
||||
LastName: 'Administrator'
|
||||
UserName: 'zitadel-global-org-admin@caos.ch'
|
||||
Email: 'zitadel-global-org-admin@caos.ch'
|
||||
Password: 'Password1!'
|
||||
Owners:
|
||||
- 'zitadel-global-org-admin@caos.ch'
|
||||
- Name: 'CAOS AG'
|
||||
Domain: 'caos.ch'
|
||||
Users:
|
||||
- FirstName: 'Zitadel'
|
||||
LastName: 'Administrator'
|
||||
UserName: 'zitadel-admin'
|
||||
Email: 'zitadel-admin@caos.ch'
|
||||
Password: 'Password1!'
|
||||
Owners:
|
||||
- 'zitadel-admin@caos.ch'
|
||||
Projects:
|
||||
- Name: 'Zitadel'
|
||||
OIDCApps:
|
||||
- Name: 'Management-API'
|
||||
- Name: 'Auth-API'
|
||||
- Name: 'Admin-API'
|
||||
- Name: 'Zitadel Console'
|
||||
RedirectUris:
|
||||
- '$ZITADEL_CONSOLE/auth/callback'
|
||||
PostLogoutRedirectUris:
|
||||
- '$ZITADEL_CONSOLE/signedout'
|
||||
ResponseTypes:
|
||||
- 'CODE'
|
||||
GrantTypes:
|
||||
- 'AUTHORIZATION_CODE'
|
||||
ApplicationType: 'NATIVE'
|
||||
AuthMethodType: 'AUTH_TYPE_NONE'
|
||||
Owners:
|
||||
- 'zitadel-admin@caos.ch'
|
||||
Notifications:
|
||||
DebugMode: $DEBUG_MODE
|
||||
Endpoints:
|
||||
|
@ -2,12 +2,9 @@ package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/handler"
|
||||
es_policy "github.com/caos/zitadel/internal/policy/repository/eventsourcing"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/eventstore"
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/setup"
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/handler"
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/spooler"
|
||||
admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view"
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
@ -16,7 +13,7 @@ import (
|
||||
es_spol "github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
es_policy "github.com/caos/zitadel/internal/policy/repository/eventsourcing"
|
||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
@ -51,14 +48,6 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
|
||||
|
||||
org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults)
|
||||
|
||||
project, err := es_proj.StartProject(es_proj.ProjectConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
}, systemDefaults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user, err := es_usr.StartUser(es_usr.UserConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
@ -82,10 +71,6 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
|
||||
return nil, err
|
||||
}
|
||||
|
||||
eventstoreRepos := setup.EventstoreRepos{OrgEvents: org, UserEvents: user, ProjectEvents: project, IamEvents: iam, PolicyEvents: policy}
|
||||
err = setup.StartSetup(systemDefaults, eventstoreRepos).Execute(ctx)
|
||||
logging.Log("SERVE-djs3R").OnError(err).Panic("failed to execute setup")
|
||||
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, handler.EventstoreRepos{UserEvents: user, OrgEvents: org})
|
||||
|
||||
return &EsRepository{
|
||||
|
@ -4,14 +4,18 @@ import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
grpc_util "github.com/caos/zitadel/internal/api/grpc"
|
||||
"github.com/caos/zitadel/internal/api/grpc/server"
|
||||
http_util "github.com/caos/zitadel/internal/api/http"
|
||||
"github.com/caos/zitadel/internal/api/oidc"
|
||||
authz_es "github.com/caos/zitadel/internal/authz/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -24,6 +28,12 @@ type API struct {
|
||||
gatewayHandler *server.GatewayHandler
|
||||
verifier *authz.TokenVerifier
|
||||
serverPort string
|
||||
health health
|
||||
}
|
||||
type health interface {
|
||||
Health(ctx context.Context) error
|
||||
IamByID(ctx context.Context) (*iam_model.Iam, error)
|
||||
VerifierClientID(ctx context.Context, appName string) (string, error)
|
||||
}
|
||||
|
||||
func Create(config Config, authZ authz.Config, authZRepo *authz_es.EsRepository, sd systemdefaults.SystemDefaults) *API {
|
||||
@ -31,8 +41,10 @@ func Create(config Config, authZ authz.Config, authZRepo *authz_es.EsRepository,
|
||||
serverPort: config.GRPC.ServerPort,
|
||||
}
|
||||
api.verifier = authz.Start(authZRepo)
|
||||
api.health = authZRepo
|
||||
api.grpcServer = server.CreateServer(api.verifier, authZ, sd.DefaultLanguage)
|
||||
api.gatewayHandler = server.CreateGatewayHandler(config.GRPC)
|
||||
api.RegisterHandler("", api.healthHandler())
|
||||
|
||||
return api
|
||||
}
|
||||
@ -51,3 +63,70 @@ func (a *API) Start(ctx context.Context) {
|
||||
server.Serve(ctx, a.grpcServer, a.serverPort)
|
||||
a.gatewayHandler.Serve(ctx)
|
||||
}
|
||||
|
||||
func (a *API) healthHandler() http.Handler {
|
||||
checks := []ValidationFunction{
|
||||
func(ctx context.Context) error {
|
||||
if err := a.health.Health(ctx); err != nil {
|
||||
return errors.ThrowInternal(err, "API-F24h2", "DB CONNECTION ERROR")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
func(ctx context.Context) error {
|
||||
iam, err := a.health.IamByID(ctx)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return errors.ThrowPreconditionFailed(err, "API-dsgT2", "IAM SETUP CHECK FAILED")
|
||||
}
|
||||
if iam == nil || !iam.SetUpStarted {
|
||||
return errors.ThrowPreconditionFailed(nil, "API-HBfs3", "IAM NOT SET UP")
|
||||
}
|
||||
if !iam.SetUpDone {
|
||||
return errors.ThrowPreconditionFailed(nil, "API-DASs2", "IAM SETUP RUNNING")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
handler := http.NewServeMux()
|
||||
handler.HandleFunc("/healthz", handleHealth)
|
||||
handler.HandleFunc("/ready", handleReadiness(checks))
|
||||
handler.HandleFunc("/clientID", a.handleClientID)
|
||||
|
||||
return handler
|
||||
}
|
||||
|
||||
func handleHealth(w http.ResponseWriter, r *http.Request) {
|
||||
_, err := w.Write([]byte("ok"))
|
||||
logging.Log("API-Hfss2").OnError(err).Error("error writing ok for health")
|
||||
}
|
||||
|
||||
func handleReadiness(checks []ValidationFunction) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
err := validate(r.Context(), checks)
|
||||
if err == nil {
|
||||
http_util.MarshalJSON(w, "ok")
|
||||
return
|
||||
}
|
||||
http_util.MarshalJSON(w, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) handleClientID(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := a.health.VerifierClientID(r.Context(), "Zitadel Console")
|
||||
if err != nil {
|
||||
http_util.MarshalJSON(w, err)
|
||||
return
|
||||
}
|
||||
http_util.MarshalJSON(w, id)
|
||||
}
|
||||
|
||||
type ValidationFunction func(ctx context.Context) error
|
||||
|
||||
func validate(ctx context.Context, validations []ValidationFunction) error {
|
||||
for _, validation := range validations {
|
||||
if err := validation(ctx); err != nil {
|
||||
logging.Log("API-vf823").WithError(err).Error("validation failed")
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
19
internal/api/http/marshal.go
Normal file
19
internal/api/http/marshal.go
Normal file
@ -0,0 +1,19 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/caos/logging"
|
||||
)
|
||||
|
||||
func MarshalJSON(w http.ResponseWriter, i interface{}) {
|
||||
b, err := json.Marshal(i)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("content-type", "application/json")
|
||||
_, err = w.Write(b)
|
||||
logging.Log("HTTP-sdgT2").OnError(err).Error("error writing response")
|
||||
}
|
@ -15,7 +15,7 @@ import (
|
||||
|
||||
type SystemDefaults struct {
|
||||
DefaultLanguage language.Tag
|
||||
DefaultDomain string
|
||||
Domain string
|
||||
ZitadelDocs ZitadelDocs
|
||||
SecretGenerators SecretGenerators
|
||||
UserVerificationKey *crypto.KeyConfig
|
||||
@ -24,7 +24,6 @@ type SystemDefaults struct {
|
||||
DefaultPolicies DefaultPolicies
|
||||
DomainVerification DomainVerification
|
||||
IamID string
|
||||
SetUp types.IAMSetUp
|
||||
Notifications Notifications
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package types
|
||||
package setup
|
||||
|
||||
type IAMSetUp struct {
|
||||
GlobalOrg string
|
||||
@ -39,4 +39,5 @@ type OIDCApp struct {
|
||||
ApplicationType string
|
||||
AuthMethodType string
|
||||
PostLogoutRedirectUris []string
|
||||
DevMode bool
|
||||
}
|
@ -2,34 +2,33 @@ package setup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/config/types"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
policy_model "github.com/caos/zitadel/internal/policy/model"
|
||||
es_policy "github.com/caos/zitadel/internal/policy/repository/eventsourcing"
|
||||
policy_event "github.com/caos/zitadel/internal/policy/repository/eventsourcing"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type Setup struct {
|
||||
repos EventstoreRepos
|
||||
iamID string
|
||||
setUpConfig types.IAMSetUp
|
||||
}
|
||||
|
||||
type EventstoreRepos struct {
|
||||
iamID string
|
||||
IamEvents *iam_event.IamEventstore
|
||||
OrgEvents *org_event.OrgEventstore
|
||||
UserEvents *usr_event.UserEventstore
|
||||
@ -62,30 +61,63 @@ const (
|
||||
OIDCAuthMethodTypePost = "POST"
|
||||
)
|
||||
|
||||
func StartSetup(sd systemdefaults.SystemDefaults, repos EventstoreRepos) *Setup {
|
||||
return &Setup{
|
||||
repos: repos,
|
||||
iamID: sd.IamID,
|
||||
setUpConfig: sd.SetUp,
|
||||
func StartSetup(esConfig es_int.Config, sd systemdefaults.SystemDefaults) (*Setup, error) {
|
||||
setup := &Setup{
|
||||
iamID: sd.IamID,
|
||||
}
|
||||
es, err := es_int.Start(esConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setup.IamEvents, err = es_iam.StartIam(es_iam.IamConfig{
|
||||
Eventstore: es,
|
||||
Cache: esConfig.Cache,
|
||||
}, sd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setup.OrgEvents = es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: sd.Domain}, sd)
|
||||
|
||||
setup.ProjectEvents, err = es_proj.StartProject(es_proj.ProjectConfig{
|
||||
Eventstore: es,
|
||||
Cache: esConfig.Cache,
|
||||
}, sd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setup.UserEvents, err = es_usr.StartUser(es_usr.UserConfig{
|
||||
Eventstore: es,
|
||||
Cache: esConfig.Cache,
|
||||
}, sd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setup.PolicyEvents, err = es_policy.StartPolicy(es_policy.PolicyConfig{
|
||||
Eventstore: es,
|
||||
Cache: esConfig.Cache,
|
||||
}, sd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return setup, nil
|
||||
}
|
||||
|
||||
func (s *Setup) Execute(ctx context.Context) error {
|
||||
iam, err := s.repos.IamEvents.IamByID(ctx, s.iamID)
|
||||
func (s *Setup) Execute(ctx context.Context, setUpConfig IAMSetUp) error {
|
||||
iam, err := s.IamEvents.IamByID(ctx, s.iamID)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
if iam != nil && iam.SetUpDone {
|
||||
if iam != nil && (iam.SetUpStarted || iam.SetUpDone) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if iam != nil && iam.SetUpStarted {
|
||||
return s.waitForSetupDone(ctx)
|
||||
}
|
||||
|
||||
logging.Log("SETUP-hwG32").Info("starting setup")
|
||||
ctx = setSetUpContextData(ctx, s.iamID)
|
||||
iam, err = s.repos.IamEvents.StartSetup(ctx, s.iamID)
|
||||
iam, err = s.IamEvents.StartSetup(ctx, s.iamID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -97,39 +129,39 @@ func (s *Setup) Execute(ctx context.Context) error {
|
||||
createdProjects: make(map[string]*proj_model.Project),
|
||||
}
|
||||
|
||||
pwComplexityPolicy, err := s.repos.PolicyEvents.GetPasswordComplexityPolicy(ctx, policy_model.DefaultPolicy)
|
||||
pwComplexityPolicy, err := s.PolicyEvents.GetPasswordComplexityPolicy(ctx, policy_model.DefaultPolicy)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-9osWF").WithError(err).Error("unable to read complexity policy")
|
||||
return err
|
||||
}
|
||||
setUp.pwComplexityPolicy = pwComplexityPolicy
|
||||
|
||||
err = setUp.orgs(ctx, s.setUpConfig.Orgs)
|
||||
err = setUp.orgs(ctx, setUpConfig.Orgs)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-p4oWq").WithError(err).Error("unable to set up orgs")
|
||||
return err
|
||||
}
|
||||
|
||||
ctx = setSetUpContextData(ctx, s.iamID)
|
||||
err = setUp.iamOwners(ctx, s.setUpConfig.Owners)
|
||||
err = setUp.iamOwners(ctx, setUpConfig.Owners)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-WHr01").WithError(err).Error("unable to set up iam owners")
|
||||
return err
|
||||
}
|
||||
|
||||
err = setUp.setGlobalOrg(ctx)
|
||||
err = setUp.setGlobalOrg(ctx, setUpConfig.GlobalOrg)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-0874m").WithError(err).Error("unable to set global org")
|
||||
return err
|
||||
}
|
||||
|
||||
err = setUp.setIamProject(ctx)
|
||||
err = setUp.setIamProject(ctx, setUpConfig.IAMProject)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-kaWjq").WithError(err).Error("unable to set zitadel project")
|
||||
return err
|
||||
}
|
||||
|
||||
iam, err = s.repos.IamEvents.SetupDone(ctx, s.iamID)
|
||||
iam, err = s.IamEvents.SetupDone(ctx, s.iamID)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-de342").WithError(err).Error("unable to finish setup")
|
||||
return err
|
||||
@ -138,26 +170,7 @@ func (s *Setup) Execute(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Setup) waitForSetupDone(ctx context.Context) error {
|
||||
logging.Log("SETUP-hws22").Info("waiting for setup to be done")
|
||||
ctx, cancel := context.WithDeadline(ctx, time.Now().UTC().Add(10*time.Second))
|
||||
defer cancel()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-time.After(1 * time.Second):
|
||||
iam, _ := s.repos.IamEvents.IamByID(ctx, s.iamID)
|
||||
if iam != nil && iam.SetUpDone {
|
||||
return nil
|
||||
}
|
||||
logging.Log("SETUP-d23g1").Info("setup not done yet")
|
||||
case <-ctx.Done():
|
||||
return caos_errs.ThrowInternal(ctx.Err(), "SETUP-dsjg3", "Timeout exceeded for setup")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (setUp *initializer) orgs(ctx context.Context, orgs []types.Org) error {
|
||||
func (setUp *initializer) orgs(ctx context.Context, orgs []Org) error {
|
||||
logging.Log("SETUP-dsTh3").Info("setting up orgs")
|
||||
for _, iamOrg := range orgs {
|
||||
org, err := setUp.org(ctx, iamOrg)
|
||||
@ -175,7 +188,7 @@ func (setUp *initializer) orgs(ctx context.Context, orgs []types.Org) error {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
policy, err = setUp.repos.OrgEvents.GetOrgIamPolicy(ctx, policy_model.DefaultPolicy)
|
||||
policy, err = setUp.OrgEvents.GetOrgIamPolicy(ctx, policy_model.DefaultPolicy)
|
||||
if err != nil {
|
||||
logging.LogWithFields("SETUP-IS8wS", "Org Iam Policy", iamOrg.Name).WithError(err).Error("unable to get default iam org policy")
|
||||
return err
|
||||
@ -205,13 +218,13 @@ func (setUp *initializer) orgs(ctx context.Context, orgs []types.Org) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (setUp *initializer) org(ctx context.Context, org types.Org) (*org_model.Org, error) {
|
||||
func (setUp *initializer) org(ctx context.Context, org Org) (*org_model.Org, error) {
|
||||
ctx = setSetUpContextData(ctx, "")
|
||||
createOrg := &org_model.Org{
|
||||
Name: org.Name,
|
||||
Domains: []*org_model.OrgDomain{{Domain: org.Domain}},
|
||||
}
|
||||
return setUp.repos.OrgEvents.CreateOrg(ctx, createOrg, nil)
|
||||
return setUp.OrgEvents.CreateOrg(ctx, createOrg, nil)
|
||||
}
|
||||
|
||||
func (setUp *initializer) iamorgpolicy(ctx context.Context, org *org_model.Org) (*org_model.OrgIamPolicy, error) {
|
||||
@ -220,7 +233,7 @@ func (setUp *initializer) iamorgpolicy(ctx context.Context, org *org_model.Org)
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID},
|
||||
UserLoginMustBeDomain: false,
|
||||
}
|
||||
return setUp.repos.OrgEvents.AddOrgIamPolicy(ctx, policy)
|
||||
return setUp.OrgEvents.AddOrgIamPolicy(ctx, policy)
|
||||
}
|
||||
|
||||
func (setUp *initializer) iamOwners(ctx context.Context, owners []string) error {
|
||||
@ -231,7 +244,7 @@ func (setUp *initializer) iamOwners(ctx context.Context, owners []string) error
|
||||
logging.LogWithFields("SETUP-8siew", "Owner", iamOwner).Error("unable to add user to iam members")
|
||||
return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-su6L3", "unable to add user to iam members")
|
||||
}
|
||||
_, err := setUp.repos.IamEvents.AddIamMember(ctx, &iam_model.IamMember{ObjectRoot: models.ObjectRoot{AggregateID: setUp.iamID}, UserID: user.AggregateID, Roles: []string{"IAM_OWNER"}})
|
||||
_, err := setUp.IamEvents.AddIamMember(ctx, &iam_model.IamMember{ObjectRoot: models.ObjectRoot{AggregateID: setUp.iamID}, UserID: user.AggregateID, Roles: []string{"IAM_OWNER"}})
|
||||
if err != nil {
|
||||
logging.Log("SETUP-LM7rI").WithError(err).Error("unable to add iam administrator to iam members as owner")
|
||||
return err
|
||||
@ -241,15 +254,15 @@ func (setUp *initializer) iamOwners(ctx context.Context, owners []string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (setUp *initializer) setGlobalOrg(ctx context.Context) error {
|
||||
func (setUp *initializer) setGlobalOrg(ctx context.Context, globalOrgName string) error {
|
||||
logging.Log("SETUP-dsj75").Info("setting global org")
|
||||
globalOrg, ok := setUp.createdOrgs[setUp.setUpConfig.GlobalOrg]
|
||||
globalOrg, ok := setUp.createdOrgs[globalOrgName]
|
||||
if !ok {
|
||||
logging.LogWithFields("SETUP-FBhs9", "GlobalOrg", setUp.setUpConfig.GlobalOrg).Error("global org not created")
|
||||
return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-4GwU7", "global org not created: %v", setUp.setUpConfig.GlobalOrg)
|
||||
logging.LogWithFields("SETUP-FBhs9", "GlobalOrg", globalOrgName).Error("global org not created")
|
||||
return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-4GwU7", "global org not created: %v", globalOrgName)
|
||||
}
|
||||
|
||||
if _, err := setUp.repos.IamEvents.SetGlobalOrg(ctx, setUp.iamID, globalOrg.AggregateID); err != nil {
|
||||
if _, err := setUp.IamEvents.SetGlobalOrg(ctx, setUp.iamID, globalOrg.AggregateID); err != nil {
|
||||
logging.Log("SETUP-uGMA3").WithError(err).Error("unable to set global org on iam")
|
||||
return err
|
||||
}
|
||||
@ -257,15 +270,15 @@ func (setUp *initializer) setGlobalOrg(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (setUp *initializer) setIamProject(ctx context.Context) error {
|
||||
func (setUp *initializer) setIamProject(ctx context.Context, iamProjectName string) error {
|
||||
logging.Log("SETUP-HE3qa").Info("setting iam project")
|
||||
iamProject, ok := setUp.createdProjects[setUp.setUpConfig.IAMProject]
|
||||
iamProject, ok := setUp.createdProjects[iamProjectName]
|
||||
if !ok {
|
||||
logging.LogWithFields("SETUP-SJFWP", "Iam Project", setUp.setUpConfig.IAMProject).Error("iam project created")
|
||||
return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-sGmQt", "iam project not created: %v", setUp.setUpConfig.IAMProject)
|
||||
logging.LogWithFields("SETUP-SJFWP", "Iam Project", iamProjectName).Error("iam project created")
|
||||
return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-sGmQt", "iam project not created: %v", iamProjectName)
|
||||
}
|
||||
|
||||
if _, err := setUp.repos.IamEvents.SetIamProject(ctx, setUp.iamID, iamProject.AggregateID); err != nil {
|
||||
if _, err := setUp.IamEvents.SetIamProject(ctx, setUp.iamID, iamProject.AggregateID); err != nil {
|
||||
logging.Log("SETUP-i1pNh").WithError(err).Error("unable to set iam project on iam")
|
||||
return err
|
||||
}
|
||||
@ -273,7 +286,7 @@ func (setUp *initializer) setIamProject(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (setUp *initializer) users(ctx context.Context, users []types.User, orgPolicy *org_model.OrgIamPolicy) error {
|
||||
func (setUp *initializer) users(ctx context.Context, users []User, orgPolicy *org_model.OrgIamPolicy) error {
|
||||
for _, user := range users {
|
||||
created, err := setUp.user(ctx, user, orgPolicy)
|
||||
if err != nil {
|
||||
@ -285,7 +298,7 @@ func (setUp *initializer) users(ctx context.Context, users []types.User, orgPoli
|
||||
return nil
|
||||
}
|
||||
|
||||
func (setUp *initializer) user(ctx context.Context, user types.User, orgPolicy *org_model.OrgIamPolicy) (*usr_model.User, error) {
|
||||
func (setUp *initializer) user(ctx context.Context, user User, orgPolicy *org_model.OrgIamPolicy) (*usr_model.User, error) {
|
||||
createUser := &usr_model.User{
|
||||
Profile: &usr_model.Profile{
|
||||
UserName: user.UserName,
|
||||
@ -300,7 +313,7 @@ func (setUp *initializer) user(ctx context.Context, user types.User, orgPolicy *
|
||||
SecretString: user.Password,
|
||||
},
|
||||
}
|
||||
return setUp.repos.UserEvents.CreateUser(ctx, createUser, setUp.pwComplexityPolicy, orgPolicy)
|
||||
return setUp.UserEvents.CreateUser(ctx, createUser, setUp.pwComplexityPolicy, orgPolicy)
|
||||
}
|
||||
|
||||
func (setUp *initializer) orgOwners(ctx context.Context, org *org_model.Org, owners []string) error {
|
||||
@ -325,11 +338,11 @@ func (setUp *initializer) orgOwner(ctx context.Context, org *org_model.Org, user
|
||||
UserID: user.AggregateID,
|
||||
Roles: []string{OrgOwnerRole},
|
||||
}
|
||||
_, err := setUp.repos.OrgEvents.AddOrgMember(ctx, addMember)
|
||||
_, err := setUp.OrgEvents.AddOrgMember(ctx, addMember)
|
||||
return err
|
||||
}
|
||||
|
||||
func (setUp *initializer) projects(ctx context.Context, projects []types.Project) error {
|
||||
func (setUp *initializer) projects(ctx context.Context, projects []Project) error {
|
||||
for _, project := range projects {
|
||||
createdProject, err := setUp.project(ctx, project)
|
||||
if err != nil {
|
||||
@ -347,14 +360,14 @@ func (setUp *initializer) projects(ctx context.Context, projects []types.Project
|
||||
return nil
|
||||
}
|
||||
|
||||
func (setUp *initializer) project(ctx context.Context, project types.Project) (*proj_model.Project, error) {
|
||||
func (setUp *initializer) project(ctx context.Context, project Project) (*proj_model.Project, error) {
|
||||
addProject := &proj_model.Project{
|
||||
Name: project.Name,
|
||||
}
|
||||
return setUp.repos.ProjectEvents.CreateProject(ctx, addProject)
|
||||
return setUp.ProjectEvents.CreateProject(ctx, addProject)
|
||||
}
|
||||
|
||||
func (setUp *initializer) oidcApp(ctx context.Context, project *proj_model.Project, oidc types.OIDCApp) (*proj_model.Application, error) {
|
||||
func (setUp *initializer) oidcApp(ctx context.Context, project *proj_model.Project, oidc OIDCApp) (*proj_model.Application, error) {
|
||||
addOIDCApp := &proj_model.Application{
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: project.AggregateID},
|
||||
Name: oidc.Name,
|
||||
@ -365,9 +378,10 @@ func (setUp *initializer) oidcApp(ctx context.Context, project *proj_model.Proje
|
||||
ApplicationType: getOIDCApplicationType(oidc.ApplicationType),
|
||||
AuthMethodType: getOIDCAuthMethod(oidc.AuthMethodType),
|
||||
PostLogoutRedirectUris: oidc.PostLogoutRedirectUris,
|
||||
DevMode: oidc.DevMode,
|
||||
},
|
||||
}
|
||||
return setUp.repos.ProjectEvents.AddApplication(ctx, addOIDCApp)
|
||||
return setUp.ProjectEvents.AddApplication(ctx, addOIDCApp)
|
||||
}
|
||||
|
||||
func getOIDCResponseTypes(responseTypes []string) []proj_model.OIDCResponseType {
|
||||
@ -431,7 +445,7 @@ func getOIDCAuthMethod(authMethod string) proj_model.OIDCAuthMethodType {
|
||||
case OIDCAuthMethodTypePost:
|
||||
return proj_model.OIDCAuthMethodTypePost
|
||||
}
|
||||
return proj_model.OIDCAuthMethodTypeNone
|
||||
return proj_model.OIDCAuthMethodTypeBasic
|
||||
}
|
||||
|
||||
func setSetUpContextData(ctx context.Context, orgID string) context.Context {
|
@ -32,7 +32,7 @@ type UserEventstore struct {
|
||||
es_int.Eventstore
|
||||
userCache *UserCache
|
||||
idGenerator id.Generator
|
||||
defaultDomain string
|
||||
domain string
|
||||
PasswordAlg crypto.HashAlgorithm
|
||||
InitializeUserCode crypto.Generator
|
||||
EmailVerificationCode crypto.Generator
|
||||
@ -68,7 +68,7 @@ func StartUser(conf UserConfig, systemDefaults sd.SystemDefaults) (*UserEventsto
|
||||
Eventstore: conf.Eventstore,
|
||||
userCache: userCache,
|
||||
idGenerator: id.SonyFlakeGenerator,
|
||||
defaultDomain: systemDefaults.DefaultDomain,
|
||||
domain: systemDefaults.Domain,
|
||||
InitializeUserCode: initCodeGen,
|
||||
EmailVerificationCode: emailVerificationCode,
|
||||
PhoneVerificationCode: phoneVerificationCode,
|
||||
@ -1115,5 +1115,5 @@ func (es *UserEventstore) generateTemporaryLoginName() (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%s@temporary.%s", id, es.defaultDomain), nil
|
||||
return fmt.Sprintf("%s@temporary.%s", id, es.domain), nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user