| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 | 
							- // Copyright (C) 2019 Nicola Murino
 
- //
 
- // This program is free software: you can redistribute it and/or modify
 
- // it under the terms of the GNU Affero General Public License as published
 
- // by the Free Software Foundation, version 3.
 
- //
 
- // This program is distributed in the hope that it will be useful,
 
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
 
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
- // GNU Affero General Public License for more details.
 
- //
 
- // You should have received a copy of the GNU Affero General Public License
 
- // along with this program. If not, see <https://www.gnu.org/licenses/>.
 
- // Package cmd provides Command Line Interface support
 
- package cmd
 
- import (
 
- 	"fmt"
 
- 	"os"
 
- 	"github.com/spf13/cobra"
 
- 	"github.com/spf13/viper"
 
- 	"github.com/drakkan/sftpgo/v2/internal/version"
 
- )
 
- const (
 
- 	configDirFlag            = "config-dir"
 
- 	configDirKey             = "config_dir"
 
- 	configFileFlag           = "config-file"
 
- 	configFileKey            = "config_file"
 
- 	logFilePathFlag          = "log-file-path"
 
- 	logFilePathKey           = "log_file_path"
 
- 	logMaxSizeFlag           = "log-max-size"
 
- 	logMaxSizeKey            = "log_max_size"
 
- 	logMaxBackupFlag         = "log-max-backups"
 
- 	logMaxBackupKey          = "log_max_backups"
 
- 	logMaxAgeFlag            = "log-max-age"
 
- 	logMaxAgeKey             = "log_max_age"
 
- 	logCompressFlag          = "log-compress"
 
- 	logCompressKey           = "log_compress"
 
- 	logLevelFlag             = "log-level"
 
- 	logLevelKey              = "log_level"
 
- 	logUTCTimeFlag           = "log-utc-time"
 
- 	logUTCTimeKey            = "log_utc_time"
 
- 	loadDataFromFlag         = "loaddata-from"
 
- 	loadDataFromKey          = "loaddata_from"
 
- 	loadDataModeFlag         = "loaddata-mode"
 
- 	loadDataModeKey          = "loaddata_mode"
 
- 	loadDataQuotaScanFlag    = "loaddata-scan"
 
- 	loadDataQuotaScanKey     = "loaddata_scan"
 
- 	loadDataCleanFlag        = "loaddata-clean"
 
- 	loadDataCleanKey         = "loaddata_clean"
 
- 	graceTimeFlag            = "grace-time"
 
- 	graceTimeKey             = "grace_time"
 
- 	defaultConfigDir         = "."
 
- 	defaultConfigFile        = ""
 
- 	defaultLogFile           = "sftpgo.log"
 
- 	defaultLogMaxSize        = 10
 
- 	defaultLogMaxBackup      = 5
 
- 	defaultLogMaxAge         = 28
 
- 	defaultLogCompress       = false
 
- 	defaultLogLevel          = "debug"
 
- 	defaultLogUTCTime        = false
 
- 	defaultLoadDataFrom      = ""
 
- 	defaultLoadDataMode      = 1
 
- 	defaultLoadDataQuotaScan = 0
 
- 	defaultLoadDataClean     = false
 
- 	defaultGraceTime         = 0
 
- )
 
- var (
 
- 	configDir         string
 
- 	configFile        string
 
- 	logFilePath       string
 
- 	logMaxSize        int
 
- 	logMaxBackups     int
 
- 	logMaxAge         int
 
- 	logCompress       bool
 
- 	logLevel          string
 
- 	logUTCTime        bool
 
- 	loadDataFrom      string
 
- 	loadDataMode      int
 
- 	loadDataQuotaScan int
 
- 	loadDataClean     bool
 
- 	graceTime         int
 
- 	// used if awscontainer build tag is enabled
 
- 	disableAWSInstallationCode bool
 
- 	rootCmd = &cobra.Command{
 
- 		Use:   "sftpgo",
 
- 		Short: "Fully featured and highly configurable SFTP server",
 
- 	}
 
- )
 
