forked from TrueCloudLab/lego
Add support for reading DNS provider setup from files (#535)
This commit is contained in:
parent
37ef38c4fc
commit
fa455bc037
13 changed files with 112 additions and 31 deletions
39
platform/config/env/env.go
vendored
39
platform/config/env/env.go
vendored
|
@ -3,10 +3,13 @@ package env
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/xenolf/lego/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get environment variables
|
// Get environment variables
|
||||||
|
@ -15,7 +18,7 @@ func Get(names ...string) (map[string]string, error) {
|
||||||
|
|
||||||
var missingEnvVars []string
|
var missingEnvVars []string
|
||||||
for _, envVar := range names {
|
for _, envVar := range names {
|
||||||
value := os.Getenv(envVar)
|
value := GetOrFile(envVar)
|
||||||
if value == "" {
|
if value == "" {
|
||||||
missingEnvVars = append(missingEnvVars, envVar)
|
missingEnvVars = append(missingEnvVars, envVar)
|
||||||
}
|
}
|
||||||
|
@ -76,13 +79,13 @@ func GetWithFallback(groups ...[]string) (map[string]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOneWithFallback(main string, names ...string) (string, string) {
|
func getOneWithFallback(main string, names ...string) (string, string) {
|
||||||
value := os.Getenv(main)
|
value := GetOrFile(main)
|
||||||
if len(value) > 0 {
|
if len(value) > 0 {
|
||||||
return value, main
|
return value, main
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
value := os.Getenv(name)
|
value := GetOrFile(name)
|
||||||
if len(value) > 0 {
|
if len(value) > 0 {
|
||||||
return value, main
|
return value, main
|
||||||
}
|
}
|
||||||
|
@ -94,7 +97,7 @@ func getOneWithFallback(main string, names ...string) (string, string) {
|
||||||
// GetOrDefaultInt returns the given environment variable value as an integer.
|
// GetOrDefaultInt returns the given environment variable value as an integer.
|
||||||
// Returns the default if the envvar cannot be coopered to an int, or is not found.
|
// Returns the default if the envvar cannot be coopered to an int, or is not found.
|
||||||
func GetOrDefaultInt(envVar string, defaultValue int) int {
|
func GetOrDefaultInt(envVar string, defaultValue int) int {
|
||||||
v, err := strconv.Atoi(os.Getenv(envVar))
|
v, err := strconv.Atoi(GetOrFile(envVar))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
@ -116,7 +119,7 @@ func GetOrDefaultSecond(envVar string, defaultValue time.Duration) time.Duration
|
||||||
// GetOrDefaultString returns the given environment variable value as a string.
|
// GetOrDefaultString returns the given environment variable value as a string.
|
||||||
// Returns the default if the envvar cannot be find.
|
// Returns the default if the envvar cannot be find.
|
||||||
func GetOrDefaultString(envVar string, defaultValue string) string {
|
func GetOrDefaultString(envVar string, defaultValue string) string {
|
||||||
v := os.Getenv(envVar)
|
v := GetOrFile(envVar)
|
||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
@ -127,10 +130,34 @@ func GetOrDefaultString(envVar string, defaultValue string) string {
|
||||||
// GetOrDefaultBool returns the given environment variable value as a boolean.
|
// GetOrDefaultBool returns the given environment variable value as a boolean.
|
||||||
// Returns the default if the envvar cannot be coopered to a boolean, or is not found.
|
// Returns the default if the envvar cannot be coopered to a boolean, or is not found.
|
||||||
func GetOrDefaultBool(envVar string, defaultValue bool) bool {
|
func GetOrDefaultBool(envVar string, defaultValue bool) bool {
|
||||||
v, err := strconv.ParseBool(os.Getenv(envVar))
|
v, err := strconv.ParseBool(GetOrFile(envVar))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOrFile Attempts to resolve 'key' as an environment variable.
|
||||||
|
// Failing that, it will check to see if '<key>_FILE' exists.
|
||||||
|
// If so, it will attempt to read from the referenced file to populate a value.
|
||||||
|
func GetOrFile(envVar string) string {
|
||||||
|
envVarValue := os.Getenv(envVar)
|
||||||
|
if envVarValue != "" {
|
||||||
|
return envVarValue
|
||||||
|
}
|
||||||
|
|
||||||
|
fileVar := envVar + "_FILE"
|
||||||
|
fileVarValue := os.Getenv(fileVar)
|
||||||
|
if fileVarValue == "" {
|
||||||
|
return envVarValue
|
||||||
|
}
|
||||||
|
|
||||||
|
fileContents, err := ioutil.ReadFile(fileVarValue)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed to read the file %s (defined by env var %s): %s", fileVarValue, fileVar, err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(fileContents)
|
||||||
|
}
|
||||||
|
|
65
platform/config/env/env_test.go
vendored
65
platform/config/env/env_test.go
vendored
|
@ -1,6 +1,7 @@
|
||||||
package env
|
package env
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -273,3 +274,67 @@ func TestGetOrDefaultBool(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetOrFile_ReadsEnvVars(t *testing.T) {
|
||||||
|
err := os.Setenv("TEST_LEGO_ENV_VAR", "lego_env")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.Unsetenv("TEST_LEGO_ENV_VAR")
|
||||||
|
|
||||||
|
value := GetOrFile("TEST_LEGO_ENV_VAR")
|
||||||
|
|
||||||
|
assert.Equal(t, "lego_env", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetOrFile_ReadsFiles(t *testing.T) {
|
||||||
|
varEnvFileName := "TEST_LEGO_ENV_VAR_FILE"
|
||||||
|
varEnvName := "TEST_LEGO_ENV_VAR"
|
||||||
|
|
||||||
|
err := os.Unsetenv(varEnvFileName)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = os.Unsetenv(varEnvName)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
file, err := ioutil.TempFile("", "lego")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.Remove(file.Name())
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(file.Name(), []byte("lego_file"), 0644)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = os.Setenv(varEnvFileName, file.Name())
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.Unsetenv(varEnvFileName)
|
||||||
|
|
||||||
|
value := GetOrFile(varEnvName)
|
||||||
|
|
||||||
|
assert.Equal(t, "lego_file", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetOrFile_PrefersEnvVars(t *testing.T) {
|
||||||
|
varEnvFileName := "TEST_LEGO_ENV_VAR_FILE"
|
||||||
|
varEnvName := "TEST_LEGO_ENV_VAR"
|
||||||
|
|
||||||
|
err := os.Unsetenv(varEnvFileName)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = os.Unsetenv(varEnvName)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
file, err := ioutil.TempFile("", "lego")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.Remove(file.Name())
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(file.Name(), []byte("lego_file"), 0644)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = os.Setenv(varEnvFileName, file.Name())
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.Unsetenv(varEnvFileName)
|
||||||
|
|
||||||
|
err = os.Setenv(varEnvName, "lego_env")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.Unsetenv(varEnvName)
|
||||||
|
|
||||||
|
value := GetOrFile(varEnvName)
|
||||||
|
|
||||||
|
assert.Equal(t, "lego_env", value)
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ package alidns
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -57,7 +56,7 @@ func NewDNSProvider() (*DNSProvider, error) {
|
||||||
config := NewDefaultConfig()
|
config := NewDefaultConfig()
|
||||||
config.APIKey = values["ALICLOUD_ACCESS_KEY"]
|
config.APIKey = values["ALICLOUD_ACCESS_KEY"]
|
||||||
config.SecretKey = values["ALICLOUD_SECRET_KEY"]
|
config.SecretKey = values["ALICLOUD_SECRET_KEY"]
|
||||||
config.RegionID = os.Getenv("ALICLOUD_REGION_ID")
|
config.RegionID = env.GetOrFile("ALICLOUD_REGION_ID")
|
||||||
|
|
||||||
return NewDNSProviderConfig(config)
|
return NewDNSProviderConfig(config)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package auroradns
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -53,7 +52,7 @@ func NewDNSProvider() (*DNSProvider, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
config := NewDefaultConfig()
|
config := NewDefaultConfig()
|
||||||
config.BaseURL = os.Getenv("AURORA_ENDPOINT")
|
config.BaseURL = env.GetOrFile("AURORA_ENDPOINT")
|
||||||
config.UserID = values["AURORA_USER_ID"]
|
config.UserID = values["AURORA_USER_ID"]
|
||||||
config.Key = values["AURORA_KEY"]
|
config.Key = values["AURORA_KEY"]
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ package dnsimple
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -45,8 +44,8 @@ type DNSProvider struct {
|
||||||
// See: https://developer.dnsimple.com/v2/#authentication
|
// See: https://developer.dnsimple.com/v2/#authentication
|
||||||
func NewDNSProvider() (*DNSProvider, error) {
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
config := NewDefaultConfig()
|
config := NewDefaultConfig()
|
||||||
config.AccessToken = os.Getenv("DNSIMPLE_OAUTH_TOKEN")
|
config.AccessToken = env.GetOrFile("DNSIMPLE_OAUTH_TOKEN")
|
||||||
config.BaseURL = os.Getenv("DNSIMPLE_BASE_URL")
|
config.BaseURL = env.GetOrFile("DNSIMPLE_BASE_URL")
|
||||||
|
|
||||||
return NewDNSProviderConfig(config)
|
return NewDNSProviderConfig(config)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -57,7 +56,7 @@ func NewDNSProvider() (*DNSProvider, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var baseURL string
|
var baseURL string
|
||||||
if sandbox, _ := strconv.ParseBool(os.Getenv("DNSMADEEASY_SANDBOX")); sandbox {
|
if sandbox, _ := strconv.ParseBool(env.GetOrFile("DNSMADEEASY_SANDBOX")); sandbox {
|
||||||
baseURL = "https://api.sandbox.dnsmadeeasy.com/V2.0"
|
baseURL = "https://api.sandbox.dnsmadeeasy.com/V2.0"
|
||||||
} else {
|
} else {
|
||||||
baseURL = "https://api.dnsmadeeasy.com/V2.0"
|
baseURL = "https://api.dnsmadeeasy.com/V2.0"
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/exoscale/egoscale"
|
"github.com/exoscale/egoscale"
|
||||||
|
@ -56,7 +55,7 @@ func NewDNSProvider() (*DNSProvider, error) {
|
||||||
config := NewDefaultConfig()
|
config := NewDefaultConfig()
|
||||||
config.APIKey = values["EXOSCALE_API_KEY"]
|
config.APIKey = values["EXOSCALE_API_KEY"]
|
||||||
config.APISecret = values["EXOSCALE_API_SECRET"]
|
config.APISecret = values["EXOSCALE_API_SECRET"]
|
||||||
config.Endpoint = os.Getenv("EXOSCALE_ENDPOINT")
|
config.Endpoint = env.GetOrFile("EXOSCALE_ENDPOINT")
|
||||||
|
|
||||||
return NewDNSProviderConfig(config)
|
return NewDNSProviderConfig(config)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
@ -54,7 +53,7 @@ type Config struct {
|
||||||
// NewDefaultConfig returns a default configuration for the DNSProvider
|
// NewDefaultConfig returns a default configuration for the DNSProvider
|
||||||
func NewDefaultConfig() *Config {
|
func NewDefaultConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
DNSZone: os.Getenv("DNS_ZONE"),
|
DNSZone: env.GetOrFile("DNS_ZONE"),
|
||||||
PropagationTimeout: env.GetOrDefaultSecond("LIGHTSAIL_PROPAGATION_TIMEOUT", acme.DefaultPropagationTimeout),
|
PropagationTimeout: env.GetOrDefaultSecond("LIGHTSAIL_PROPAGATION_TIMEOUT", acme.DefaultPropagationTimeout),
|
||||||
PollingInterval: env.GetOrDefaultSecond("LIGHTSAIL_POLLING_INTERVAL", acme.DefaultPollingInterval),
|
PollingInterval: env.GetOrDefaultSecond("LIGHTSAIL_POLLING_INTERVAL", acme.DefaultPollingInterval),
|
||||||
Region: env.GetOrDefaultString("LIGHTSAIL_REGION", "us-east-1"),
|
Region: env.GetOrDefaultString("LIGHTSAIL_REGION", "us-east-1"),
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ func NewDNSProvider() (*DNSProvider, error) {
|
||||||
config := NewDefaultConfig()
|
config := NewDefaultConfig()
|
||||||
config.Username = values["NAMECOM_USERNAME"]
|
config.Username = values["NAMECOM_USERNAME"]
|
||||||
config.APIToken = values["NAMECOM_API_TOKEN"]
|
config.APIToken = values["NAMECOM_API_TOKEN"]
|
||||||
config.Server = os.Getenv("NAMECOM_SERVER")
|
config.Server = env.GetOrFile("NAMECOM_SERVER")
|
||||||
|
|
||||||
return NewDNSProviderConfig(config)
|
return NewDNSProviderConfig(config)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/xenolf/lego/acme"
|
"github.com/xenolf/lego/acme"
|
||||||
|
@ -52,7 +51,7 @@ func NewDNSProvider() (*DNSProvider, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
config := NewDefaultConfig()
|
config := NewDefaultConfig()
|
||||||
config.BaseURL = os.Getenv("NIFCLOUD_DNS_ENDPOINT")
|
config.BaseURL = env.GetOrFile("NIFCLOUD_DNS_ENDPOINT")
|
||||||
config.AccessKey = values["NIFCLOUD_ACCESS_KEY_ID"]
|
config.AccessKey = values["NIFCLOUD_ACCESS_KEY_ID"]
|
||||||
config.SecretKey = values["NIFCLOUD_SECRET_ACCESS_KEY"]
|
config.SecretKey = values["NIFCLOUD_SECRET_ACCESS_KEY"]
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -62,8 +61,8 @@ func NewDNSProvider() (*DNSProvider, error) {
|
||||||
|
|
||||||
config := NewDefaultConfig()
|
config := NewDefaultConfig()
|
||||||
config.Nameserver = values["RFC2136_NAMESERVER"]
|
config.Nameserver = values["RFC2136_NAMESERVER"]
|
||||||
config.TSIGKey = os.Getenv("RFC2136_TSIG_KEY")
|
config.TSIGKey = env.GetOrFile("RFC2136_TSIG_KEY")
|
||||||
config.TSIGSecret = os.Getenv("RFC2136_TSIG_SECRET")
|
config.TSIGSecret = env.GetOrFile("RFC2136_TSIG_SECRET")
|
||||||
|
|
||||||
return NewDNSProviderConfig(config)
|
return NewDNSProviderConfig(config)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -35,7 +34,7 @@ func NewDefaultConfig() *Config {
|
||||||
TTL: env.GetOrDefaultInt("AWS_TTL", 10),
|
TTL: env.GetOrDefaultInt("AWS_TTL", 10),
|
||||||
PropagationTimeout: env.GetOrDefaultSecond("AWS_PROPAGATION_TIMEOUT", 2*time.Minute),
|
PropagationTimeout: env.GetOrDefaultSecond("AWS_PROPAGATION_TIMEOUT", 2*time.Minute),
|
||||||
PollingInterval: env.GetOrDefaultSecond("AWS_POLLING_INTERVAL", 4*time.Second),
|
PollingInterval: env.GetOrDefaultSecond("AWS_POLLING_INTERVAL", 4*time.Second),
|
||||||
HostedZoneID: os.Getenv("AWS_HOSTED_ZONE_ID"),
|
HostedZoneID: env.GetOrFile("AWS_HOSTED_ZONE_ID"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ package vegadns
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -50,8 +49,8 @@ func NewDNSProvider() (*DNSProvider, error) {
|
||||||
|
|
||||||
config := NewDefaultConfig()
|
config := NewDefaultConfig()
|
||||||
config.BaseURL = values["VEGADNS_URL"]
|
config.BaseURL = values["VEGADNS_URL"]
|
||||||
config.APIKey = os.Getenv("SECRET_VEGADNS_KEY")
|
config.APIKey = env.GetOrFile("SECRET_VEGADNS_KEY")
|
||||||
config.APISecret = os.Getenv("SECRET_VEGADNS_SECRET")
|
config.APISecret = env.GetOrFile("SECRET_VEGADNS_SECRET")
|
||||||
|
|
||||||
return NewDNSProviderConfig(config)
|
return NewDNSProviderConfig(config)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue