root.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // Package cmd provides Command Line Interface support
  2. package cmd
  3. import (
  4. "fmt"
  5. "os"
  6. "github.com/spf13/cobra"
  7. "github.com/spf13/viper"
  8. "github.com/drakkan/sftpgo/v2/version"
  9. )
  10. const (
  11. configDirFlag = "config-dir"
  12. configDirKey = "config_dir"
  13. configFileFlag = "config-file"
  14. configFileKey = "config_file"
  15. logFilePathFlag = "log-file-path"
  16. logFilePathKey = "log_file_path"
  17. logMaxSizeFlag = "log-max-size"
  18. logMaxSizeKey = "log_max_size"
  19. logMaxBackupFlag = "log-max-backups"
  20. logMaxBackupKey = "log_max_backups"
  21. logMaxAgeFlag = "log-max-age"
  22. logMaxAgeKey = "log_max_age"
  23. logCompressFlag = "log-compress"
  24. logCompressKey = "log_compress"
  25. logVerboseFlag = "log-verbose"
  26. logVerboseKey = "log_verbose"
  27. loadDataFromFlag = "loaddata-from"
  28. loadDataFromKey = "loaddata_from"
  29. loadDataModeFlag = "loaddata-mode"
  30. loadDataModeKey = "loaddata_mode"
  31. loadDataQuotaScanFlag = "loaddata-scan"
  32. loadDataQuotaScanKey = "loaddata_scan"
  33. loadDataCleanFlag = "loaddata-clean"
  34. loadDataCleanKey = "loaddata_clean"
  35. defaultConfigDir = "."
  36. defaultConfigFile = ""
  37. defaultLogFile = "sftpgo.log"
  38. defaultLogMaxSize = 10
  39. defaultLogMaxBackup = 5
  40. defaultLogMaxAge = 28
  41. defaultLogCompress = false
  42. defaultLogVerbose = true
  43. defaultLoadDataFrom = ""
  44. defaultLoadDataMode = 1
  45. defaultLoadDataQuotaScan = 0
  46. defaultLoadDataClean = false
  47. )
  48. var (
  49. configDir string
  50. configFile string
  51. logFilePath string
  52. logMaxSize int
  53. logMaxBackups int
  54. logMaxAge int
  55. logCompress bool
  56. logVerbose bool
  57. loadDataFrom string
  58. loadDataMode int
  59. loadDataQuotaScan int
  60. loadDataClean bool
  61. rootCmd = &cobra.Command{
  62. Use: "sftpgo",
  63. Short: "Fully featured and highly configurable SFTP server",
  64. }
  65. )
  66. func init() {
  67. rootCmd.Flags().BoolP("version", "v", false, "")
  68. rootCmd.Version = version.GetAsString()
  69. rootCmd.SetVersionTemplate(`{{printf "SFTPGo "}}{{printf "%s" .Version}}
  70. `)
  71. }
  72. // Execute adds all child commands to the root command and sets flags appropriately.
  73. // This is called by main.main(). It only needs to happen once to the rootCmd.
  74. func Execute() {
  75. if err := rootCmd.Execute(); err != nil {
  76. fmt.Println(err)
  77. os.Exit(1)
  78. }
  79. }
  80. func addConfigFlags(cmd *cobra.Command) {
  81. viper.SetDefault(configDirKey, defaultConfigDir)
  82. viper.BindEnv(configDirKey, "SFTPGO_CONFIG_DIR") //nolint:errcheck // err is not nil only if the key to bind is missing
  83. cmd.Flags().StringVarP(&configDir, configDirFlag, "c", viper.GetString(configDirKey),
  84. `Location for the config dir. This directory
  85. is used as the base for files with a relative
  86. path, eg. the private keys for the SFTP
  87. server or the SQLite database if you use
  88. SQLite as data provider.
  89. The configuration file, if not explicitly set,
  90. is looked for in this dir. We support reading
  91. from JSON, TOML, YAML, HCL, envfile and Java
  92. properties config files. The default config
  93. file name is "sftpgo" and therefore
  94. "sftpgo.json", "sftpgo.yaml" and so on are
  95. searched.
  96. This flag can be set using SFTPGO_CONFIG_DIR
  97. env var too.`)
  98. viper.BindPFlag(configDirKey, cmd.Flags().Lookup(configDirFlag)) //nolint:errcheck
  99. viper.SetDefault(configFileKey, defaultConfigFile)
  100. viper.BindEnv(configFileKey, "SFTPGO_CONFIG_FILE") //nolint:errcheck
  101. cmd.Flags().StringVar(&configFile, configFileFlag, viper.GetString(configFileKey),
  102. `Path to SFTPGo configuration file.
  103. This flag explicitly defines the path, name
  104. and extension of the config file. If must be
  105. an absolute path or a path relative to the
  106. configuration directory. The specified file
  107. name must have a supported extension (JSON,
  108. YAML, TOML, HCL or Java properties).
  109. This flag can be set using SFTPGO_CONFIG_FILE
  110. env var too.`)
  111. viper.BindPFlag(configFileKey, cmd.Flags().Lookup(configFileFlag)) //nolint:errcheck
  112. }
  113. func addServeFlags(cmd *cobra.Command) {
  114. addConfigFlags(cmd)
  115. viper.SetDefault(logFilePathKey, defaultLogFile)
  116. viper.BindEnv(logFilePathKey, "SFTPGO_LOG_FILE_PATH") //nolint:errcheck
  117. cmd.Flags().StringVarP(&logFilePath, logFilePathFlag, "l", viper.GetString(logFilePathKey),
  118. `Location for the log file. Leave empty to write
  119. logs to the standard output. This flag can be
  120. set using SFTPGO_LOG_FILE_PATH env var too.
  121. `)
  122. viper.BindPFlag(logFilePathKey, cmd.Flags().Lookup(logFilePathFlag)) //nolint:errcheck
  123. viper.SetDefault(logMaxSizeKey, defaultLogMaxSize)
  124. viper.BindEnv(logMaxSizeKey, "SFTPGO_LOG_MAX_SIZE") //nolint:errcheck
  125. cmd.Flags().IntVarP(&logMaxSize, logMaxSizeFlag, "s", viper.GetInt(logMaxSizeKey),
  126. `Maximum size in megabytes of the log file
  127. before it gets rotated. This flag can be set
  128. using SFTPGO_LOG_MAX_SIZE env var too. It is
  129. unused if log-file-path is empty.
  130. `)
  131. viper.BindPFlag(logMaxSizeKey, cmd.Flags().Lookup(logMaxSizeFlag)) //nolint:errcheck
  132. viper.SetDefault(logMaxBackupKey, defaultLogMaxBackup)
  133. viper.BindEnv(logMaxBackupKey, "SFTPGO_LOG_MAX_BACKUPS") //nolint:errcheck
  134. cmd.Flags().IntVarP(&logMaxBackups, "log-max-backups", "b", viper.GetInt(logMaxBackupKey),
  135. `Maximum number of old log files to retain.
  136. This flag can be set using SFTPGO_LOG_MAX_BACKUPS
  137. env var too. It is unused if log-file-path is
  138. empty.`)
  139. viper.BindPFlag(logMaxBackupKey, cmd.Flags().Lookup(logMaxBackupFlag)) //nolint:errcheck
  140. viper.SetDefault(logMaxAgeKey, defaultLogMaxAge)
  141. viper.BindEnv(logMaxAgeKey, "SFTPGO_LOG_MAX_AGE") //nolint:errcheck
  142. cmd.Flags().IntVarP(&logMaxAge, "log-max-age", "a", viper.GetInt(logMaxAgeKey),
  143. `Maximum number of days to retain old log files.
  144. This flag can be set using SFTPGO_LOG_MAX_AGE env
  145. var too. It is unused if log-file-path is empty.
  146. `)
  147. viper.BindPFlag(logMaxAgeKey, cmd.Flags().Lookup(logMaxAgeFlag)) //nolint:errcheck
  148. viper.SetDefault(logCompressKey, defaultLogCompress)
  149. viper.BindEnv(logCompressKey, "SFTPGO_LOG_COMPRESS") //nolint:errcheck
  150. cmd.Flags().BoolVarP(&logCompress, logCompressFlag, "z", viper.GetBool(logCompressKey),
  151. `Determine if the rotated log files
  152. should be compressed using gzip. This flag can
  153. be set using SFTPGO_LOG_COMPRESS env var too.
  154. It is unused if log-file-path is empty.
  155. `)
  156. viper.BindPFlag(logCompressKey, cmd.Flags().Lookup(logCompressFlag)) //nolint:errcheck
  157. viper.SetDefault(logVerboseKey, defaultLogVerbose)
  158. viper.BindEnv(logVerboseKey, "SFTPGO_LOG_VERBOSE") //nolint:errcheck
  159. cmd.Flags().BoolVarP(&logVerbose, logVerboseFlag, "v", viper.GetBool(logVerboseKey),
  160. `Enable verbose logs. This flag can be set
  161. using SFTPGO_LOG_VERBOSE env var too.
  162. `)
  163. viper.BindPFlag(logVerboseKey, cmd.Flags().Lookup(logVerboseFlag)) //nolint:errcheck
  164. viper.SetDefault(loadDataFromKey, defaultLoadDataFrom)
  165. viper.BindEnv(loadDataFromKey, "SFTPGO_LOADDATA_FROM") //nolint:errcheck
  166. cmd.Flags().StringVar(&loadDataFrom, loadDataFromFlag, viper.GetString(loadDataFromKey),
  167. `Load users and folders from this file.
  168. The file must be specified as absolute path
  169. and it must contain a backup obtained using
  170. the "dumpdata" REST API or compatible content.
  171. This flag can be set using SFTPGO_LOADDATA_FROM
  172. env var too.
  173. `)
  174. viper.BindPFlag(loadDataFromKey, cmd.Flags().Lookup(loadDataFromFlag)) //nolint:errcheck
  175. viper.SetDefault(loadDataModeKey, defaultLoadDataMode)
  176. viper.BindEnv(loadDataModeKey, "SFTPGO_LOADDATA_MODE") //nolint:errcheck
  177. cmd.Flags().IntVar(&loadDataMode, loadDataModeFlag, viper.GetInt(loadDataModeKey),
  178. `Restore mode for data to load:
  179. 0 - new users are added, existing users are
  180. updated
  181. 1 - New users are added, existing users are
  182. not modified
  183. This flag can be set using SFTPGO_LOADDATA_MODE
  184. env var too.
  185. `)
  186. viper.BindPFlag(loadDataModeKey, cmd.Flags().Lookup(loadDataModeFlag)) //nolint:errcheck
  187. viper.SetDefault(loadDataQuotaScanKey, defaultLoadDataQuotaScan)
  188. viper.BindEnv(loadDataQuotaScanKey, "SFTPGO_LOADDATA_QUOTA_SCAN") //nolint:errcheck
  189. cmd.Flags().IntVar(&loadDataQuotaScan, loadDataQuotaScanFlag, viper.GetInt(loadDataQuotaScanKey),
  190. `Quota scan mode after data load:
  191. 0 - no quota scan
  192. 1 - scan quota
  193. 2 - scan quota if the user has quota restrictions
  194. This flag can be set using SFTPGO_LOADDATA_QUOTA_SCAN
  195. env var too.
  196. (default 0)`)
  197. viper.BindPFlag(loadDataQuotaScanKey, cmd.Flags().Lookup(loadDataQuotaScanFlag)) //nolint:errcheck
  198. viper.SetDefault(loadDataCleanKey, defaultLoadDataClean)
  199. viper.BindEnv(loadDataCleanKey, "SFTPGO_LOADDATA_CLEAN") //nolint:errcheck
  200. cmd.Flags().BoolVar(&loadDataClean, loadDataCleanFlag, viper.GetBool(loadDataCleanKey),
  201. `Determine if the loaddata-from file should
  202. be removed after a successful load. This flag
  203. can be set using SFTPGO_LOADDATA_CLEAN env var
  204. too. (default "false")
  205. `)
  206. viper.BindPFlag(logCompressKey, cmd.Flags().Lookup(logCompressFlag)) //nolint:errcheck
  207. }