- func init() {
 
- 	rootCmd.CompletionOptions.DisableDefaultCmd = true
 
- 	rootCmd.Flags().BoolP("version", "v", false, "")
 
- 	rootCmd.Version = version.GetAsString()
 
- 	rootCmd.SetVersionTemplate(`{{printf "SFTPGo "}}{{printf "%s" .Version}}
 
- `)
 
- }
 
- // Execute adds all child commands to the root command and sets flags appropriately.
 
- // This is called by main.main(). It only needs to happen once to the rootCmd.
 
- func Execute() {
 
- 	if err := rootCmd.Execute(); err != nil {
 
- 		fmt.Println(err)
 
- 		os.Exit(1)
 
- 	}
 
- }
 
- func addConfigFlags(cmd *cobra.Command) {
 
- 	viper.SetDefault(configDirKey, defaultConfigDir)
 
- 	viper.BindEnv(configDirKey, "SFTPGO_CONFIG_DIR") //nolint:errcheck // err is not nil only if the key to bind is missing
 
- 	cmd.Flags().StringVarP(&configDir, configDirFlag, "c", viper.GetString(configDirKey),
 
- 		`Location of the config dir. This directory
 
- is used as the base for files with a relative
 
- path, e.g. the private keys for the SFTP
 
- server or the database file if you use a
 
- file-based data provider.
 
- The configuration file, if not explicitly set,
 
- is looked for in this dir. We support reading
 
- from JSON, TOML, YAML, HCL, envfile and Java
 
- properties config files. The default config
 
- file name is "sftpgo" and therefore
 
- "sftpgo.json", "sftpgo.yaml" and so on are
 
- searched.
 
- This flag can be set using SFTPGO_CONFIG_DIR
 
- env var too.`)
 
- 	viper.BindPFlag(configDirKey, cmd.Flags().Lookup(configDirFlag)) //nolint:errcheck
 
- 	viper.SetDefault(configFileKey, defaultConfigFile)
 
- 	viper.BindEnv(configFileKey, "SFTPGO_CONFIG_FILE") //nolint:errcheck
 
- 	cmd.Flags().StringVar(&configFile, configFileFlag, viper.GetString(configFileKey),
 
- 		`Path to SFTPGo configuration file.
 
- This flag explicitly defines the path, name
 
- and extension of the config file. If must be
 
- an absolute path or a path relative to the
 
- configuration directory. The specified file
 
- name must have a supported extension (JSON,
 
- YAML, TOML, HCL or Java properties).
 
- This flag can be set using SFTPGO_CONFIG_FILE
 
- env var too.`)
 
- 	viper.BindPFlag(configFileKey, cmd.Flags().Lookup(configFileFlag)) //nolint:errcheck
 
- }
 
- func addBaseLoadDataFlags(cmd *cobra.Command) {
 
- 	viper.SetDefault(loadDataFromKey, defaultLoadDataFrom)
 
- 	viper.BindEnv(loadDataFromKey, "SFTPGO_LOADDATA_FROM") //nolint:errcheck
 
- 	cmd.Flags().StringVar(&loadDataFrom, loadDataFromFlag, viper.GetString(loadDataFromKey),
 
- 		`Load users and folders from this file.
 
- The file must be specified as absolute path
 
- and it must contain a backup obtained using
 
- the "dumpdata" REST API or compatible content.
 
- This flag can be set using SFTPGO_LOADDATA_FROM
 
- env var too.
 
- `)
 
- 	viper.BindPFlag(loadDataFromKey, cmd.Flags().Lookup(loadDataFromFlag)) //nolint:errcheck
 
- 	viper.SetDefault(loadDataModeKey, defaultLoadDataMode)
 
- 	viper.BindEnv(loadDataModeKey, "SFTPGO_LOADDATA_MODE") //nolint:errcheck
 
- 	cmd.Flags().IntVar(&loadDataMode, loadDataModeFlag, viper.GetInt(loadDataModeKey),
 
- 		`Restore mode for data to load:
 
-   0 - new users are added, existing users are
 
-       updated
 
-   1 - New users are added, existing users are
 
- 	  not modified
 
- This flag can be set using SFTPGO_LOADDATA_MODE
 
- env var too.
 
- `)
 
- 	viper.BindPFlag(loadDataModeKey, cmd.Flags().Lookup(loadDataModeFlag)) //nolint:errcheck
 
- 	viper.SetDefault(loadDataCleanKey, defaultLoadDataClean)
 
- 	viper.BindEnv(loadDataCleanKey, "SFTPGO_LOADDATA_CLEAN") //nolint:errcheck
 
- 	cmd.Flags().BoolVar(&loadDataClean, loadDataCleanFlag, viper.GetBool(loadDataCleanKey),
 
- 		`Determine if the loaddata-from file should
 
- be removed after a successful load. This flag
 
- can be set using SFTPGO_LOADDATA_CLEAN env var
 
- too. (default "false")
 
- `)
 
- 	viper.BindPFlag(loadDataCleanKey, cmd.Flags().Lookup(loadDataCleanFlag)) //nolint:errcheck
 
- }
 
