diff --git a/README.md b/README.md index 4a4890de..c8cc7812 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ apt-get update apt-get install plikd plik ``` -Edit server configuration at /etc/plikd.cfg and start the server +Edit server configuration at /etc/plikd.cfg and start the server ``` service plikd start ``` @@ -376,4 +376,18 @@ See : https://github.com/golang/go/wiki/GoArm server/plikd: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, Go ... Then either copy the binary from the docker or play with releaser/releaser.sh to generate a release archive +``` + +* Defining configuration parameters using environment variables + +One can specify configuration parameters using env variable with the configuration parameter in screaming snake case +``` + PLIKD_DEBUG_REQUESTS=true ./plikd +``` + +For Arrays and config maps they must be provided in json format. +Arrays are overriden but maps are merged + +``` + PLIKD_DATA_BACKEND_CONFIG='{"Directory":"/var/files"}' ./plikd ``` \ No newline at end of file diff --git a/go.mod b/go.mod index b92ad990..507e993d 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/google/uuid v1.1.2 // indirect github.com/gorilla/mux v1.7.1 github.com/hashicorp/golang-lru v0.5.1 // indirect - github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 // indirect + github.com/iancoleman/strcase v0.1.2 github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a github.com/jinzhu/gorm v1.9.13-0.20200126152832-7180bd0f27d1 github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 @@ -31,7 +31,7 @@ require ( github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 github.com/pilagod/gorm-cursor-paginator v1.2.0 github.com/root-gg/logger v0.0.0-20150501173826-5d9a47a35312 - github.com/root-gg/utils v0.0.0-20151025161626-38f45ede2ce2 + github.com/root-gg/utils v0.0.0-20201113182430-4cef83d8cdcf github.com/spf13/cobra v0.0.6-0.20200106181057-89c7ffb5129b github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.4.0 diff --git a/go.sum b/go.sum index 7feaaf86..484b33b6 100644 --- a/go.sum +++ b/go.sum @@ -104,8 +104,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= -github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 h1:VHgatEHNcBFEB7inlalqfNqw65aNkM1lGX2yt3NmbS8= -github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= +github.com/iancoleman/strcase v0.1.2 h1:gnomlvw9tnV3ITTAxzKSgTF+8kFWcU/f+TgttpXGz1U= +github.com/iancoleman/strcase v0.1.2/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o= @@ -216,6 +216,8 @@ github.com/root-gg/logger v0.0.0-20150501173826-5d9a47a35312 h1:gLYLMWhdoU02+VLb github.com/root-gg/logger v0.0.0-20150501173826-5d9a47a35312/go.mod h1:SZ5sf0POVtIvp+vNCGYwJp1/ZT6/nShOau6aVMGgtGU= github.com/root-gg/utils v0.0.0-20151025161626-38f45ede2ce2 h1:2IC5+HunAKLL0GxcXtqbsQxEOmDcFTf8gn34mxpTs20= github.com/root-gg/utils v0.0.0-20151025161626-38f45ede2ce2/go.mod h1:XF39UJcqum+uYclrw+wB0V1qg9vgglJ8gz8AMrVJ/AQ= +github.com/root-gg/utils v0.0.0-20201113182430-4cef83d8cdcf h1:Qx8jlCUW4X3+W+k14GCr33IBh/jYt+kaV/AzZWrl4vk= +github.com/root-gg/utils v0.0.0-20201113182430-4cef83d8cdcf/go.mod h1:XF39UJcqum+uYclrw+wB0V1qg9vgglJ8gz8AMrVJ/AQ= github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/server/cmd/root.go b/server/cmd/root.go index 5c94a957..7bdc450a 100644 --- a/server/cmd/root.go +++ b/server/cmd/root.go @@ -94,13 +94,9 @@ func initConfig() { } } - if configPath != "" { - config, err = common.LoadConfiguration(configPath) - if err != nil { - fmt.Printf("Unable to read config file : %s\n", err) - } - } else { - config = common.NewConfiguration() + config, err = common.LoadConfiguration(configPath) + if err != nil { + fmt.Printf("Unable to load config : %s\n", err) } } diff --git a/server/common/config.go b/server/common/config.go index 86115078..62104f76 100644 --- a/server/common/config.go +++ b/server/common/config.go @@ -4,15 +4,21 @@ import ( "fmt" "net" "net/url" + "os" "strings" "time" + "github.com/root-gg/utils" + "github.com/BurntSushi/toml" "github.com/dustin/go-humanize" + "github.com/iancoleman/strcase" "github.com/root-gg/logger" ) +const envPrefix = "PLIKD_" + // Configuration object type Configuration struct { Debug bool `json:"-"` @@ -96,11 +102,18 @@ func NewConfiguration() (config *Configuration) { // LoadConfiguration creates a new empty configuration // and try to load specified file with toml library to // override default params -func LoadConfiguration(file string) (config *Configuration, err error) { +func LoadConfiguration(path string) (config *Configuration, err error) { config = NewConfiguration() - if _, err := toml.DecodeFile(file, config); err != nil { - return nil, fmt.Errorf("unable to load config file %s : %s", file, err) + if path != "" { + if _, err := toml.DecodeFile(path, config); err != nil { + return nil, fmt.Errorf("unable to load config file %s : %s", path, err) + } + } + + err = config.EnvironmentOverride() + if err != nil { + return nil, err } err = config.Initialize() @@ -111,6 +124,15 @@ func LoadConfiguration(file string) (config *Configuration, err error) { return config, nil } +// EnvironmentOverride override config from environment variables +// Environment variables must match config params in screaming snake case ( DebugRequests -> PLIKD_DEBUG_REQUESTS ) +func (config *Configuration) EnvironmentOverride() (err error) { + getEnvOverride := func(fieldName string) (string, bool) { + return os.LookupEnv(envPrefix + strcase.ToScreamingSnake(fieldName)) + } + return utils.AssignStrings(config, getEnvOverride) +} + // Initialize config internal parameters func (config *Configuration) Initialize() (err error) { diff --git a/server/common/config_test.go b/server/common/config_test.go index fd5d5ea4..482b2adc 100644 --- a/server/common/config_test.go +++ b/server/common/config_test.go @@ -2,11 +2,20 @@ package common import ( "net" + "os" "testing" + "github.com/iancoleman/strcase" + "github.com/stretchr/testify/require" ) +func TestToScreamingSnakeCase(t *testing.T) { + require.Equal(t, "DEBUG_REQUESTS", strcase.ToScreamingSnake("DebugRequests")) + require.Equal(t, "DEFAULT_TTL", strcase.ToScreamingSnake("DefaultTTL")) + require.Equal(t, "GOOGLE_API_CLIENT_ID", strcase.ToScreamingSnake("GoogleAPIClientID")) +} + // Test new configuration func TestNewConfig(t *testing.T) { config := NewConfiguration() @@ -116,3 +125,38 @@ func TestString(t *testing.T) { config := NewConfiguration() require.NotEmpty(t, config.String()) } + +func TestConfiguration_EnvironmentOverride(t *testing.T) { + defer func() { + _ = os.Unsetenv(envPrefix + "DEBUG") + _ = os.Unsetenv(envPrefix + "LISTEN_ADDRESS") + _ = os.Unsetenv(envPrefix + "MAX_FILE_SIZE") + _ = os.Unsetenv(envPrefix + "UPLOAD_WHITELIST") + _ = os.Unsetenv(envPrefix + "METADATA_BACKEND_CONFIG") + }() + + err := os.Setenv(envPrefix+"DEBUG", "true") + require.NoError(t, err) + + err = os.Setenv(envPrefix+"LISTEN_ADDRESS", "1.2.3.4") + require.NoError(t, err) + + err = os.Setenv(envPrefix+"MAX_FILE_SIZE", "42") + require.NoError(t, err) + + err = os.Setenv(envPrefix+"UPLOAD_WHITELIST", "[\"127.0.0.1\"]") + require.NoError(t, err) + + err = os.Setenv(envPrefix+"METADATA_BACKEND_CONFIG", "{\"path\": \"files\"}") + require.NoError(t, err) + + config := NewConfiguration() + err = config.EnvironmentOverride() + require.NoError(t, err) + + require.True(t, config.Debug) + require.Equal(t, "1.2.3.4", config.ListenAddress) + require.Equal(t, int64(42), config.MaxFileSize) + require.EqualValues(t, []string{"127.0.0.1"}, config.UploadWhitelist) + require.EqualValues(t, map[string]interface{}{"path": "files"}, config.MetadataBackendConfig) +}