From fa6b744a3c5e3b69d1120ad55014dfe5fad78cd2 Mon Sep 17 00:00:00 2001 From: Michael Tharp Date: Tue, 3 Jul 2018 14:46:46 +0000 Subject: [PATCH] Support use of environment variables to configure the client --- cmdline/remotecmd/client.go | 4 ++-- cmdline/shared/util.go | 37 +++++++++++++++++++++++++---- config/env.go | 47 +++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 config/env.go diff --git a/cmdline/remotecmd/client.go b/cmdline/remotecmd/client.go index 34912a6..efce97e 100644 --- a/cmdline/remotecmd/client.go +++ b/cmdline/remotecmd/client.go @@ -44,7 +44,7 @@ type ReaderGetter interface { // Make a single API request to a named endpoint, handling directory lookup and failover automatically. func CallRemote(endpoint, method string, query *url.Values, body ReaderGetter) (*http.Response, error) { - if err := shared.InitConfig(); err != nil { + if err := shared.InitClientConfig(); err != nil { return nil, err } if shared.CurrentConfig.Remote == nil { @@ -121,7 +121,7 @@ func buildRequest(base, endpoint, method, encoding string, query *url.Values, bo // Build TLS config based on client configuration func makeTLSConfig() (*tls.Config, error) { - err := shared.InitConfig() + err := shared.InitClientConfig() if err != nil { return nil, err } diff --git a/cmdline/shared/util.go b/cmdline/shared/util.go index ccda00b..6a558f1 100644 --- a/cmdline/shared/util.go +++ b/cmdline/shared/util.go @@ -26,6 +26,14 @@ import ( ) func InitConfig() error { + return initConfig(false) +} + +func InitClientConfig() error { + return initConfig(true) +} + +func initConfig(client bool) error { if CurrentConfig != nil { return nil } @@ -33,19 +41,38 @@ func InitConfig() error { usedDefault := false if ArgConfig == "" { ArgConfig = config.DefaultConfig() - if ArgConfig == "" { - return errors.New("--config not specified") - } usedDefault = true } - config, err := config.ReadFile(ArgConfig) + if client && usedDefault { + cfg, err := config.FromEnvironment() + if err != nil { + return err + } else if cfg != nil { + CurrentConfig = cfg + return nil + } + } + if ArgConfig == "" { + return errors.New("--config not specified") + } + cfg, err := config.ReadFile(ArgConfig) if err != nil { if os.IsNotExist(err) && usedDefault { + if client { + // try to use environment + cfg, err = config.FromEnvironment() + if err != nil { + return err + } else if cfg != nil { + CurrentConfig = cfg + return nil + } + } return fmt.Errorf("--config not specified and default config at %s does not exist", ArgConfig) } return err } - CurrentConfig = config + CurrentConfig = cfg return nil } diff --git a/config/env.go b/config/env.go new file mode 100644 index 0000000..17e82f8 --- /dev/null +++ b/config/env.go @@ -0,0 +1,47 @@ +// +// Copyright (c) SAS Institute Inc. +// +// 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://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 config + +import ( + "errors" + "os" +) + +// FromEnvironment tries to build a client-only config from environment variables. If none are set then returns nil. +func FromEnvironment() (*Config, error) { + remoteURL := os.Getenv("RELIC_URL") + if remoteURL == "" { + return nil, nil + } + clientCert := os.Getenv("RELIC_CLIENT_CERT") + clientKey := os.Getenv("RELIC_CLIENT_KEY") + if clientCert == "" { + return nil, errors.New("RELIC_CLIENT_CERT must be set when RELIC_URL is set") + } + if clientKey == "" { + clientKey = clientCert + } + cfg := &Config{ + Remote: &RemoteConfig{ + DirectoryURL: remoteURL, + KeyFile: clientKey, + CertFile: clientCert, + CaCert: os.Getenv("RELIC_CACERT"), + }, + } + return cfg, cfg.Normalize("") +}