Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config with env #1072

Merged
merged 3 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions doc/cookbook/multi-node-cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [Deploy an Easegress Cluster Step by Step](#deploy-an-easegress-cluster-step-by-step)
- [Add New Member](#add-new-member)
- [YAML Configuration (optional)](#yaml-configuration-optional)
- [Flags and Environment Variables](#flags-and-environment-variables)
- [Configuration tips (optional)](#configuration-tips-optional)
- [References](#references)

Expand Down Expand Up @@ -187,6 +188,51 @@ cluster:
- http:https://$HOST1:2380
```

## Flags and Environment Variables

In addition to deploying the easegress-server using command-line flags or a YAML file, you can also utilize environment variables. Below are all the available environment variables along with their corresponding flags.

```
EASEGRESS_NAME: --name
EASEGRESS_LABELS: --labels
EASEGRESS_CONFIG_FILE: --config-file
EASEGRESS_FORCE_NEW_CLUSTER: --force-new-cluster
EASEGRESS_SIGNAL_UPGRADE: --signal-upgrade
EASEGRESS_USE_STANDALONE_ETCD: --use-standalone-etcd

EASEGRESS_CLUSTER_NAME: --cluster-name
EASEGRESS_CLUSTER_ROLE: --cluster-role
EASEGRESS_CLUSTER_REQUEST_TIMEOUT: --cluster-request-timeout

EASEGRESS_LISTEN_CLIENT_URLS: --listen-client-urls
EASEGRESS_LISTEN_PEER_URLS: --listen-peer-urls
EASEGRESS_ADVERTISE_CLIENT_URLS: --advertise-client-urls
EASEGRESS_INITIAL_ADVERTISE_PEER_URLS: --initial-advertise-peer-urls
EASEGRESS_INITIAL_CLUSTER: --initial-cluster
EASEGRESS_STATE_FLAG: --state-flag
EASEGRESS_PRIMARY_LISTEN_PEER_URLS: --primary-listen-peer-urls
EASEGRESS_MAX_CALL_SEND_MSG_SIZE: --max-call-send-msg-size

EASEGRESS_API_ADDR: --api-addr
EASEGRESS_TLS: --tls
EASEGRESS_CERT_FILE: --cert-file
EASEGRESS_KEY_FILE: --key-file
EASEGRESS_DEBUG: --debug
EASEGRESS_DISABLE_ACCESS: --disable-access
EASEGRESS_OBJECTS_DUMP_INTERVAL: --objects-dump-interval
EASEGRESS_INITIAL_OBJECT_CONFIG_FILES: --initial-object-config-files

EASEGRESS_HOME_DIR: --home-dir
EASEGRESS_DATA_DIR: --data-dir
EASEGRESS_WAL_DIR: --wal-dir
EASEGRESS_LOG_DIR: --log-dir
EASEGRESS_MEMBER_DIR: --member-dir

EASEGRESS_CPU_PROFILE_FILE: --cpu-profile-file
EASEGRESS_MEMORY_PROFILE_FILE: --memory-profile-file
EASEGRESS_STATUS_UPDATE_MAX_BATCH_SIZE: --status-update-max-batch-size
```

## Configuration tips (optional)

*What is a good size for the cluster?*
Expand Down
52 changes: 52 additions & 0 deletions pkg/option/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2017, MegaEase
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http:https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package option

import (
"fmt"
"os"
"strings"

"github.com/spf13/pflag"
)

// SetFlagsFromEnv sets flags from environment variables.
func SetFlagsFromEnv(prefix string, fs *pflag.FlagSet) error {
var err error
fs.VisitAll(func(f *pflag.Flag) {
if err2 := setFlagFromEnv(fs, prefix, f.Name); err2 != nil {
err = err2
}
})
return err
}

func flagToEnv(prefix, name string) string {
return prefix + "_" + strings.ToUpper(strings.ReplaceAll(name, "-", "_"))
}

func setFlagFromEnv(fs *pflag.FlagSet, prefix, flagName string) error {
key := flagToEnv(prefix, flagName)
val := os.Getenv(key)
if val != "" {
if err := fs.Set(flagName, val); err != nil {
return fmt.Errorf("invalid value %q for %s: %v", val, key, err)
}
}
return nil
}
126 changes: 126 additions & 0 deletions pkg/option/env_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2017, MegaEase
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http:https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package option

import (
"os"
"strings"
"testing"

"github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
)

func resetEnv() func() {
envs := os.Environ()
return func() {
os.Clearenv()
for _, env := range envs {
kv := strings.SplitN(env, "=", 2)
os.Setenv(kv[0], kv[1])
}
}
}

func TestSetFlagsFromEnv(t *testing.T) {
assert := assert.New(t)

reset := resetEnv()
defer reset()
os.Setenv("EASEGRESS_TEST_STRING", "test")
os.Setenv("EASEGRESS_TEST_BOOL", "true")
os.Setenv("EASEGRESS_TEST_ARRAY", "a,b,c")
os.Setenv("EASEGRESS_TEST_INT", "1")

var stringFlag string
var boolFlag bool
var arrayFlag []string
var intFlag int
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
flags.StringVar(&stringFlag, "test-string", "", "test string flag")
flags.BoolVar(&boolFlag, "test-bool", false, "test bool flag")
flags.StringSliceVar(&arrayFlag, "test-array", []string{}, "test array flag")
flags.IntVar(&intFlag, "test-int", 0, "test int flag")

err := SetFlagsFromEnv("EASEGRESS", flags)
assert.NoError(err)
assert.Equal("test", stringFlag)
assert.Equal(true, boolFlag)
assert.Equal([]string{"a", "b", "c"}, arrayFlag)
assert.Equal(1, intFlag)
}

func TestSetFlagsFromEnvFail(t *testing.T) {
assert := assert.New(t)

reset := resetEnv()
defer reset()
os.Setenv("EASEGRESS_TEST_BOOL", "123")

var boolFlag bool
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
flags.BoolVar(&boolFlag, "test-bool", false, "test bool flag")

err := SetFlagsFromEnv("EASEGRESS", flags)
assert.Error(err)

os.Setenv("EASEGRESS_VERSION", "not-a-bool")
// options from env
opt := New()
err = opt.Parse()
assert.Error(err)
}

func TestOptionFromEnv(t *testing.T) {
assert := assert.New(t)

reset := resetEnv()
defer reset()
os.Setenv("EASEGRESS_NAME", "test-option-from-env")
os.Setenv("EASEGRESS_HOME_DIR", "./test-home-dir")
os.Setenv("EASEGRESS_LOG_DIR", "./test-log-dir")
os.Setenv("EASEGRESS_NAME", "test-option-from-env")
os.Setenv("EASEGRESS_LISTEN_CLIENT_URLS", "http:https://localhost:2379,http:https://localhost:10080")

{
// options from env
opt := New()
err := opt.Parse()
assert.NoError(err)
assert.Equal("test-option-from-env", opt.Name)
assert.Equal("./test-home-dir", opt.HomeDir)
assert.Equal("./test-log-dir", opt.LogDir)
assert.Equal([]string{"http:https://localhost:2379", "http:https://localhost:10080"}, opt.Cluster.ListenClientURLs)
}

{
args := os.Args
defer func() {
os.Args = args
}()
os.Args = []string{"easegress-server", "--name=test-option-from-args", "--home-dir=./test-home-dir-from-args", "--log-dir=./test-log-dir-from-args"}
// options from env and args
opt := New()
err := opt.Parse()
assert.NoError(err)
assert.Equal("test-option-from-args", opt.Name)
assert.Equal("./test-home-dir-from-args", opt.HomeDir)
assert.Equal("./test-log-dir-from-args", opt.LogDir)
assert.Equal([]string{"http:https://localhost:2379", "http:https://localhost:10080"}, opt.Cluster.ListenClientURLs)
}
}
6 changes: 5 additions & 1 deletion pkg/option/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,11 @@ func (opt *Options) renameLegacyClusterRoles() {
// Parse parses all arguments, when the user wants to display version information or view help,
// we do not execute subsequent logic and return directly.
func (opt *Options) Parse() error {
err := opt.flags.Parse(os.Args[1:])
err := SetFlagsFromEnv("EASEGRESS", opt.flags)
if err != nil {
return err
}
err = opt.flags.Parse(os.Args[1:])
if err != nil {
return err
}
Expand Down
Loading