Allow configuration of CLI config via env variables
**What** - Support configuration the faas-cli configuration directory path via the `OPENFAAS_CONFIG` env variable. When this value is set, the path will be overridden. When empty, we will also check the CI flag, which defaults the location to the current working directory. When neither `OPENFAAS_CONFIG` or `CI` are set, then the default location is in the current HOME folder. - Various tests have been updated to use this new env variable instead of modifying the global variables. Also, the variables are now constants to prevent this kind of modiication in general. Signed-off-by: Lucas Roesler <roesler.lucas@gmail.com>
This commit is contained in:
committed by
Alex Ellis
parent
6914d950c9
commit
d8c8e342c2
@@ -378,6 +378,8 @@ The [scripts/export-sealed-secret-pubcert.sh](https://github.com/openfaas-incuba
|
||||
* `OPENFAAS_TEMPLATE_URL` - to set the default URL to pull templates from
|
||||
* `OPENFAAS_PREFIX` - for use with `faas-cli new` - this can act in place of `--prefix`
|
||||
* `OPENFAAS_URL` - to override the default gateway URL
|
||||
* `OPENFAAS_CONFIG` - to override the location of the configuration folder, which contains auth configuration.
|
||||
* `CI` - to override the location of the configuration folder, when true, the configuration folder is `.openfaas` in the current working directory. This value is ignored if `OPENFAAS_CONFIG` is set.
|
||||
|
||||
### FaaS-CLI Developers / Contributors
|
||||
|
||||
|
||||
@@ -18,7 +18,20 @@ import (
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
//AuthType auth type
|
||||
type AuthType string
|
||||
|
||||
const (
|
||||
//BasicAuthType basic authentication type
|
||||
BasicAuthType = "basic"
|
||||
//Oauth2AuthType oauth2 authentication type
|
||||
Oauth2AuthType = "oauth2"
|
||||
|
||||
// ConfigLocationEnv is the name of he env variable used
|
||||
// to configure the location of the faas-cli config folder.
|
||||
// When not set, DefaultDir location is used.
|
||||
ConfigLocationEnv string = "OPENFAAS_CONFIG"
|
||||
|
||||
DefaultDir string = "~/.openfaas"
|
||||
DefaultFile string = "config.yml"
|
||||
DefaultPermissions os.FileMode = 0700
|
||||
@@ -31,16 +44,6 @@ var (
|
||||
DefaultCIPermissions os.FileMode = 0744
|
||||
)
|
||||
|
||||
//AuthType auth type
|
||||
type AuthType string
|
||||
|
||||
const (
|
||||
//BasicAuthType basic authentication type
|
||||
BasicAuthType = "basic"
|
||||
//Oauth2AuthType oauth2 authentication type
|
||||
Oauth2AuthType = "oauth2"
|
||||
)
|
||||
|
||||
// ConfigFile for OpenFaaS CLI exclusively.
|
||||
type ConfigFile struct {
|
||||
AuthConfigs []AuthConfig `yaml:"auths"`
|
||||
@@ -66,6 +69,28 @@ func New(filePath string) (*ConfigFile, error) {
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
// ConfigDir returns the path to the faas-cli config directory.
|
||||
// When
|
||||
// 1. CI = "true" and OPENFAAS_CONFIG="", then it will return `.openfaas`, which is located in the current working directory.
|
||||
// 2. CI = "true" and OPENFAAS_CONFIG="<path>", then it will return the path value in OPENFAAS_CONFIG
|
||||
// 3. CI = "" and OPENFAAS_CONFIG="", then it will return the default location ~/.openfaas
|
||||
func ConfigDir() string {
|
||||
override := os.Getenv(ConfigLocationEnv)
|
||||
ci := isRunningInCI()
|
||||
|
||||
switch {
|
||||
// case (1) from docs string
|
||||
case ci && override == "":
|
||||
return DefaultCIDir
|
||||
// case (2) from the doc string
|
||||
case override != "":
|
||||
// case (3) from the doc string
|
||||
return override
|
||||
default:
|
||||
return DefaultDir
|
||||
}
|
||||
}
|
||||
|
||||
// isRunningInCI checks the ENV var CI and returns true if it's set to true or 1
|
||||
func isRunningInCI() bool {
|
||||
if env, ok := os.LookupEnv("CI"); ok {
|
||||
@@ -79,10 +104,9 @@ func isRunningInCI() bool {
|
||||
// EnsureFile creates the root dir and config file
|
||||
func EnsureFile() (string, error) {
|
||||
permission := DefaultPermissions
|
||||
dir := DefaultDir
|
||||
dir := ConfigDir()
|
||||
if isRunningInCI() {
|
||||
permission = DefaultCIPermissions
|
||||
dir = DefaultCIDir
|
||||
}
|
||||
dirPath, err := homedir.Expand(dir)
|
||||
if err != nil {
|
||||
@@ -107,10 +131,7 @@ func EnsureFile() (string, error) {
|
||||
|
||||
// FileExists returns true if the config file is located at the default path
|
||||
func fileExists() bool {
|
||||
dir := DefaultDir
|
||||
if isRunningInCI() {
|
||||
dir = DefaultCIDir
|
||||
}
|
||||
dir := ConfigDir()
|
||||
dirPath, err := homedir.Expand(dir)
|
||||
if err != nil {
|
||||
return false
|
||||
|
||||
@@ -13,9 +13,16 @@ import (
|
||||
)
|
||||
|
||||
func Test_LookupAuthConfig_WithNoConfigFile(t *testing.T) {
|
||||
DefaultDir, _ = ioutil.TempDir("", "faas-cli-file-test")
|
||||
DefaultFile = "test1.yml"
|
||||
_, err := LookupAuthConfig("http://openfaas.test1")
|
||||
configDir, err := ioutil.TempDir("", "faas-cli-file-test")
|
||||
if err != nil {
|
||||
t.Fatalf("can not create test config directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(configDir)
|
||||
|
||||
os.Setenv(ConfigLocationEnv, configDir)
|
||||
defer os.Unsetenv(ConfigLocationEnv)
|
||||
|
||||
_, err = LookupAuthConfig("http://openfaas.test1")
|
||||
if err == nil {
|
||||
t.Errorf("Error was not returned")
|
||||
}
|
||||
@@ -27,15 +34,25 @@ func Test_LookupAuthConfig_WithNoConfigFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_LookupAuthConfig_GatewayWithNoConfig(t *testing.T) {
|
||||
DefaultDir, _ = ioutil.TempDir("", "faas-cli-file-test")
|
||||
DefaultFile = "test2.yml"
|
||||
configDir, err := ioutil.TempDir("", "faas-cli-file-test")
|
||||
if err != nil {
|
||||
t.Fatalf("can not create test config directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(configDir)
|
||||
|
||||
os.Setenv(ConfigLocationEnv, configDir)
|
||||
defer os.Unsetenv(ConfigLocationEnv)
|
||||
|
||||
u := "admin"
|
||||
p := "some pass"
|
||||
gatewayURL := strings.TrimRight("http://openfaas.test/", "/")
|
||||
token := EncodeAuth(u, p)
|
||||
UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
err = UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when updating auth config: %s", err)
|
||||
}
|
||||
|
||||
_, err := LookupAuthConfig("http://openfaas.com")
|
||||
_, err = LookupAuthConfig("http://openfaas.com")
|
||||
if err == nil {
|
||||
t.Errorf("Error was not returned")
|
||||
}
|
||||
@@ -47,13 +64,23 @@ func Test_LookupAuthConfig_GatewayWithNoConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_UpdateAuthConfig_Insert(t *testing.T) {
|
||||
DefaultDir, _ = ioutil.TempDir("", "faas-cli-file-test")
|
||||
DefaultFile = "test2.yml"
|
||||
configDir, err := ioutil.TempDir("", "faas-cli-file-test")
|
||||
if err != nil {
|
||||
t.Fatalf("can not create test config directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(configDir)
|
||||
|
||||
os.Setenv(ConfigLocationEnv, configDir)
|
||||
defer os.Unsetenv(ConfigLocationEnv)
|
||||
|
||||
u := "admin"
|
||||
p := "some pass"
|
||||
gatewayURL := strings.TrimRight("http://openfaas.test/", "/")
|
||||
token := EncodeAuth(u, p)
|
||||
UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
err = UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when updating auth config: %s", err)
|
||||
}
|
||||
|
||||
authConfig, err := LookupAuthConfig(gatewayURL)
|
||||
if err != nil {
|
||||
@@ -73,13 +100,23 @@ func Test_UpdateAuthConfig_Insert(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_UpdateAuthConfig_Update(t *testing.T) {
|
||||
DefaultDir, _ = ioutil.TempDir("", "faas-cli-file-test")
|
||||
DefaultFile = "test3.yml"
|
||||
configDir, err := ioutil.TempDir("", "faas-cli-file-test")
|
||||
if err != nil {
|
||||
t.Fatalf("can not create test config directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(configDir)
|
||||
|
||||
os.Setenv(ConfigLocationEnv, configDir)
|
||||
defer os.Unsetenv(ConfigLocationEnv)
|
||||
|
||||
u := "admin"
|
||||
p := "pass"
|
||||
gatewayURL := strings.TrimRight("http://openfaas.test/", "/")
|
||||
token := EncodeAuth(u, p)
|
||||
UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
err = UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when updating auth config: %s", err)
|
||||
}
|
||||
|
||||
authConfig, err := LookupAuthConfig(gatewayURL)
|
||||
if err != nil {
|
||||
@@ -97,7 +134,10 @@ func Test_UpdateAuthConfig_Update(t *testing.T) {
|
||||
u = "admin2"
|
||||
p = "pass2"
|
||||
token = EncodeAuth(u, p)
|
||||
UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
err = UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when updating auth config: %s", err)
|
||||
}
|
||||
|
||||
authConfig, err = LookupAuthConfig(gatewayURL)
|
||||
if err != nil {
|
||||
@@ -148,13 +188,21 @@ func Test_New_NoFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_EnsureFile(t *testing.T) {
|
||||
DefaultDir, _ = ioutil.TempDir("", "faas-cli-file-test")
|
||||
DefaultFile = "test6.yml"
|
||||
configDir, err := ioutil.TempDir("", "faas-cli-file-test")
|
||||
if err != nil {
|
||||
t.Fatalf("can not create test config directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(configDir)
|
||||
|
||||
os.Setenv(ConfigLocationEnv, configDir)
|
||||
defer os.Unsetenv(ConfigLocationEnv)
|
||||
|
||||
cfg, err := EnsureFile()
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if _, err := os.Stat(cfg); os.IsNotExist(err) {
|
||||
_, err = os.Stat(cfg)
|
||||
if os.IsNotExist(err) {
|
||||
t.Errorf("expected config at %s", cfg)
|
||||
}
|
||||
}
|
||||
@@ -174,19 +222,31 @@ func Test_DecodeAuth(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_RemoveAuthConfig(t *testing.T) {
|
||||
DefaultDir, _ = ioutil.TempDir("", "faas-cli-file-test")
|
||||
DefaultFile = "test7.yml"
|
||||
configDir, err := ioutil.TempDir("", "faas-cli-file-test")
|
||||
if err != nil {
|
||||
t.Fatalf("can not create test config directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(configDir)
|
||||
|
||||
os.Setenv(ConfigLocationEnv, configDir)
|
||||
defer os.Unsetenv(ConfigLocationEnv)
|
||||
|
||||
u := "admin"
|
||||
p := "pass"
|
||||
token := EncodeAuth(u, p)
|
||||
gatewayURL := strings.TrimRight("http://openfaas.test/", "/")
|
||||
UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
err = UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when updating auth config: %s", err)
|
||||
}
|
||||
|
||||
gatewayURL2 := strings.TrimRight("http://openfaas.test2/", "/")
|
||||
UpdateAuthConfig(gatewayURL2, token, BasicAuthType)
|
||||
err = UpdateAuthConfig(gatewayURL2, token, BasicAuthType)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when updating auth config: %s", err)
|
||||
}
|
||||
|
||||
err := RemoveAuthConfig(gatewayURL)
|
||||
err = RemoveAuthConfig(gatewayURL)
|
||||
if err != nil {
|
||||
t.Errorf("got error %s", err.Error())
|
||||
}
|
||||
@@ -202,9 +262,16 @@ func Test_RemoveAuthConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_RemoveAuthConfig_WithNoConfigFile(t *testing.T) {
|
||||
DefaultDir, _ = ioutil.TempDir("", "faas-cli-file-test")
|
||||
DefaultFile = "test8.yml"
|
||||
err := RemoveAuthConfig("http://openfaas.test1")
|
||||
configDir, err := ioutil.TempDir("", "faas-cli-file-test")
|
||||
if err != nil {
|
||||
t.Fatalf("can not create test config directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(configDir)
|
||||
|
||||
os.Setenv(ConfigLocationEnv, configDir)
|
||||
defer os.Unsetenv(ConfigLocationEnv)
|
||||
|
||||
err = RemoveAuthConfig("http://openfaas.test1")
|
||||
if err == nil {
|
||||
t.Errorf("Error was not returned")
|
||||
}
|
||||
@@ -216,16 +283,25 @@ func Test_RemoveAuthConfig_WithNoConfigFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_RemoveAuthConfig_WithUnknownGateway(t *testing.T) {
|
||||
DefaultDir, _ = ioutil.TempDir("", "faas-cli-file-test")
|
||||
DefaultFile = "test9.yml"
|
||||
configDir, err := ioutil.TempDir("", "faas-cli-file-test")
|
||||
if err != nil {
|
||||
t.Fatalf("can not create test config directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(configDir)
|
||||
|
||||
os.Setenv(ConfigLocationEnv, configDir)
|
||||
defer os.Unsetenv(ConfigLocationEnv)
|
||||
|
||||
u := "admin"
|
||||
p := "pass"
|
||||
token := EncodeAuth(u, p)
|
||||
gatewayURL := strings.TrimRight("http://openfaas.test/", "/")
|
||||
UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
err = UpdateAuthConfig(gatewayURL, token, BasicAuthType)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when updating auth config: %s", err)
|
||||
}
|
||||
|
||||
err := RemoveAuthConfig("http://openfaas.test1")
|
||||
err = RemoveAuthConfig("http://openfaas.test1")
|
||||
if err == nil {
|
||||
t.Errorf("Error was not returned")
|
||||
}
|
||||
@@ -237,11 +313,21 @@ func Test_RemoveAuthConfig_WithUnknownGateway(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_UpdateAuthConfig_Oauth2Insert(t *testing.T) {
|
||||
DefaultDir, _ = ioutil.TempDir("", "faas-cli-file-test")
|
||||
DefaultFile = "test2.yml"
|
||||
configDir, err := ioutil.TempDir("", "faas-cli-file-test")
|
||||
if err != nil {
|
||||
t.Fatalf("can not create test config directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(configDir)
|
||||
|
||||
os.Setenv(ConfigLocationEnv, configDir)
|
||||
defer os.Unsetenv(ConfigLocationEnv)
|
||||
|
||||
token := "somebase64encodedstring"
|
||||
gatewayURL := strings.TrimRight("http://openfaas.test/", "/")
|
||||
UpdateAuthConfig(gatewayURL, token, Oauth2AuthType)
|
||||
err = UpdateAuthConfig(gatewayURL, token, Oauth2AuthType)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when updating auth config: %s", err)
|
||||
}
|
||||
|
||||
authConfig, err := LookupAuthConfig(gatewayURL)
|
||||
if err != nil {
|
||||
@@ -253,3 +339,70 @@ func Test_UpdateAuthConfig_Oauth2Insert(t *testing.T) {
|
||||
t.Errorf("got token %s, expected %s", authConfig.Token, token)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_ConfigDir(t *testing.T) {
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
env map[string]string
|
||||
expectedPath string
|
||||
}{
|
||||
{
|
||||
name: "override value is returned",
|
||||
env: map[string]string{
|
||||
"OPENFAAS_CONFIG": "/tmp/foo",
|
||||
},
|
||||
expectedPath: "/tmp/foo",
|
||||
},
|
||||
{
|
||||
name: "override value is returned, when CI is set but false",
|
||||
env: map[string]string{
|
||||
"OPENFAAS_CONFIG": "/tmp/foo",
|
||||
"CI": "false",
|
||||
},
|
||||
expectedPath: "/tmp/foo",
|
||||
},
|
||||
{
|
||||
name: "override value is returned even when CI is set",
|
||||
env: map[string]string{
|
||||
"OPENFAAS_CONFIG": "/tmp/foo",
|
||||
"CI": "true",
|
||||
},
|
||||
expectedPath: "/tmp/foo",
|
||||
},
|
||||
{
|
||||
name: "when CI is true, return the default CI directory",
|
||||
env: map[string]string{
|
||||
"CI": "true",
|
||||
},
|
||||
expectedPath: DefaultCIDir,
|
||||
},
|
||||
{
|
||||
name: "when CI is false, return the default directory",
|
||||
env: map[string]string{
|
||||
"CI": "false",
|
||||
},
|
||||
expectedPath: DefaultDir,
|
||||
},
|
||||
{
|
||||
name: "when no other env variables are set, the default path is returned",
|
||||
expectedPath: DefaultDir,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
||||
for name, value := range tc.env {
|
||||
os.Setenv(name, value)
|
||||
defer os.Unsetenv(name)
|
||||
}
|
||||
|
||||
path := ConfigDir()
|
||||
if path != tc.expectedPath {
|
||||
t.Fatalf("expected config path '%s', got '%s'", tc.expectedPath, path)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user