- func addServeFlags(cmd *cobra.Command) {
 
- 	addConfigFlags(cmd)
 
- 	viper.SetDefault(logFilePathKey, defaultLogFile)
 
- 	viper.BindEnv(logFilePathKey, "SFTPGO_LOG_FILE_PATH") //nolint:errcheck
 
- 	cmd.Flags().StringVarP(&logFilePath, logFilePathFlag, "l", viper.GetString(logFilePathKey),
 
- 		`Location for the log file. Leave empty to write
 
- logs to the standard output. This flag can be
 
- set using SFTPGO_LOG_FILE_PATH env var too.
 
- `)
 
- 	viper.BindPFlag(logFilePathKey, cmd.Flags().Lookup(logFilePathFlag)) //nolint:errcheck
 
- 	viper.SetDefault(logMaxSizeKey, defaultLogMaxSize)
 
- 	viper.BindEnv(logMaxSizeKey, "SFTPGO_LOG_MAX_SIZE") //nolint:errcheck
 
- 	cmd.Flags().IntVarP(&logMaxSize, logMaxSizeFlag, "s", viper.GetInt(logMaxSizeKey),
 
- 		`Maximum size in megabytes of the log file
 
- before it gets rotated. This flag can be set
 
- using SFTPGO_LOG_MAX_SIZE env var too. It is
 
- unused if log-file-path is empty.
 
- `)
 
- 	viper.BindPFlag(logMaxSizeKey, cmd.Flags().Lookup(logMaxSizeFlag)) //nolint:errcheck
 
- 	viper.SetDefault(logMaxBackupKey, defaultLogMaxBackup)
 
- 	viper.BindEnv(logMaxBackupKey, "SFTPGO_LOG_MAX_BACKUPS") //nolint:errcheck
 
- 	cmd.Flags().IntVarP(&logMaxBackups, "log-max-backups", "b", viper.GetInt(logMaxBackupKey),
 
- 		`Maximum number of old log files to retain.
 
- This flag can be set using SFTPGO_LOG_MAX_BACKUPS
 
- env var too. It is unused if log-file-path is
 
- empty.`)
 
- 	viper.BindPFlag(logMaxBackupKey, cmd.Flags().Lookup(logMaxBackupFlag)) //nolint:errcheck
 
- 	viper.SetDefault(logMaxAgeKey, defaultLogMaxAge)
 
- 	viper.BindEnv(logMaxAgeKey, "SFTPGO_LOG_MAX_AGE") //nolint:errcheck
 
- 	cmd.Flags().IntVarP(&logMaxAge, "log-max-age", "a", viper.GetInt(logMaxAgeKey),
 
- 		`Maximum number of days to retain old log files.
 
- This flag can be set using SFTPGO_LOG_MAX_AGE env
 
- var too. It is unused if log-file-path is empty.
 
- `)
 
- 	viper.BindPFlag(logMaxAgeKey, cmd.Flags().Lookup(logMaxAgeFlag)) //nolint:errcheck
 
- 	viper.SetDefault(logCompressKey, defaultLogCompress)
 
- 	viper.BindEnv(logCompressKey, "SFTPGO_LOG_COMPRESS") //nolint:errcheck
 
- 	cmd.Flags().BoolVarP(&logCompress, logCompressFlag, "z", viper.GetBool(logCompressKey),
 
- 		`Determine if the rotated log files
 
- should be compressed using gzip. This flag can
 
- be set using SFTPGO_LOG_COMPRESS env var too.
 
- It is unused if log-file-path is empty.
 
- `)
 
- 	viper.BindPFlag(logCompressKey, cmd.Flags().Lookup(logCompressFlag)) //nolint:errcheck
 
- 	viper.SetDefault(logLevelKey, defaultLogLevel)
 
- 	viper.BindEnv(logLevelKey, "SFTPGO_LOG_LEVEL") //nolint:errcheck
 
- 	cmd.Flags().StringVar(&logLevel, logLevelFlag, viper.GetString(logLevelKey),
 
- 		`Set the log level. Supported values:
 
- debug, info, warn, error.
 
- This flag can be set
 
- using SFTPGO_LOG_LEVEL env var too.
 
- `)
 
- 	viper.BindPFlag(logLevelKey, cmd.Flags().Lookup(logLevelFlag)) //nolint:errcheck
 
- 	viper.SetDefault(logUTCTimeKey, defaultLogUTCTime)
 
- 	viper.BindEnv(logUTCTimeKey, "SFTPGO_LOG_UTC_TIME") //nolint:errcheck
 
- 	cmd.Flags().BoolVar(&logUTCTime, logUTCTimeFlag, viper.GetBool(logUTCTimeKey),
 
- 		`Use UTC time for logging. This flag can be set
 
- using SFTPGO_LOG_UTC_TIME env var too.
 
- `)
 
- 	viper.BindPFlag(logUTCTimeKey, cmd.Flags().Lookup(logUTCTimeFlag)) //nolint:errcheck
 
- 	addBaseLoadDataFlags(cmd)
 
- 	viper.SetDefault(loadDataQuotaScanKey, defaultLoadDataQuotaScan)
 
- 	viper.BindEnv(loadDataQuotaScanKey, "SFTPGO_LOADDATA_QUOTA_SCAN") //nolint:errcheck
 
- 	cmd.Flags().IntVar(&loadDataQuotaScan, loadDataQuotaScanFlag, viper.GetInt(loadDataQuotaScanKey),
 
- 		`Quota scan mode after data load:
 
-   0 - no quota scan
 
-   1 - scan quota
 
-   2 - scan quota if the user has quota restrictions
 
- This flag can be set using SFTPGO_LOADDATA_QUOTA_SCAN
 
- env var too.
 
- (default 0)`)
 
- 	viper.BindPFlag(loadDataQuotaScanKey, cmd.Flags().Lookup(loadDataQuotaScanFlag)) //nolint:errcheck
 
- 	viper.SetDefault(graceTimeKey, defaultGraceTime)
 
- 	viper.BindEnv(graceTimeKey, "SFTPGO_GRACE_TIME") //nolint:errcheck
 
- 	cmd.Flags().IntVar(&graceTime, graceTimeFlag, viper.GetInt(graceTimeKey),
 
- 		`Graceful shutdown is an option to initiate a
 
- shutdown without abrupt cancellation of the
 
- currently ongoing client-initiated transfer
 
- sessions.
 
- This grace time defines the number of seconds
 
- allowed for existing transfers to get
 
- completed before shutting down.
 
- A graceful shutdown is triggered by an
 
- interrupt signal.
 
- This flag can be set using SFTPGO_GRACE_TIME env
 
- var too. 0 means disabled. (default 0)`)
 
- 	viper.BindPFlag(graceTimeKey, cmd.Flags().Lookup(graceTimeFlag)) //nolint:errcheck
 
- }
 
 
  |