mirror of
https://github.com/steinhobelgruen/netatmo-exporter.git
synced 2024-11-21 17:03:56 +00:00
Environment variables take precedence over flags.
This commit is contained in:
parent
6eb05643c9
commit
f0bc18ab43
102
config.go
Normal file
102
config.go
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
netatmo "github.com/exzz/netatmo-api-go"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
envVarListenAddress = "NETATMO_EXPORTER_ADDR"
|
||||||
|
envVarNetatmoClientID = "NETATMO_CLIENT_ID"
|
||||||
|
envVarNetatmoClientSecret = "NETATMO_CLIENT_SECRET"
|
||||||
|
envVarNetatmoUsername = "NETATMO_CLIENT_USERNAME"
|
||||||
|
envVarNetatmoPassword = "NETATMO_CLIENT_PASSWORD"
|
||||||
|
|
||||||
|
flagListenAddress = "addr"
|
||||||
|
flagNetatmoClientID = "client-id"
|
||||||
|
flagNetatmoClientSecret = "client-secret"
|
||||||
|
flagNetatmoUsername = "username"
|
||||||
|
flagNetatmoPassword = "password"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
defaultConfig = config{
|
||||||
|
Addr: ":9210",
|
||||||
|
}
|
||||||
|
|
||||||
|
errNoBinaryName = errors.New("need the binary name as first argument")
|
||||||
|
errNoListenAddress = errors.New("no listen address")
|
||||||
|
errNoNetatmoClientID = errors.New("need a NetAtmo client ID")
|
||||||
|
errNoNetatmoClientSecret = errors.New("need a NetAtmo client secret")
|
||||||
|
errNoNetatmoUsername = errors.New("username can not be blank")
|
||||||
|
errNoNetatmoPassword = errors.New("password can not be blank")
|
||||||
|
)
|
||||||
|
|
||||||
|
type config struct {
|
||||||
|
Addr string
|
||||||
|
Netatmo netatmo.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseConfig(args []string, getenv func(string) string) (config, error) {
|
||||||
|
cfg := defaultConfig
|
||||||
|
|
||||||
|
if len(args) < 1 {
|
||||||
|
return cfg, errNoBinaryName
|
||||||
|
}
|
||||||
|
|
||||||
|
flagSet := pflag.NewFlagSet(args[0], pflag.ExitOnError)
|
||||||
|
flagSet.StringVarP(&cfg.Addr, "addr", "a", cfg.Addr, "Address to listen on.")
|
||||||
|
flagSet.StringVarP(&cfg.Netatmo.ClientID, "client-id", "i", cfg.Netatmo.ClientID, "Client ID for NetAtmo app.")
|
||||||
|
flagSet.StringVarP(&cfg.Netatmo.ClientSecret, "client-secret", "s", cfg.Netatmo.ClientSecret, "Client secret for NetAtmo app.")
|
||||||
|
flagSet.StringVarP(&cfg.Netatmo.Username, "username", "u", cfg.Netatmo.Username, "Username of NetAtmo account.")
|
||||||
|
flagSet.StringVarP(&cfg.Netatmo.Password, "password", "p", cfg.Netatmo.Password, "Password of NetAtmo account.")
|
||||||
|
flagSet.Parse(args[1:])
|
||||||
|
|
||||||
|
applyEnvironment(&cfg, getenv)
|
||||||
|
|
||||||
|
if len(cfg.Addr) == 0 {
|
||||||
|
return cfg, errNoListenAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cfg.Netatmo.ClientID) == 0 {
|
||||||
|
return cfg, errNoNetatmoClientID
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cfg.Netatmo.ClientSecret) == 0 {
|
||||||
|
return cfg, errNoNetatmoClientSecret
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cfg.Netatmo.Username) == 0 {
|
||||||
|
return cfg, errNoNetatmoUsername
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cfg.Netatmo.Password) == 0 {
|
||||||
|
return cfg, errNoNetatmoPassword
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyEnvironment(cfg *config, getenv func(string) string) {
|
||||||
|
if envAddr := getenv(envVarListenAddress); envAddr != "" {
|
||||||
|
cfg.Addr = envAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
if envClientID := getenv(envVarNetatmoClientID); envClientID != "" {
|
||||||
|
cfg.Netatmo.ClientID = envClientID
|
||||||
|
}
|
||||||
|
|
||||||
|
if envClientSecret := getenv(envVarNetatmoClientSecret); envClientSecret != "" {
|
||||||
|
cfg.Netatmo.ClientSecret = envClientSecret
|
||||||
|
}
|
||||||
|
|
||||||
|
if envUsername := getenv(envVarNetatmoUsername); envUsername != "" {
|
||||||
|
cfg.Netatmo.Username = envUsername
|
||||||
|
}
|
||||||
|
|
||||||
|
if envPassword := getenv(envVarNetatmoPassword); envPassword != "" {
|
||||||
|
cfg.Netatmo.Password = envPassword
|
||||||
|
}
|
||||||
|
}
|
219
config_test.go
Normal file
219
config_test.go
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
netatmo "github.com/exzz/netatmo-api-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseConfig(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
env map[string]string
|
||||||
|
wantConfig config
|
||||||
|
wantErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no args",
|
||||||
|
args: []string{},
|
||||||
|
env: map[string]string{},
|
||||||
|
wantConfig: config{},
|
||||||
|
wantErr: errNoBinaryName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "success",
|
||||||
|
args: []string{
|
||||||
|
"test-cmd",
|
||||||
|
"--" + flagNetatmoClientID,
|
||||||
|
"id",
|
||||||
|
"--" + flagNetatmoClientSecret,
|
||||||
|
"secret",
|
||||||
|
"--" + flagNetatmoUsername,
|
||||||
|
"username",
|
||||||
|
"--" + flagNetatmoPassword,
|
||||||
|
"password",
|
||||||
|
},
|
||||||
|
env: map[string]string{},
|
||||||
|
wantConfig: config{
|
||||||
|
Addr: defaultConfig.Addr,
|
||||||
|
Netatmo: netatmo.Config{
|
||||||
|
ClientID: "id",
|
||||||
|
ClientSecret: "secret",
|
||||||
|
Username: "username",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "all env",
|
||||||
|
args: []string{
|
||||||
|
"test-cmd",
|
||||||
|
},
|
||||||
|
env: map[string]string{
|
||||||
|
envVarListenAddress: ":8080",
|
||||||
|
envVarNetatmoClientID: "id",
|
||||||
|
envVarNetatmoClientSecret: "secret",
|
||||||
|
envVarNetatmoUsername: "username",
|
||||||
|
envVarNetatmoPassword: "password",
|
||||||
|
},
|
||||||
|
wantConfig: config{
|
||||||
|
Addr: ":8080",
|
||||||
|
Netatmo: netatmo.Config{
|
||||||
|
ClientID: "id",
|
||||||
|
ClientSecret: "secret",
|
||||||
|
Username: "username",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no addr",
|
||||||
|
args: []string{
|
||||||
|
"test-cmd",
|
||||||
|
"--" + flagListenAddress,
|
||||||
|
"",
|
||||||
|
"--" + flagNetatmoClientID,
|
||||||
|
"id",
|
||||||
|
"--" + flagNetatmoClientSecret,
|
||||||
|
"secret",
|
||||||
|
"--" + flagNetatmoUsername,
|
||||||
|
"username",
|
||||||
|
"--" + flagNetatmoPassword,
|
||||||
|
"password",
|
||||||
|
},
|
||||||
|
env: map[string]string{},
|
||||||
|
wantConfig: config{
|
||||||
|
Addr: defaultConfig.Addr,
|
||||||
|
Netatmo: netatmo.Config{
|
||||||
|
ClientID: "id",
|
||||||
|
ClientSecret: "secret",
|
||||||
|
Username: "username",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: errNoListenAddress,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no client id",
|
||||||
|
args: []string{
|
||||||
|
"test-cmd",
|
||||||
|
"--" + flagNetatmoClientSecret,
|
||||||
|
"secret",
|
||||||
|
"--" + flagNetatmoUsername,
|
||||||
|
"username",
|
||||||
|
"--" + flagNetatmoPassword,
|
||||||
|
"password",
|
||||||
|
},
|
||||||
|
env: map[string]string{},
|
||||||
|
wantConfig: config{
|
||||||
|
Addr: defaultConfig.Addr,
|
||||||
|
Netatmo: netatmo.Config{
|
||||||
|
ClientID: "id",
|
||||||
|
ClientSecret: "secret",
|
||||||
|
Username: "username",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: errNoNetatmoClientID,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no client secret",
|
||||||
|
args: []string{
|
||||||
|
"test-cmd",
|
||||||
|
"--" + flagNetatmoClientID,
|
||||||
|
"id",
|
||||||
|
"--" + flagNetatmoUsername,
|
||||||
|
"username",
|
||||||
|
"--" + flagNetatmoPassword,
|
||||||
|
"password",
|
||||||
|
},
|
||||||
|
env: map[string]string{},
|
||||||
|
wantConfig: config{
|
||||||
|
Addr: defaultConfig.Addr,
|
||||||
|
Netatmo: netatmo.Config{
|
||||||
|
ClientID: "id",
|
||||||
|
ClientSecret: "secret",
|
||||||
|
Username: "username",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: errNoNetatmoClientSecret,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no username",
|
||||||
|
args: []string{
|
||||||
|
"test-cmd",
|
||||||
|
"--" + flagNetatmoClientID,
|
||||||
|
"id",
|
||||||
|
"--" + flagNetatmoClientSecret,
|
||||||
|
"secret",
|
||||||
|
"--" + flagNetatmoPassword,
|
||||||
|
"password",
|
||||||
|
},
|
||||||
|
env: map[string]string{},
|
||||||
|
wantConfig: config{
|
||||||
|
Addr: defaultConfig.Addr,
|
||||||
|
Netatmo: netatmo.Config{
|
||||||
|
ClientID: "id",
|
||||||
|
ClientSecret: "secret",
|
||||||
|
Username: "username",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: errNoNetatmoUsername,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no password",
|
||||||
|
args: []string{
|
||||||
|
"test-cmd",
|
||||||
|
"--" + flagNetatmoClientID,
|
||||||
|
"id",
|
||||||
|
"--" + flagNetatmoClientSecret,
|
||||||
|
"secret",
|
||||||
|
"--" + flagNetatmoUsername,
|
||||||
|
"username",
|
||||||
|
},
|
||||||
|
env: map[string]string{},
|
||||||
|
wantConfig: config{
|
||||||
|
Addr: defaultConfig.Addr,
|
||||||
|
Netatmo: netatmo.Config{
|
||||||
|
ClientID: "id",
|
||||||
|
ClientSecret: "secret",
|
||||||
|
Username: "username",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: errNoNetatmoPassword,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
getenv := func(key string) string {
|
||||||
|
return tt.env[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := parseConfig(tt.args, getenv)
|
||||||
|
|
||||||
|
if err != tt.wantErr {
|
||||||
|
t.Errorf("got error %q, want %q", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(config, tt.wantConfig) {
|
||||||
|
t.Errorf("got config %v, want %v", config, tt.wantConfig)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
48
main.go
48
main.go
|
@ -1,62 +1,16 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
netatmo "github.com/exzz/netatmo-api-go"
|
netatmo "github.com/exzz/netatmo-api-go"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/spf13/pflag"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
|
||||||
Addr string
|
|
||||||
Netatmo netatmo.Config
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseConfig() (config, error) {
|
|
||||||
cfg := config{}
|
|
||||||
|
|
||||||
// Set default port to bind to
|
|
||||||
addr := ":9210"
|
|
||||||
if envAddr := os.Getenv("NETATMO_EXPORTER_ADDR"); envAddr != "" {
|
|
||||||
addr = envAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
pflag.StringVarP(&cfg.Addr, "addr", "a", addr, "Address to listen on.")
|
|
||||||
pflag.StringVarP(&cfg.Netatmo.ClientID, "client-id", "i", os.Getenv("NETATMO_CLIENT_ID"), "Client ID for NetAtmo app.")
|
|
||||||
pflag.StringVarP(&cfg.Netatmo.ClientSecret, "client-secret", "s", os.Getenv("NETATMO_CLIENT_SECRET"), "Client secret for NetAtmo app.")
|
|
||||||
pflag.StringVarP(&cfg.Netatmo.Username, "username", "u", os.Getenv("NETATMO_CLIENT_USERNAME"), "Username of NetAtmo account.")
|
|
||||||
pflag.StringVarP(&cfg.Netatmo.Password, "password", "p", os.Getenv("NETATMO_CLIENT_PASSWORD"), "Password of NetAtmo account.")
|
|
||||||
pflag.Parse()
|
|
||||||
|
|
||||||
if len(cfg.Addr) == 0 {
|
|
||||||
return cfg, errors.New("no listen address")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.Netatmo.ClientID) == 0 {
|
|
||||||
return cfg, errors.New("need a NetAtmo client ID")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.Netatmo.ClientSecret) == 0 {
|
|
||||||
return cfg, errors.New("need a NetAtmo client secret")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.Netatmo.Username) == 0 {
|
|
||||||
return cfg, errors.New("username can not be blank")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.Netatmo.Password) == 0 {
|
|
||||||
return cfg, errors.New("password can not be blank")
|
|
||||||
}
|
|
||||||
|
|
||||||
return cfg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cfg, err := parseConfig()
|
cfg, err := parseConfig(os.Args, os.Getenv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error in configuration: %s", err)
|
log.Fatalf("Error in configuration: %s", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue