snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
This commit is contained in:
16
server/pkg/options/DB.go
Normal file
16
server/pkg/options/DB.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (o *DBOpt) Cleanup() {
|
||||
if o.DSN != "" && !strings.Contains(o.DSN, "://") {
|
||||
// Make sure DSN is compatible with new requirements
|
||||
o.DSN = "mysql://" + o.DSN
|
||||
}
|
||||
}
|
||||
|
||||
func (o DBOpt) IsSQLite() bool {
|
||||
return strings.HasPrefix(o.DSN, "sqlite3")
|
||||
}
|
||||
7
server/pkg/options/HTTPClient.go
Normal file
7
server/pkg/options/HTTPClient.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package options
|
||||
|
||||
func (o *HTTPClientOpt) Defaults() {
|
||||
// just in case anyone used env var with the typo (before it was fixed)
|
||||
o.TlsInsecure = EnvBool("HTTP_CLIENT_TSL_INSECURE", o.TlsInsecure)
|
||||
|
||||
}
|
||||
25
server/pkg/options/HTTPServer.go
Normal file
25
server/pkg/options/HTTPServer.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package options
|
||||
|
||||
func (o *HttpServerOpt) Defaults() {
|
||||
if Environment().IsDevelopment() {
|
||||
// enable web console and remove username, password defaults
|
||||
// if this is explicitly via ENV, it will override these defaults
|
||||
o.WebConsoleEnabled = true
|
||||
o.WebConsoleUsername = ""
|
||||
o.WebConsolePassword = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (o *HttpServerOpt) Cleanup() {
|
||||
o.BaseUrl = CleanBase(o.BaseUrl)
|
||||
o.ApiBaseUrl = CleanBase(o.ApiBaseUrl)
|
||||
o.WebappBaseUrl = CleanBase(o.WebappBaseUrl)
|
||||
|
||||
if o.WebappEnabled && o.ApiEnabled && (o.ApiBaseUrl == "/" || o.ApiBaseUrl == "") {
|
||||
// api base URL is still on root (empty string)
|
||||
// but webapps are enabled (that means, server also serves static files from WebappBaseDir)
|
||||
//
|
||||
// Let's be nice and move API to /api
|
||||
o.ApiBaseUrl = CleanBase("api")
|
||||
}
|
||||
}
|
||||
17
server/pkg/options/auth.go
Normal file
17
server/pkg/options/auth.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func getSecretFromEnv(salt string) string {
|
||||
gen := salt
|
||||
// generate default secrets from virtualhost/hostname and DB_DSN value.
|
||||
// this will keep the secret the same through restarts
|
||||
gen += EnvString("DB_DSN", "memory")
|
||||
// pick one of the env that holds hostname
|
||||
gen += EnvString("HOSTNAME", "localhost")
|
||||
|
||||
return fmt.Sprintf("%x", md5.Sum([]byte(gen)))
|
||||
}
|
||||
11
server/pkg/options/corredor.go
Normal file
11
server/pkg/options/corredor.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"path"
|
||||
)
|
||||
|
||||
func (o *CorredorOpt) Cleanup() {
|
||||
o.TlsCertCA = path.Join(o.TlsCertPath, o.TlsCertCA)
|
||||
o.TlsCertPrivate = path.Join(o.TlsCertPath, o.TlsCertPrivate)
|
||||
o.TlsCertPublic = path.Join(o.TlsCertPath, o.TlsCertPublic)
|
||||
}
|
||||
16
server/pkg/options/environment.go
Normal file
16
server/pkg/options/environment.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package options
|
||||
|
||||
import "strings"
|
||||
|
||||
func (e EnvironmentOpt) IsDevelopment() bool {
|
||||
return strings.HasPrefix(e.Environment, "dev")
|
||||
}
|
||||
|
||||
func (e EnvironmentOpt) IsTest() bool {
|
||||
return strings.HasPrefix(e.Environment, "test")
|
||||
}
|
||||
|
||||
func (e EnvironmentOpt) IsProduction() bool {
|
||||
return !e.IsDevelopment() &&
|
||||
!e.IsTest()
|
||||
}
|
||||
182
server/pkg/options/helpers.go
Normal file
182
server/pkg/options/helpers.go
Normal file
@@ -0,0 +1,182 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
func fill(opt interface{}) {
|
||||
v := reflect.ValueOf(opt)
|
||||
if v.Kind() != reflect.Ptr {
|
||||
panic("expecting a pointer, not a value")
|
||||
}
|
||||
|
||||
if v.IsNil() {
|
||||
panic("nil pointer passed")
|
||||
}
|
||||
|
||||
v = v.Elem()
|
||||
|
||||
length := v.NumField()
|
||||
for i := 0; i < length; i++ {
|
||||
f := v.Field(i)
|
||||
t := v.Type().Field(i)
|
||||
if tag := t.Tag.Get("env"); tag != "" {
|
||||
if !f.CanSet() {
|
||||
panic("unexpected pointer for field " + t.Name)
|
||||
}
|
||||
|
||||
if f.Type() == reflect.TypeOf(time.Duration(1)) {
|
||||
v.FieldByName(t.Name).SetInt(int64(EnvDuration(tag, time.Duration(f.Int()))))
|
||||
continue
|
||||
}
|
||||
|
||||
if f.Kind() == reflect.String {
|
||||
v.FieldByName(t.Name).SetString(EnvString(tag, f.String()))
|
||||
continue
|
||||
}
|
||||
|
||||
if f.Kind() == reflect.Bool {
|
||||
v.FieldByName(t.Name).SetBool(EnvBool(tag, f.Bool()))
|
||||
continue
|
||||
}
|
||||
|
||||
if f.Kind() == reflect.Int || f.Kind() == reflect.Int64 {
|
||||
v.FieldByName(t.Name).SetInt(int64(EnvInt(tag, int(f.Int()))))
|
||||
continue
|
||||
}
|
||||
|
||||
if f.Kind() == reflect.Float32 || f.Kind() == reflect.Float64 {
|
||||
v.FieldByName(t.Name).SetFloat(float64(EnvFloat32(tag, float32(f.Float()))))
|
||||
continue
|
||||
}
|
||||
|
||||
panic("unsupported type/kind for field " + t.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func GuessApiHostname() string {
|
||||
return guessHostname(os.Getenv("DOMAIN"))
|
||||
}
|
||||
|
||||
func GuessWebappHostname() string {
|
||||
return guessHostname(os.Getenv("DOMAIN_WEBAPP"))
|
||||
}
|
||||
|
||||
func guessHostname(base ...string) string {
|
||||
// All env keys we'll check, first one with a value set, will be used as hostname
|
||||
candidates := append(base, []string{
|
||||
os.Getenv("LETSENCRYPT_HOST"),
|
||||
os.Getenv("VIRTUAL_HOST"),
|
||||
}...)
|
||||
|
||||
for _, host := range candidates {
|
||||
if len(host) > 0 {
|
||||
return host
|
||||
}
|
||||
}
|
||||
|
||||
return "localhost"
|
||||
}
|
||||
|
||||
// returns path prefix
|
||||
func pathPrefix(pp ...string) string {
|
||||
return CleanBase(append([]string{EnvString("HTTP_BASE_URL", "")}, pp...)...)
|
||||
}
|
||||
|
||||
// will return base URL with domain and prefix path
|
||||
func FullURL(pp ...string) string {
|
||||
return fullUrl(GuessApiHostname(), pp...)
|
||||
}
|
||||
|
||||
func FullWebappURL(pp ...string) string {
|
||||
return fullUrl(GuessWebappHostname(), pp...)
|
||||
}
|
||||
|
||||
// will return base URL with domain and prefix path
|
||||
func fullUrl(host string, pp ...string) string {
|
||||
var (
|
||||
full string
|
||||
)
|
||||
|
||||
if strings.Contains(host, "local.") || strings.Contains(host, "localhost") || !isSecure() {
|
||||
full = "http://" + host
|
||||
} else {
|
||||
full = "https://" + host
|
||||
}
|
||||
|
||||
if pfix := pathPrefix(pp...); pfix != "" {
|
||||
return full + pfix
|
||||
}
|
||||
|
||||
return full
|
||||
}
|
||||
|
||||
// Checks value of HTTP_SSL_TERMINATED and fallbacks to checking existence of LETSENCRYPT_HOST
|
||||
// to determinate we are behind a SSL termination infrastructure
|
||||
func isSecure() bool {
|
||||
var _, is = os.LookupEnv("LETSENCRYPT_HOST")
|
||||
|
||||
// We're accessing to HTTP_SSL_TERMINATED directly here and not via HttpServerOpt.SslTerminated
|
||||
// because we need to get to this value early and directly
|
||||
return EnvBool("HTTP_SSL_TERMINATED", is)
|
||||
}
|
||||
|
||||
// Path joins all parts with / and prefixes result (if not empty) with /
|
||||
func CleanBase(pp ...string) string {
|
||||
//if p := strings.Trim(path.Join(pp...), "/"); p != "" {
|
||||
// // prefix base with slash
|
||||
// return "/" + p
|
||||
//}
|
||||
|
||||
return "/" + strings.Trim(path.Join(pp...), "/")
|
||||
}
|
||||
|
||||
func EnvString(key string, def string) string {
|
||||
if val, has := os.LookupEnv(key); has {
|
||||
return val
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func EnvBool(key string, def bool) bool {
|
||||
if val, has := os.LookupEnv(key); has {
|
||||
if b, err := cast.ToBoolE(val); err == nil {
|
||||
return b
|
||||
}
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func EnvInt(key string, def int) int {
|
||||
if val, has := os.LookupEnv(key); has {
|
||||
if i, err := cast.ToIntE(val); err == nil {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func EnvFloat32(key string, def float32) float32 {
|
||||
if val, has := os.LookupEnv(key); has {
|
||||
if i, err := cast.ToFloat32E(val); err == nil {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func EnvDuration(key string, def time.Duration) time.Duration {
|
||||
if val, has := os.LookupEnv(key); has {
|
||||
if d, err := cast.ToDurationE(val); err == nil {
|
||||
return d
|
||||
}
|
||||
}
|
||||
return def
|
||||
}
|
||||
7
server/pkg/options/locale.go
Normal file
7
server/pkg/options/locale.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package options
|
||||
|
||||
func (o *LocaleOpt) Defaults() {
|
||||
if Environment().IsDevelopment() || o.DevelopmentMode {
|
||||
o.Path = "../locale"
|
||||
}
|
||||
}
|
||||
1144
server/pkg/options/options.gen.go
generated
Normal file
1144
server/pkg/options/options.gen.go
generated
Normal file
File diff suppressed because it is too large
Load Diff
67
server/pkg/options/options.go
Normal file
67
server/pkg/options/options.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package options
|
||||
|
||||
type (
|
||||
Options struct {
|
||||
Environment EnvironmentOpt
|
||||
ActionLog ActionLogOpt
|
||||
SMTP SMTPOpt
|
||||
Auth AuthOpt
|
||||
HTTPClient HTTPClientOpt
|
||||
DB DBOpt
|
||||
Template TemplateOpt
|
||||
Upgrade UpgradeOpt
|
||||
Provision ProvisionOpt
|
||||
Sentry SentryOpt
|
||||
ObjStore ObjectStoreOpt
|
||||
Corredor CorredorOpt
|
||||
Monitor MonitorOpt
|
||||
WaitFor WaitForOpt
|
||||
HTTPServer HttpServerOpt
|
||||
Websocket WebsocketOpt
|
||||
Eventbus EventbusOpt
|
||||
Messagebus MessagebusOpt
|
||||
Federation FederationOpt
|
||||
SCIM SCIMOpt
|
||||
Workflow WorkflowOpt
|
||||
RBAC RbacOpt
|
||||
Locale LocaleOpt
|
||||
Limit LimitOpt
|
||||
Discovery DiscoveryOpt
|
||||
Apigw ApigwOpt
|
||||
Attachment AttachmentOpt
|
||||
Webapp WebappOpt
|
||||
}
|
||||
)
|
||||
|
||||
func Init() *Options {
|
||||
return &Options{
|
||||
Environment: *Environment(),
|
||||
ActionLog: *ActionLog(),
|
||||
Auth: *Auth(),
|
||||
SMTP: *SMTP(),
|
||||
HTTPClient: *HTTPClient(),
|
||||
DB: *DB(),
|
||||
Template: *Template(),
|
||||
Upgrade: *Upgrade(),
|
||||
Provision: *Provision(),
|
||||
Sentry: *Sentry(),
|
||||
ObjStore: *ObjectStore(),
|
||||
Corredor: *Corredor(),
|
||||
Monitor: *Monitor(),
|
||||
WaitFor: *WaitFor(),
|
||||
HTTPServer: *HttpServer(),
|
||||
Websocket: *Websocket(),
|
||||
Eventbus: *Eventbus(),
|
||||
Messagebus: *Messagebus(),
|
||||
Federation: *Federation(),
|
||||
SCIM: *SCIM(),
|
||||
Workflow: *Workflow(),
|
||||
RBAC: *Rbac(),
|
||||
Locale: *Locale(),
|
||||
Limit: *Limit(),
|
||||
Discovery: *Discovery(),
|
||||
Apigw: *Apigw(),
|
||||
Attachment: *Attachment(),
|
||||
Webapp: *Webapp(),
|
||||
}
|
||||
}
|
||||
14
server/pkg/options/waitFor.go
Normal file
14
server/pkg/options/waitFor.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Parses hosts and return slice of strings, one per host
|
||||
func (o WaitForOpt) GetServices() []string {
|
||||
if len(o.Services) == 0 {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
return strings.Split(o.Services, " ")
|
||||
}
|
||||
Reference in New Issue
Block a user