Improve cli env setup & running
This commit is contained in:
+2
-2
@@ -14,11 +14,11 @@ type (
|
||||
func DB(cmd *cobra.Command, pfix string) (o *DBOpt) {
|
||||
o = &DBOpt{}
|
||||
|
||||
bindString(cmd, &o.DSN,
|
||||
BindString(cmd, &o.DSN,
|
||||
pFlag(pfix, "db-dsn"), "corteza:corteza@tcp(db:3306)/corteza?collation=utf8mb4_general_ci",
|
||||
"DSN for database connection")
|
||||
|
||||
bindString(cmd, &o.Profiler,
|
||||
BindString(cmd, &o.Profiler,
|
||||
pFlag(pfix, "db-profiler"), "none",
|
||||
"Profiler for DB queries (none, stdout, logger)")
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ func envKey(s string) string {
|
||||
return strings.ToUpper(strings.ReplaceAll(s, "-", "_"))
|
||||
}
|
||||
|
||||
func bindString(cmd *cobra.Command, v *string, flag, def string, desc string) {
|
||||
func BindString(cmd *cobra.Command, v *string, flag, def string, desc string) {
|
||||
if env, has := os.LookupEnv(envKey(flag)); has {
|
||||
def = cast.ToString(env)
|
||||
}
|
||||
@@ -31,7 +31,7 @@ func bindString(cmd *cobra.Command, v *string, flag, def string, desc string) {
|
||||
cmd.Flags().StringVar(v, flag, def, desc)
|
||||
}
|
||||
|
||||
func bindBool(cmd *cobra.Command, v *bool, flag string, def bool, desc string) {
|
||||
func BindBool(cmd *cobra.Command, v *bool, flag string, def bool, desc string) {
|
||||
if env, has := os.LookupEnv(envKey(flag)); has {
|
||||
def = cast.ToBool(env)
|
||||
}
|
||||
@@ -39,7 +39,7 @@ func bindBool(cmd *cobra.Command, v *bool, flag string, def bool, desc string) {
|
||||
cmd.Flags().BoolVar(v, flag, def, desc)
|
||||
}
|
||||
|
||||
func bindInt(cmd *cobra.Command, v *int, flag string, def int, desc string) {
|
||||
func BindInt(cmd *cobra.Command, v *int, flag string, def int, desc string) {
|
||||
if env, has := os.LookupEnv(envKey(flag)); has {
|
||||
def = cast.ToInt(env)
|
||||
}
|
||||
@@ -47,7 +47,7 @@ func bindInt(cmd *cobra.Command, v *int, flag string, def int, desc string) {
|
||||
cmd.Flags().IntVar(v, flag, def, desc)
|
||||
}
|
||||
|
||||
func bindDuration(cmd *cobra.Command, v *time.Duration, flag string, def time.Duration, desc string) {
|
||||
func BindDuration(cmd *cobra.Command, v *time.Duration, flag string, def time.Duration, desc string) {
|
||||
if env, has := os.LookupEnv(envKey(flag)); has {
|
||||
def = cast.ToDuration(env)
|
||||
}
|
||||
|
||||
+10
-10
@@ -26,44 +26,44 @@ type (
|
||||
func HTTP(cmd *cobra.Command, pfix string) (o *HTTPOpt) {
|
||||
o = &HTTPOpt{}
|
||||
|
||||
bindString(cmd, &o.Addr,
|
||||
BindString(cmd, &o.Addr,
|
||||
pFlag(pfix, "http-addr"), ":80",
|
||||
"Listen address for HTTP server")
|
||||
|
||||
bindBool(cmd, &o.Logging,
|
||||
BindBool(cmd, &o.Logging,
|
||||
pFlag(pfix, "http-log"), true,
|
||||
"Enable/disable HTTP request log")
|
||||
|
||||
bindBool(cmd, &o.Pretty,
|
||||
BindBool(cmd, &o.Pretty,
|
||||
pFlag(pfix, "http-pretty-json"), false,
|
||||
"Prettify returned JSON output")
|
||||
|
||||
bindBool(cmd, &o.Tracing,
|
||||
BindBool(cmd, &o.Tracing,
|
||||
pFlag(pfix, "http-error-tracing"), false,
|
||||
"Return error stack frame")
|
||||
|
||||
bindBool(cmd, &o.EnableVersionRoute,
|
||||
BindBool(cmd, &o.EnableVersionRoute,
|
||||
pFlag(pfix, "http-enable-version-route"), true,
|
||||
"Enable /version route")
|
||||
|
||||
bindBool(cmd, &o.EnableDebugRoute,
|
||||
BindBool(cmd, &o.EnableDebugRoute,
|
||||
pFlag(pfix, "http-enable-debug-route"), false,
|
||||
"Enable /debug route with pprof data")
|
||||
|
||||
bindBool(cmd, &o.EnableMetrics,
|
||||
BindBool(cmd, &o.EnableMetrics,
|
||||
pFlag(pfix, "http-metrics"), false,
|
||||
"Enable metrics")
|
||||
|
||||
bindString(cmd, &o.MetricsServiceLabel,
|
||||
BindString(cmd, &o.MetricsServiceLabel,
|
||||
pFlag(pfix, "http-metrics-name"), "corteza",
|
||||
"Provide metrics service label for Prometheus")
|
||||
|
||||
bindString(cmd, &o.MetricsUsername,
|
||||
BindString(cmd, &o.MetricsUsername,
|
||||
pFlag(pfix, "http-metrics-username"), "metrics",
|
||||
"Provide metrics username for Prometheus")
|
||||
|
||||
// Setting metrics password to random string to prevent security accidents...
|
||||
bindString(cmd, &o.MetricsPassword,
|
||||
BindString(cmd, &o.MetricsPassword,
|
||||
pFlag(pfix, "http-metrics-password"), string(rand.Bytes(5)),
|
||||
"Provide metrics password for Prometheus")
|
||||
|
||||
|
||||
@@ -16,11 +16,11 @@ type (
|
||||
func HttpClient(cmd *cobra.Command) (o *HttpClientOpt) {
|
||||
o = &HttpClientOpt{}
|
||||
|
||||
bindBool(cmd, &o.ClientTSLInsecure,
|
||||
BindBool(cmd, &o.ClientTSLInsecure,
|
||||
"http-client-tsl-insecure", false,
|
||||
"Skip insecure TSL verification on outbound HTTP requests (allow invalid/self-signed certificates")
|
||||
|
||||
bindDuration(cmd, &o.HttpClientTimeout,
|
||||
BindDuration(cmd, &o.HttpClientTimeout,
|
||||
"http-client-timeout", 30*time.Second,
|
||||
"Default HTTP client timeout")
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@ func JWT(cmd *cobra.Command) (o *JWTOpt) {
|
||||
o = &JWTOpt{}
|
||||
|
||||
// Setting JWT secret to random string to prevent security accidents...
|
||||
bindString(cmd, &o.Secret,
|
||||
BindString(cmd, &o.Secret,
|
||||
"auth-jwt-secret", string(rand.Bytes(32)),
|
||||
"JWT Secret")
|
||||
|
||||
bindInt(cmd, &o.Expiry,
|
||||
BindInt(cmd, &o.Expiry,
|
||||
"auth-jwt-expiry", 60*24*30,
|
||||
"JWT Expiration in minutes")
|
||||
|
||||
|
||||
@@ -5,22 +5,19 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
// Logger's output leve is configured here, but
|
||||
// dev/prod configuration happens earlier
|
||||
LogOpt struct {
|
||||
Level string
|
||||
JSON bool
|
||||
}
|
||||
)
|
||||
|
||||
func Log(cmd *cobra.Command) (o *LogOpt) {
|
||||
o = &LogOpt{}
|
||||
|
||||
bindString(cmd, &o.Level,
|
||||
BindString(cmd, &o.Level,
|
||||
"log-level", "info",
|
||||
"Log level (debug, info, warn, error, panic, fatal)")
|
||||
|
||||
bindBool(cmd, &o.JSON,
|
||||
"log-json", true,
|
||||
"Log in JSON format")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
package flags
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type (
|
||||
MonitorOpt struct {
|
||||
Interval int
|
||||
Interval time.Duration
|
||||
}
|
||||
)
|
||||
|
||||
func Monitor(cmd *cobra.Command, pfix string) (o *MonitorOpt) {
|
||||
o = &MonitorOpt{}
|
||||
|
||||
bindInt(cmd, &o.Interval,
|
||||
pFlag(pfix, "monitor-interval"), 300,
|
||||
"Monitor interval (seconds, 0 = disable)")
|
||||
BindDuration(cmd, &o.Interval,
|
||||
pFlag(pfix, "monitor-interval"), 300*time.Second,
|
||||
"Monitor interval (0 = disable)")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6,16 +6,22 @@ import (
|
||||
|
||||
type (
|
||||
ProvisionOpt struct {
|
||||
Database bool
|
||||
MigrateDatabase bool
|
||||
|
||||
AutoSetup bool
|
||||
}
|
||||
)
|
||||
|
||||
func Provision(cmd *cobra.Command, pfix string) (o *ProvisionOpt) {
|
||||
o = &ProvisionOpt{}
|
||||
|
||||
bindBool(cmd, &o.Database,
|
||||
pFlag(pfix, "provision-database"), true,
|
||||
"Run database migration scripts")
|
||||
BindBool(cmd, &o.MigrateDatabase,
|
||||
pFlag(pfix, "provision-migrate-database"), true,
|
||||
"Run database migration")
|
||||
|
||||
BindBool(cmd, &o.AutoSetup,
|
||||
pFlag(pfix, "provision-auto-setup"), true,
|
||||
"Run auto-setup procedures on service")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -30,27 +30,27 @@ func PubSub(cmd *cobra.Command, pfix string) (o *PubSubOpt) {
|
||||
pingPeriod = (pingTimeout * 9) / 10
|
||||
)
|
||||
|
||||
bindString(cmd, &o.Mode,
|
||||
BindString(cmd, &o.Mode,
|
||||
pFlag(pfix, "pubsub-mode"), "poll",
|
||||
"Pub/Sub mode (poll, redis")
|
||||
|
||||
bindDuration(cmd, &o.RedisPingTimeout,
|
||||
BindDuration(cmd, &o.RedisPingTimeout,
|
||||
pFlag(pfix, "pubsub-polling-interval"), timeout,
|
||||
"Sub/Sub polling interval")
|
||||
|
||||
bindString(cmd, &o.RedisAddr,
|
||||
BindString(cmd, &o.RedisAddr,
|
||||
pFlag(pfix, "pubsub-redis-addr"), "redis:6379",
|
||||
"Pub/Sub mode (poll, redis")
|
||||
|
||||
bindDuration(cmd, &o.RedisTimeout,
|
||||
BindDuration(cmd, &o.RedisTimeout,
|
||||
pFlag(pfix, "pubsub-redis-timeout"), timeout,
|
||||
"Websocket connection timeout")
|
||||
|
||||
bindDuration(cmd, &o.RedisPingTimeout,
|
||||
BindDuration(cmd, &o.RedisPingTimeout,
|
||||
pFlag(pfix, "pubsub-redis-ping-timeout"), pingTimeout,
|
||||
"Pub/Sub connection ping timeout")
|
||||
|
||||
bindDuration(cmd, &o.RedisPingPeriod,
|
||||
BindDuration(cmd, &o.RedisPingPeriod,
|
||||
pFlag(pfix, "pubsub-redis-ping-period"), pingPeriod,
|
||||
"Pub/Sub connection ping period (should be lower than timeout)")
|
||||
|
||||
|
||||
@@ -17,23 +17,23 @@ type (
|
||||
func SMTP(cmd *cobra.Command) (o *SMTPOpt) {
|
||||
o = &SMTPOpt{}
|
||||
|
||||
bindString(cmd, &o.Host,
|
||||
BindString(cmd, &o.Host,
|
||||
"smtp-host", "localhost:25",
|
||||
"SMTP hostname")
|
||||
|
||||
bindString(cmd, &o.User,
|
||||
BindString(cmd, &o.User,
|
||||
"smtp-username", "",
|
||||
"SMTP server username")
|
||||
|
||||
bindString(cmd, &o.Pass,
|
||||
BindString(cmd, &o.Pass,
|
||||
"smtp-pass", "",
|
||||
"SMTP server password")
|
||||
|
||||
bindString(cmd, &o.From,
|
||||
BindString(cmd, &o.From,
|
||||
"smtp-from", "",
|
||||
"Sender's email address")
|
||||
|
||||
bindInt(cmd, &o.Port,
|
||||
BindInt(cmd, &o.Port,
|
||||
"smtp-port", 25,
|
||||
"SMTP port number")
|
||||
|
||||
|
||||
@@ -23,15 +23,15 @@ func Websocket(cmd *cobra.Command, pfix string) (o *WebsocketOpt) {
|
||||
pingPeriod = (pingTimeout * 9) / 10
|
||||
)
|
||||
|
||||
bindDuration(cmd, &o.Timeout,
|
||||
BindDuration(cmd, &o.Timeout,
|
||||
pFlag(pfix, "websocket-timeout"), timeout,
|
||||
"Websocket connection timeout")
|
||||
|
||||
bindDuration(cmd, &o.PingTimeout,
|
||||
BindDuration(cmd, &o.PingTimeout,
|
||||
pFlag(pfix, "websocket-ping-timeout"), pingTimeout,
|
||||
"Websocket connection ping timeout")
|
||||
|
||||
bindDuration(cmd, &o.PingPeriod,
|
||||
BindDuration(cmd, &o.PingPeriod,
|
||||
pFlag(pfix, "websocket-ping-period"), pingPeriod,
|
||||
"Websocket connection ping period (should be lower than timeout)")
|
||||
|
||||
|
||||
+13
-83
@@ -1,9 +1,9 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/internal/auth"
|
||||
@@ -13,90 +13,11 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/logger"
|
||||
)
|
||||
|
||||
// SetupProvisionCommands sets-up standard provision commands
|
||||
// Deprecated: use SetupProvisionSubCommands
|
||||
func SetupProvisionCommands(ac func() error, md func() error) *cobra.Command {
|
||||
var (
|
||||
cmd = &cobra.Command{
|
||||
Use: "provision",
|
||||
Short: "Provision tasks",
|
||||
}
|
||||
)
|
||||
|
||||
// Add only commands with defined callbacks
|
||||
if ac != nil {
|
||||
cmd.AddCommand(&cobra.Command{
|
||||
Use: "access-control-rules",
|
||||
Short: "Reset access control rules & roles",
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return ac()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Add only commands with defined callbacks
|
||||
if md != nil {
|
||||
cmd.AddCommand(&cobra.Command{
|
||||
Use: "migrate-database",
|
||||
Short: "Run database migration scripts",
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return md()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
type (
|
||||
provisioner interface {
|
||||
ProvisionMigrateDatabase(ctx context.Context) error
|
||||
ProvisionAccessControl(ctx context.Context) error
|
||||
}
|
||||
)
|
||||
|
||||
func SetupProvisionSubcommands(ctx context.Context, p provisioner) *cobra.Command {
|
||||
var (
|
||||
cmd = &cobra.Command{
|
||||
Use: "provision",
|
||||
Short: "Provision tasks",
|
||||
}
|
||||
)
|
||||
|
||||
// Add only commands with defined callbacks
|
||||
cmd.AddCommand(&cobra.Command{
|
||||
Use: "access-control-rules",
|
||||
Short: "Reset access control rules & roles",
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return p.ProvisionAccessControl(ctx)
|
||||
},
|
||||
})
|
||||
|
||||
// Add only commands with defined callbacks
|
||||
cmd.AddCommand(&cobra.Command{
|
||||
Use: "migrate-database",
|
||||
Short: "Run database migration scripts",
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return p.ProvisionMigrateDatabase(ctx)
|
||||
},
|
||||
})
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func InitGeneralServices(logOpt *flags.LogOpt, smtpOpt *flags.SMTPOpt, jwtOpt *flags.JWTOpt, httpClientOpt *flags.HttpClientOpt) {
|
||||
// Reset logger's level to whatever we want
|
||||
var logLevel = zap.InfoLevel
|
||||
_ = logLevel.Set(logOpt.Level)
|
||||
|
||||
if logger.Default() == nil {
|
||||
logger.Init(logLevel)
|
||||
} else {
|
||||
logger.DefaultLevel.SetLevel(logLevel)
|
||||
}
|
||||
logger.DefaultLevel.SetLevel(logLevel)
|
||||
|
||||
auth.SetupDefault(jwtOpt.Secret, jwtOpt.Expiry)
|
||||
mail.SetupDialer(smtpOpt.Host, smtpOpt.Port, smtpOpt.User, smtpOpt.Pass, smtpOpt.From)
|
||||
@@ -105,3 +26,12 @@ func InitGeneralServices(logOpt *flags.LogOpt, smtpOpt *flags.SMTPOpt, jwtOpt *f
|
||||
httpClientOpt.ClientTSLInsecure,
|
||||
)
|
||||
}
|
||||
|
||||
func HandleError(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,315 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/internal/db"
|
||||
"github.com/cortezaproject/corteza-server/pkg/api"
|
||||
"github.com/cortezaproject/corteza-server/pkg/cli/flags"
|
||||
"github.com/cortezaproject/corteza-server/pkg/logger"
|
||||
)
|
||||
|
||||
type (
|
||||
Runner func(ctx context.Context, cmd *cobra.Command, c *Config) error
|
||||
Runners []Runner
|
||||
|
||||
CommandMaker func(ctx context.Context, c *Config) *cobra.Command
|
||||
CommandMakers []CommandMaker
|
||||
|
||||
FlagBinder func(cmd *cobra.Command, c *Config)
|
||||
FlagBinders []FlagBinder
|
||||
|
||||
Mounter func(r chi.Router)
|
||||
Mounters []Mounter
|
||||
|
||||
Config struct {
|
||||
init bool
|
||||
|
||||
// Service name (messaging, system...)
|
||||
// See comments on other fields for how it is used.
|
||||
ServiceName string
|
||||
|
||||
// Logger name for internal services, defaults to ServiceName
|
||||
LoggerName string
|
||||
Log *zap.Logger
|
||||
|
||||
// General options/flags
|
||||
LogOpt *flags.LogOpt
|
||||
SmtpOpt *flags.SMTPOpt
|
||||
JwtOpt *flags.JWTOpt
|
||||
HttpClientOpt *flags.HttpClientOpt
|
||||
|
||||
// Per-service options/flags
|
||||
DbOpt *flags.DBOpt
|
||||
ProvisionOpt *flags.ProvisionOpt
|
||||
|
||||
// DB Connection name, defaults to ServiceName
|
||||
DatabaseName string
|
||||
|
||||
// Root command name, , defaults to "corteza-server-<ServiceName>"
|
||||
RootCommandName string
|
||||
|
||||
// Flags that are bond to root command, no (per-service) prefixed
|
||||
RootCommandBaseFlags FlagBinders
|
||||
|
||||
// Prefix for flags for root command, defaults to ServiceName
|
||||
RootCommandFlagsPrefix string
|
||||
|
||||
// Flags that are bond to root command, (per-service) prefixed
|
||||
RootCommandPrefixedFlags FlagBinders
|
||||
|
||||
// Database setup/connection procedure
|
||||
// Runner autobinds default runner that tries to connect using DbOpt.DSN
|
||||
RootCommandDBSetup Runners
|
||||
|
||||
// All that needs to be initialized before any sub-comman is executed
|
||||
RootCommandPreRun Runners
|
||||
|
||||
// ******************************************************************
|
||||
|
||||
// API Server instance
|
||||
ApiServer *api.Server
|
||||
|
||||
// API Server command name
|
||||
ApiServerCommandName string
|
||||
|
||||
// Prefix for "serve-api command flags", defaults to ServiceName
|
||||
ApiServerFlagsPrefix string
|
||||
|
||||
// Additional command flags for API server
|
||||
ApiServerAdtFlags FlagBinders
|
||||
|
||||
// Code that needs to be executed before HTTP server is started
|
||||
ApiServerPreRun Runners
|
||||
|
||||
// Routers that we mount on HTTP server
|
||||
ApiServerRoutes Mounters
|
||||
|
||||
// Sets-up all available subcommands.
|
||||
AdtSubCommands CommandMakers
|
||||
|
||||
// Database migration code
|
||||
// This is used for "provision migrate-database" command and after db connection is
|
||||
// established (if --provision-migrate-database is enabled
|
||||
ProvisionMigrateDatabase Runners
|
||||
|
||||
// Access control initial setup
|
||||
// Reapplies default access control rules for roles "everyone" [1] and "admin" [2]
|
||||
ProvisionAccessControl Runners
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Have logger ready in case we need to log anything
|
||||
// before it gets properly initialized through InitGeneralServices
|
||||
logger.Init()
|
||||
}
|
||||
|
||||
func (rr Runners) Run(ctx context.Context, cmd *cobra.Command, c *Config) (err error) {
|
||||
for i := range rr {
|
||||
err = rr[i](ctx, cmd, c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (rr Mounters) MountRoutes(r chi.Router) {
|
||||
for i := range rr {
|
||||
rr[i](r)
|
||||
}
|
||||
}
|
||||
|
||||
func (bb FlagBinders) Bind(cmd *cobra.Command, c *Config) {
|
||||
for i := range bb {
|
||||
bb[i](cmd, c)
|
||||
}
|
||||
}
|
||||
|
||||
func (mm CommandMakers) Make(ctx context.Context, c *Config) []*cobra.Command {
|
||||
var (
|
||||
valid = make([]*cobra.Command, 0)
|
||||
cmd *cobra.Command
|
||||
)
|
||||
|
||||
for i := range mm {
|
||||
if cmd = mm[i](ctx, c); cmd != nil {
|
||||
valid = append(valid, cmd)
|
||||
}
|
||||
}
|
||||
|
||||
return valid
|
||||
}
|
||||
|
||||
func CombineFlagBinders(rr ...FlagBinders) (out FlagBinders) {
|
||||
for i := range rr {
|
||||
out = append(out, rr[i]...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (c *Config) Init() {
|
||||
if c.init {
|
||||
return
|
||||
}
|
||||
|
||||
if c.Log == nil {
|
||||
c.Log = logger.Default()
|
||||
}
|
||||
|
||||
if c.LoggerName == "" {
|
||||
c.LoggerName = c.ServiceName
|
||||
}
|
||||
|
||||
c.Log = c.Log.Named(c.LoggerName)
|
||||
|
||||
if c.RootCommandName == "" {
|
||||
c.RootCommandName = "corteza-server-" + c.ServiceName
|
||||
}
|
||||
|
||||
if c.ApiServerCommandName == "" {
|
||||
c.ApiServerCommandName = "serve-api"
|
||||
}
|
||||
|
||||
if c.ApiServerFlagsPrefix == "" {
|
||||
c.ApiServerFlagsPrefix = c.ServiceName
|
||||
}
|
||||
|
||||
if c.DatabaseName == "" {
|
||||
c.DatabaseName = c.ServiceName
|
||||
}
|
||||
|
||||
if c.RootCommandDBSetup == nil {
|
||||
c.RootCommandDBSetup = Runners{func(ctx context.Context, cmd *cobra.Command, c *Config) (err error) {
|
||||
_, err = db.TryToConnect(ctx, c.Log, c.DatabaseName, c.DbOpt.DSN, c.DbOpt.Profiler)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not connect to database")
|
||||
}
|
||||
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
// Flags, not prefixed with service name
|
||||
if c.RootCommandBaseFlags == nil {
|
||||
c.RootCommandBaseFlags = FlagBinders{
|
||||
func(cmd *cobra.Command, c *Config) {
|
||||
c.LogOpt = flags.Log(cmd)
|
||||
c.SmtpOpt = flags.SMTP(cmd)
|
||||
c.JwtOpt = flags.JWT(cmd)
|
||||
c.HttpClientOpt = flags.HttpClient(cmd)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if c.RootCommandFlagsPrefix == "" {
|
||||
c.RootCommandFlagsPrefix = c.ServiceName
|
||||
}
|
||||
|
||||
// Flags, prefixed with service name
|
||||
if c.RootCommandPrefixedFlags == nil {
|
||||
c.RootCommandPrefixedFlags = FlagBinders{
|
||||
func(cmd *cobra.Command, c *Config) {
|
||||
c.DbOpt = flags.DB(cmd, c.ServiceName)
|
||||
c.ProvisionOpt = flags.Provision(cmd, c.ServiceName)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if c.ApiServer == nil {
|
||||
c.ApiServer = api.NewServer(c.Log)
|
||||
}
|
||||
|
||||
for i := range c.ApiServerRoutes {
|
||||
c.ApiServer.MountRoutes(c.ApiServerRoutes[i])
|
||||
}
|
||||
}
|
||||
|
||||
// MakeCLI creates command line interface
|
||||
//
|
||||
// It tries to construct "serve-api" and "provision" sub-commands
|
||||
// if configured properly (see Config struct)
|
||||
func (c *Config) MakeCLI(ctx context.Context) (cmd *cobra.Command) {
|
||||
c.Init()
|
||||
|
||||
cmd = &cobra.Command{
|
||||
Use: c.RootCommandName,
|
||||
TraverseChildren: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
InitGeneralServices(c.LogOpt, c.SmtpOpt, c.JwtOpt, c.HttpClientOpt)
|
||||
|
||||
err = c.RootCommandDBSetup.Run(ctx, cmd, c)
|
||||
if err != nil {
|
||||
c.Log.Error("Failed to connect to the database", zap.Error(err))
|
||||
return nil
|
||||
}
|
||||
|
||||
err = c.RootCommandPreRun.Run(ctx, cmd, c)
|
||||
if err != nil {
|
||||
c.Log.Error("Failed to run command pre-run scripts", zap.Error(err))
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
c.RootCommandBaseFlags.Bind(cmd, c)
|
||||
c.RootCommandPrefixedFlags.Bind(cmd, c)
|
||||
|
||||
serveApiCmd := c.ApiServer.Command(ctx, c.ApiServerCommandName, c.ApiServerFlagsPrefix, func(ctx context.Context) (err error) {
|
||||
return c.ApiServerPreRun.Run(ctx, cmd, c)
|
||||
})
|
||||
|
||||
// Bind all flags we need for serving the API
|
||||
c.ApiServerAdtFlags.Bind(serveApiCmd, c)
|
||||
|
||||
cmd.AddCommand(serveApiCmd)
|
||||
|
||||
if len(c.ProvisionMigrateDatabase) > 0 || len(c.ProvisionAccessControl) > 0 {
|
||||
var (
|
||||
provisionCmd = &cobra.Command{
|
||||
Use: "provision",
|
||||
Short: "Provision tasks",
|
||||
}
|
||||
)
|
||||
|
||||
// Add only commands with defined callbacks
|
||||
if len(c.ProvisionMigrateDatabase) > 0 {
|
||||
provisionCmd.AddCommand(&cobra.Command{
|
||||
Use: "access-control-rules",
|
||||
Short: "Reset access control rules & roles",
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return c.ProvisionAccessControl.Run(ctx, nil, c)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Add only commands with defined callbacks
|
||||
if len(c.ProvisionAccessControl) > 0 {
|
||||
provisionCmd.AddCommand(&cobra.Command{
|
||||
Use: "migrate-database",
|
||||
Short: "Run database migration scripts",
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return c.ProvisionMigrateDatabase.Run(ctx, nil, c)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
cmd.AddCommand(provisionCmd)
|
||||
}
|
||||
|
||||
cmd.AddCommand(c.AdtSubCommands.Make(ctx, c)...)
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user