Skip to content

Commit

Permalink
Add option to load CLI flags via environment variables
Browse files Browse the repository at this point in the history
  • Loading branch information
martialblog committed Oct 18, 2023
1 parent 83c4625 commit c33cf97
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 14 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ Available Commands:
query Checks the total hits/results of an Elasticsearch query
Flags:
-H, --hostname string Hostname of the Elasticsearch instance (default "localhost")
-H, --hostname string Hostname of the Elasticsearch instance (CHECK_ELASTICSEARCH_HOSTNAME) (default "localhost")
-p, --port int Port of the Elasticsearch instance (default 9200)
-U, --username string Username if authentication is required
-P, --password string Password if authentication is required
-U, --username string Username for HTTP Basic Authentication (CHECK_ELASTICSEARCH_USERNAME)
-P, --password string Password for HTTP Basic Authentication (CHECK_ELASTICSEARCH_PASSWORD)
-S, --tls Use a HTTPS connection
--insecure Skip the verification of the server's TLS certificate
-t, --timeout int Timeout in seconds for the CheckPlugin (default 30)
Expand All @@ -28,6 +28,8 @@ Flags:

The check plugin respects the environment variables `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY`.

Various flags can be set with environment variables, refer to the help to see which flags.

### Health

Checks the health status of an Elasticsearch cluster.
Expand Down
52 changes: 44 additions & 8 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"net"
"net/http"
"net/url"
"os"
"reflect"
"strconv"
"time"

Expand All @@ -14,19 +16,53 @@ import (
)

type Config struct {
Hostname string
BasicAuth string
Bearer string
CAFile string
CertFile string
KeyFile string
Username string
Password string
BasicAuth string // Currently unused in CLI
Bearer string // Currently unused in CLI
Hostname string `env:"CHECK_ELASTICSEARCH_HOSTNAME"`
CAFile string `env:"CHECK_ELASTICSEARCH_CA_FILE"`
CertFile string `env:"CHECK_ELASTICSEARCH_CERT_FILE"`
KeyFile string `env:"CHECK_ELASTICSEARCH_CERT_FILE"`
Username string `env:"CHECK_ELASTICSEARCH_USERNAME"`
Password string `env:"CHECK_ELASTICSEARCH_PASSWORD"`
Port int
TLS bool
Insecure bool
}

// LoadFromEnv can be used to load struct values from 'env' tags.
// Mainly used to avoid passing secrets via the CLI
//
// type Config struct {
// Token string `env:"BEARER_TOKEN"`
// }
func loadFromEnv(config interface{}) {
configValue := reflect.ValueOf(config).Elem()
configType := configValue.Type()

for i := 0; i < configValue.NumField(); i++ {
field := configType.Field(i)
tag := field.Tag.Get("env")

// If there's no "env" tag, skip this field.
if tag == "" {
continue
}

envValue := os.Getenv(tag)

if envValue == "" {
continue
}

// Potential for addding different types
// nolint: exhaustive, gocritic
switch field.Type.Kind() {
case reflect.String:
configValue.Field(i).SetString(envValue)
}
}
}

var cliConfig Config

func (c *Config) NewClient() *client.Client {
Expand Down
26 changes: 26 additions & 0 deletions cmd/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cmd

import (
"os"
"testing"
)

func TestLoadFromEnv(t *testing.T) {
c := Config{}

err := os.Setenv("CHECK_ELASTICSEARCH_USERNAME", "foobar")
defer os.Unsetenv("CHECK_ELASTICSEARCH_USERNAME") // to not impact other tests

if err != nil {
t.Error("Did not expect error, got: %w", err)
}

loadFromEnv(&c)

if "foobar" != c.Username {
t.Error("\nActual: ", c.Username, "\nExpected: ", "foobar")
}
if "" != c.Password {
t.Error("\nActual: ", c.Password, "\nExpected: ", "empty-string")
}
}
8 changes: 5 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ func init() {

pfs := rootCmd.PersistentFlags()
pfs.StringVarP(&cliConfig.Hostname, "hostname", "H", "localhost",
"Hostname of the Elasticsearch instance")
"Hostname of the Elasticsearch instance (CHECK_ELASTICSEARCH_HOSTNAME)")
pfs.IntVarP(&cliConfig.Port, "port", "p", 9200,
"Port of the Elasticsearch instance")
pfs.StringVarP(&cliConfig.Username, "username", "U", "",
"Username for HTTP Basic Authentication")
"Username for HTTP Basic Authentication (CHECK_ELASTICSEARCH_USERNAME)")
pfs.StringVarP(&cliConfig.Password, "password", "P", "",
"Password for HTTP Basic Authentication")
"Password for HTTP Basic Authentication (CHECK_ELASTICSEARCH_PASSWORD)")
pfs.BoolVarP(&cliConfig.TLS, "tls", "S", false,
"Use a HTTPS connection")
pfs.BoolVar(&cliConfig.Insecure, "insecure", false,
Expand All @@ -58,6 +58,8 @@ func init() {

rootCmd.Flags().SortFlags = false
pfs.SortFlags = false

loadFromEnv(&cliConfig)
}

func Help(cmd *cobra.Command, _ []string) {
Expand Down

0 comments on commit c33cf97

Please sign in to comment.