2021-08-03 09:55:21 +00:00
package commands
import (
"fmt"
"os"
2021-09-17 09:53:59 +00:00
"strings"
2021-08-03 09:55:21 +00:00
"github.com/spf13/cobra"
2021-08-11 01:04:35 +00:00
"github.com/authelia/authelia/v4/internal/logging"
2022-03-06 05:47:40 +00:00
"github.com/authelia/authelia/v4/internal/model"
2021-08-11 01:04:35 +00:00
"github.com/authelia/authelia/v4/internal/utils"
2021-08-03 09:55:21 +00:00
)
// NewRootCmd returns a new Root Cmd.
func NewRootCmd ( ) ( cmd * cobra . Command ) {
2022-12-22 00:21:29 +00:00
ctx := NewCmdCtx ( )
2021-08-03 09:55:21 +00:00
version := utils . Version ( )
cmd = & cobra . Command {
Use : "authelia" ,
2022-06-14 12:40:00 +00:00
Short : fmt . Sprintf ( fmtCmdAutheliaShort , version ) ,
Long : fmt . Sprintf ( fmtCmdAutheliaLong , version ) ,
2021-08-03 09:55:21 +00:00
Example : cmdAutheliaExample ,
Version : version ,
Args : cobra . NoArgs ,
2022-12-22 00:21:29 +00:00
PreRunE : ctx . ChainRunE (
ctx . ConfigEnsureExistsRunE ,
ctx . ConfigLoadRunE ,
ctx . ConfigValidateKeysRunE ,
ctx . ConfigValidateRunE ,
ctx . ConfigValidateLogRunE ,
) ,
RunE : ctx . RootRunE ,
2022-09-01 02:24:47 +00:00
DisableAutoGenTag : true ,
2021-08-03 09:55:21 +00:00
}
2022-12-23 00:03:50 +00:00
cmd . PersistentFlags ( ) . StringSliceP ( cmdFlagNameConfig , "c" , [ ] string { "configuration.yml" } , "configuration files or directories to load, for more information run 'authelia -h authelia config'" )
2021-08-03 09:55:21 +00:00
2022-12-23 00:03:50 +00:00
cmd . PersistentFlags ( ) . StringSlice ( cmdFlagNameConfigExpFilters , nil , "list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters'" )
2022-12-21 09:48:14 +00:00
2021-08-03 09:55:21 +00:00
cmd . AddCommand (
2022-12-22 00:21:29 +00:00
newAccessControlCommand ( ctx ) ,
newBuildInfoCmd ( ctx ) ,
newCryptoCmd ( ctx ) ,
newStorageCmd ( ctx ) ,
newValidateConfigCmd ( ctx ) ,
2022-12-22 06:34:20 +00:00
2022-12-23 00:03:50 +00:00
newHelpTopic ( "config" , "Help for the config file/directory paths" , helpTopicConfig ) ,
newHelpTopic ( "filters" , "help topic for the config filters" , helpTopicConfigFilters ) ,
2023-02-11 03:11:40 +00:00
newHelpTopic ( "time-layouts" , "help topic for the various time layouts" , helpTopicTimeLayouts ) ,
2021-08-03 09:55:21 +00:00
)
return cmd
}
2022-12-22 00:21:29 +00:00
func ( ctx * CmdCtx ) RootRunE ( _ * cobra . Command , _ [ ] string ) ( err error ) {
ctx . log . Infof ( "Authelia %s is starting" , utils . Version ( ) )
2021-08-03 09:55:21 +00:00
if os . Getenv ( "ENVIRONMENT" ) == "dev" {
2022-12-22 00:21:29 +00:00
ctx . log . Info ( "===> Authelia is running in development mode. <===" )
2021-08-03 09:55:21 +00:00
}
2022-12-22 00:21:29 +00:00
if err = logging . InitializeLogger ( ctx . config . Log , true ) ; err != nil {
ctx . log . Fatalf ( "Cannot initialize logger: %v" , err )
2021-08-03 09:55:21 +00:00
}
2022-12-22 00:21:29 +00:00
warns , errs := ctx . LoadProviders ( )
if len ( warns ) != 0 {
for _ , err = range warns {
ctx . log . Warn ( err )
2021-08-03 09:55:21 +00:00
}
}
2022-12-22 00:21:29 +00:00
if len ( errs ) != 0 {
for _ , err = range errs {
ctx . log . Error ( err )
2021-08-03 09:55:21 +00:00
}
2022-12-22 00:21:29 +00:00
ctx . log . Fatalf ( "Errors occurred provisioning providers." )
2021-08-03 09:55:21 +00:00
}
2022-12-22 00:21:29 +00:00
doStartupChecks ( ctx )
2022-12-22 06:34:20 +00:00
ctx . cconfig = nil
2023-02-11 10:45:26 +00:00
servicesRun ( ctx )
2021-09-17 09:53:59 +00:00
2022-12-22 00:21:29 +00:00
return nil
2022-06-14 07:20:13 +00:00
}
2022-12-22 00:21:29 +00:00
func doStartupChecks ( ctx * CmdCtx ) {
2021-09-17 09:53:59 +00:00
var (
failures [ ] string
err error
)
2022-12-22 00:21:29 +00:00
if err = doStartupCheck ( ctx , "storage" , ctx . providers . StorageProvider , false ) ; err != nil {
ctx . log . Errorf ( "Failure running the storage provider startup check: %+v" , err )
2021-11-23 09:45:38 +00:00
failures = append ( failures , "storage" )
}
2022-12-22 00:21:29 +00:00
if err = doStartupCheck ( ctx , "user" , ctx . providers . UserProvider , false ) ; err != nil {
ctx . log . Errorf ( "Failure running the user provider startup check: %+v" , err )
2021-09-17 09:53:59 +00:00
failures = append ( failures , "user" )
}
2022-12-22 00:21:29 +00:00
if err = doStartupCheck ( ctx , "notification" , ctx . providers . Notifier , ctx . config . Notifier . DisableStartupCheck ) ; err != nil {
ctx . log . Errorf ( "Failure running the notification provider startup check: %+v" , err )
2021-09-17 09:53:59 +00:00
failures = append ( failures , "notification" )
}
2022-12-22 00:21:29 +00:00
if ! ctx . config . NTP . DisableStartupCheck && ! ctx . providers . Authorizer . IsSecondFactorEnabled ( ) {
ctx . log . Debug ( "The NTP startup check was skipped due to there being no configured 2FA access control rules" )
} else if err = doStartupCheck ( ctx , "ntp" , ctx . providers . NTP , ctx . config . NTP . DisableStartupCheck ) ; err != nil {
ctx . log . Errorf ( "Failure running the ntp provider startup check: %+v" , err )
2021-09-17 09:53:59 +00:00
2022-12-22 00:21:29 +00:00
if ! ctx . config . NTP . DisableFailure {
2022-02-03 03:04:24 +00:00
failures = append ( failures , "ntp" )
}
2021-09-17 09:53:59 +00:00
}
if len ( failures ) != 0 {
2022-12-22 00:21:29 +00:00
ctx . log . Fatalf ( "The following providers had fatal failures during startup: %s" , strings . Join ( failures , ", " ) )
2021-09-17 09:53:59 +00:00
}
}
2022-12-22 00:21:29 +00:00
func doStartupCheck ( ctx * CmdCtx , name string , provider model . StartupCheck , disabled bool ) error {
2021-09-17 09:53:59 +00:00
if disabled {
2022-12-22 00:21:29 +00:00
ctx . log . Debugf ( "%s provider: startup check skipped as it is disabled" , name )
2021-09-17 09:53:59 +00:00
return nil
}
if provider == nil {
return fmt . Errorf ( "unrecognized provider or it is not configured properly" )
}
2022-02-09 22:07:53 +00:00
return provider . StartupCheck ( )
2021-09-17 09:53:59 +00:00
}