mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:17:32 +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:
@@ -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")
|
||||
}
|
Reference in New Issue
Block a user