mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-09 08:15:13 +03:00
allow to customize timeout and env vars for program based hooks
Fixes #847 Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/drakkan/sftpgo/v2/command"
|
||||
"github.com/drakkan/sftpgo/v2/common"
|
||||
"github.com/drakkan/sftpgo/v2/dataprovider"
|
||||
"github.com/drakkan/sftpgo/v2/ftpd"
|
||||
@@ -139,6 +140,7 @@ type globalConfig struct {
|
||||
ProviderConf dataprovider.Config `json:"data_provider" mapstructure:"data_provider"`
|
||||
HTTPDConfig httpd.Conf `json:"httpd" mapstructure:"httpd"`
|
||||
HTTPConfig httpclient.Config `json:"http" mapstructure:"http"`
|
||||
CommandConfig command.Config `json:"command" mapstructure:"command"`
|
||||
KMSConfig kms.Configuration `json:"kms" mapstructure:"kms"`
|
||||
MFAConfig mfa.Config `json:"mfa" mapstructure:"mfa"`
|
||||
TelemetryConfig telemetry.Conf `json:"telemetry" mapstructure:"telemetry"`
|
||||
@@ -353,6 +355,11 @@ func Init() {
|
||||
SkipTLSVerify: false,
|
||||
Headers: nil,
|
||||
},
|
||||
CommandConfig: command.Config{
|
||||
Timeout: 30,
|
||||
Env: nil,
|
||||
Commands: nil,
|
||||
},
|
||||
KMSConfig: kms.Configuration{
|
||||
Secrets: kms.Secrets{
|
||||
URL: "",
|
||||
@@ -461,6 +468,11 @@ func GetHTTPConfig() httpclient.Config {
|
||||
return globalConf.HTTPConfig
|
||||
}
|
||||
|
||||
// GetCommandConfig returns the configuration for external commands
|
||||
func GetCommandConfig() command.Config {
|
||||
return globalConf.CommandConfig
|
||||
}
|
||||
|
||||
// GetKMSConfig returns the KMS configuration
|
||||
func GetKMSConfig() kms.Configuration {
|
||||
return globalConf.KMSConfig
|
||||
@@ -674,6 +686,7 @@ func loadBindingsFromEnv() {
|
||||
getHTTPDBindingFromEnv(idx)
|
||||
getHTTPClientCertificatesFromEnv(idx)
|
||||
getHTTPClientHeadersFromEnv(idx)
|
||||
getCommandConfigsFromEnv(idx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1546,6 +1559,9 @@ func getHTTPClientCertificatesFromEnv(idx int) {
|
||||
|
||||
func getHTTPClientHeadersFromEnv(idx int) {
|
||||
header := httpclient.Header{}
|
||||
if len(globalConf.HTTPConfig.Headers) > idx {
|
||||
header = globalConf.HTTPConfig.Headers[idx]
|
||||
}
|
||||
|
||||
key, ok := os.LookupEnv(fmt.Sprintf("SFTPGO_HTTP__HEADERS__%v__KEY", idx))
|
||||
if ok {
|
||||
@@ -1571,6 +1587,36 @@ func getHTTPClientHeadersFromEnv(idx int) {
|
||||
}
|
||||
}
|
||||
|
||||
func getCommandConfigsFromEnv(idx int) {
|
||||
cfg := command.Command{}
|
||||
if len(globalConf.CommandConfig.Commands) > idx {
|
||||
cfg = globalConf.CommandConfig.Commands[idx]
|
||||
}
|
||||
|
||||
path, ok := os.LookupEnv(fmt.Sprintf("SFTPGO_COMMAND__COMMANDS__%v__PATH", idx))
|
||||
if ok {
|
||||
cfg.Path = path
|
||||
}
|
||||
|
||||
timeout, ok := lookupIntFromEnv(fmt.Sprintf("SFTPGO_COMMAND__COMMANDS__%v__TIMEOUT", idx))
|
||||
if ok {
|
||||
cfg.Timeout = int(timeout)
|
||||
}
|
||||
|
||||
env, ok := lookupStringListFromEnv(fmt.Sprintf("SFTPGO_COMMAND__COMMANDS__%v__ENV", idx))
|
||||
if ok {
|
||||
cfg.Env = env
|
||||
}
|
||||
|
||||
if cfg.Path != "" {
|
||||
if len(globalConf.CommandConfig.Commands) > idx {
|
||||
globalConf.CommandConfig.Commands[idx] = cfg
|
||||
} else {
|
||||
globalConf.CommandConfig.Commands = append(globalConf.CommandConfig.Commands, cfg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setViperDefaults() {
|
||||
viper.SetDefault("common.idle_timeout", globalConf.Common.IdleTimeout)
|
||||
viper.SetDefault("common.upload_mode", globalConf.Common.UploadMode)
|
||||
@@ -1714,6 +1760,8 @@ func setViperDefaults() {
|
||||
viper.SetDefault("http.retry_max", globalConf.HTTPConfig.RetryMax)
|
||||
viper.SetDefault("http.ca_certificates", globalConf.HTTPConfig.CACertificates)
|
||||
viper.SetDefault("http.skip_tls_verify", globalConf.HTTPConfig.SkipTLSVerify)
|
||||
viper.SetDefault("command.timeout", globalConf.CommandConfig.Timeout)
|
||||
viper.SetDefault("command.env", globalConf.CommandConfig.Env)
|
||||
viper.SetDefault("kms.secrets.url", globalConf.KMSConfig.Secrets.URL)
|
||||
viper.SetDefault("kms.secrets.master_key", globalConf.KMSConfig.Secrets.MasterKeyString)
|
||||
viper.SetDefault("kms.secrets.master_key_path", globalConf.KMSConfig.Secrets.MasterKeyPath)
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/drakkan/sftpgo/v2/command"
|
||||
"github.com/drakkan/sftpgo/v2/common"
|
||||
"github.com/drakkan/sftpgo/v2/config"
|
||||
"github.com/drakkan/sftpgo/v2/dataprovider"
|
||||
@@ -679,6 +680,69 @@ func TestSFTPDBindingsFromEnv(t *testing.T) {
|
||||
require.True(t, bindings[1].ApplyProxyConfig) // default value
|
||||
}
|
||||
|
||||
func TestCommandsFromEnv(t *testing.T) {
|
||||
reset()
|
||||
|
||||
configDir := ".."
|
||||
confName := tempConfigName + ".json"
|
||||
configFilePath := filepath.Join(configDir, confName)
|
||||
err := config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
commandConfig := config.GetCommandConfig()
|
||||
commandConfig.Commands = append(commandConfig.Commands, command.Command{
|
||||
Path: "cmd",
|
||||
Timeout: 10,
|
||||
Env: []string{"a=a"},
|
||||
})
|
||||
c := make(map[string]command.Config)
|
||||
c["command"] = commandConfig
|
||||
jsonConf, err := json.Marshal(c)
|
||||
require.NoError(t, err)
|
||||
err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
|
||||
require.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, confName)
|
||||
require.NoError(t, err)
|
||||
commandConfig = config.GetCommandConfig()
|
||||
require.Equal(t, 30, commandConfig.Timeout)
|
||||
require.Len(t, commandConfig.Env, 0)
|
||||
require.Len(t, commandConfig.Commands, 1)
|
||||
require.Equal(t, "cmd", commandConfig.Commands[0].Path)
|
||||
require.Equal(t, 10, commandConfig.Commands[0].Timeout)
|
||||
require.Equal(t, []string{"a=a"}, commandConfig.Commands[0].Env)
|
||||
|
||||
os.Setenv("SFTPGO_COMMAND__TIMEOUT", "25")
|
||||
os.Setenv("SFTPGO_COMMAND__ENV", "a=b,c=d")
|
||||
os.Setenv("SFTPGO_COMMAND__COMMANDS__0__PATH", "cmd1")
|
||||
os.Setenv("SFTPGO_COMMAND__COMMANDS__0__TIMEOUT", "11")
|
||||
os.Setenv("SFTPGO_COMMAND__COMMANDS__1__PATH", "cmd2")
|
||||
os.Setenv("SFTPGO_COMMAND__COMMANDS__1__TIMEOUT", "20")
|
||||
os.Setenv("SFTPGO_COMMAND__COMMANDS__1__ENV", "e=f")
|
||||
|
||||
t.Cleanup(func() {
|
||||
os.Unsetenv("SFTPGO_COMMAND__TIMEOUT")
|
||||
os.Unsetenv("SFTPGO_COMMAND__ENV")
|
||||
os.Unsetenv("SFTPGO_COMMAND__COMMANDS__0__PATH")
|
||||
os.Unsetenv("SFTPGO_COMMAND__COMMANDS__0__TIMEOUT")
|
||||
os.Unsetenv("SFTPGO_COMMAND__COMMANDS__0__ENV")
|
||||
})
|
||||
|
||||
err = config.LoadConfig(configDir, confName)
|
||||
assert.NoError(t, err)
|
||||
commandConfig = config.GetCommandConfig()
|
||||
require.Equal(t, 25, commandConfig.Timeout)
|
||||
require.Equal(t, []string{"a=b", "c=d"}, commandConfig.Env)
|
||||
require.Len(t, commandConfig.Commands, 2)
|
||||
require.Equal(t, "cmd1", commandConfig.Commands[0].Path)
|
||||
require.Equal(t, 11, commandConfig.Commands[0].Timeout)
|
||||
require.Equal(t, []string{"a=a"}, commandConfig.Commands[0].Env)
|
||||
require.Equal(t, "cmd2", commandConfig.Commands[1].Path)
|
||||
require.Equal(t, 20, commandConfig.Commands[1].Timeout)
|
||||
require.Equal(t, []string{"e=f"}, commandConfig.Commands[1].Env)
|
||||
|
||||
err = os.Remove(configFilePath)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestFTPDBindingsFromEnv(t *testing.T) {
|
||||
reset()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user