forked from TrueCloudLab/lego
Cloudflare: support for CF_API_KEY and CF_API_EMAIL (#647)
This commit is contained in:
parent
c09b12be08
commit
8a8aa2d81b
3 changed files with 165 additions and 3 deletions
63
platform/config/env/env.go
vendored
63
platform/config/env/env.go
vendored
|
@ -1,6 +1,7 @@
|
||||||
package env
|
package env
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -28,6 +29,68 @@ func Get(names ...string) (map[string]string, error) {
|
||||||
return values, nil
|
return values, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetWithFallback Get environment variable values
|
||||||
|
// The first name in each group is use as key in the result map
|
||||||
|
//
|
||||||
|
// // LEGO_ONE="ONE"
|
||||||
|
// // LEGO_TWO="TWO"
|
||||||
|
// env.GetWithFallback([]string{"LEGO_ONE", "LEGO_TWO"})
|
||||||
|
// // => "LEGO_ONE" = "ONE"
|
||||||
|
//
|
||||||
|
// ----
|
||||||
|
//
|
||||||
|
// // LEGO_ONE=""
|
||||||
|
// // LEGO_TWO="TWO"
|
||||||
|
// env.GetWithFallback([]string{"LEGO_ONE", "LEGO_TWO"})
|
||||||
|
// // => "LEGO_ONE" = "TWO"
|
||||||
|
//
|
||||||
|
// ----
|
||||||
|
//
|
||||||
|
// // LEGO_ONE=""
|
||||||
|
// // LEGO_TWO=""
|
||||||
|
// env.GetWithFallback([]string{"LEGO_ONE", "LEGO_TWO"})
|
||||||
|
// // => error
|
||||||
|
//
|
||||||
|
func GetWithFallback(groups ...[]string) (map[string]string, error) {
|
||||||
|
values := map[string]string{}
|
||||||
|
|
||||||
|
var missingEnvVars []string
|
||||||
|
for _, names := range groups {
|
||||||
|
if len(names) == 0 {
|
||||||
|
return nil, errors.New("undefined environment variable names")
|
||||||
|
}
|
||||||
|
|
||||||
|
value, envVar := getOneWithFallback(names[0], names[1:]...)
|
||||||
|
if len(value) == 0 {
|
||||||
|
missingEnvVars = append(missingEnvVars, envVar)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
values[envVar] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(missingEnvVars) > 0 {
|
||||||
|
return nil, fmt.Errorf("some credentials information are missing: %s", strings.Join(missingEnvVars, ","))
|
||||||
|
}
|
||||||
|
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOneWithFallback(main string, names ...string) (string, string) {
|
||||||
|
value := os.Getenv(main)
|
||||||
|
if len(value) > 0 {
|
||||||
|
return value, main
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range names {
|
||||||
|
value := os.Getenv(name)
|
||||||
|
if len(value) > 0 {
|
||||||
|
return value, main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", main
|
||||||
|
}
|
||||||
|
|
||||||
// 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 {
|
||||||
|
|
97
platform/config/env/env_test.go
vendored
97
platform/config/env/env_test.go
vendored
|
@ -9,6 +9,103 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestGetWithFallback(t *testing.T) {
|
||||||
|
var1Exist := os.Getenv("TEST_LEGO_VAR_EXIST_1")
|
||||||
|
var2Exist := os.Getenv("TEST_LEGO_VAR_EXIST_2")
|
||||||
|
var1Missing := os.Getenv("TEST_LEGO_VAR_MISSING_1")
|
||||||
|
var2Missing := os.Getenv("TEST_LEGO_VAR_MISSING_2")
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
_ = os.Setenv("TEST_LEGO_VAR_EXIST_1", var1Exist)
|
||||||
|
_ = os.Setenv("TEST_LEGO_VAR_EXIST_2", var2Exist)
|
||||||
|
_ = os.Setenv("TEST_LEGO_VAR_MISSING_1", var1Missing)
|
||||||
|
_ = os.Setenv("TEST_LEGO_VAR_MISSING_2", var2Missing)
|
||||||
|
}()
|
||||||
|
|
||||||
|
err := os.Setenv("TEST_LEGO_VAR_EXIST_1", "VAR1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = os.Setenv("TEST_LEGO_VAR_EXIST_2", "VAR2")
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = os.Unsetenv("TEST_LEGO_VAR_MISSING_1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = os.Unsetenv("TEST_LEGO_VAR_MISSING_2")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
type expected struct {
|
||||||
|
value map[string]string
|
||||||
|
error string
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
groups [][]string
|
||||||
|
expected expected
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "no groups",
|
||||||
|
groups: nil,
|
||||||
|
expected: expected{
|
||||||
|
value: map[string]string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "empty groups",
|
||||||
|
groups: [][]string{{}, {}},
|
||||||
|
expected: expected{
|
||||||
|
error: "undefined environment variable names",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing env var",
|
||||||
|
groups: [][]string{{"TEST_LEGO_VAR_MISSING_1"}},
|
||||||
|
expected: expected{
|
||||||
|
error: "some credentials information are missing: TEST_LEGO_VAR_MISSING_1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "all env var in a groups are missing",
|
||||||
|
groups: [][]string{{"TEST_LEGO_VAR_MISSING_1", "TEST_LEGO_VAR_MISSING_2"}},
|
||||||
|
expected: expected{
|
||||||
|
error: "some credentials information are missing: TEST_LEGO_VAR_MISSING_1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "only the first env var have a value",
|
||||||
|
groups: [][]string{{"TEST_LEGO_VAR_EXIST_1", "TEST_LEGO_VAR_MISSING_1"}},
|
||||||
|
expected: expected{
|
||||||
|
value: map[string]string{"TEST_LEGO_VAR_EXIST_1": "VAR1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "only the second env var have a value",
|
||||||
|
groups: [][]string{{"TEST_LEGO_VAR_MISSING_1", "TEST_LEGO_VAR_EXIST_1"}},
|
||||||
|
expected: expected{
|
||||||
|
value: map[string]string{"TEST_LEGO_VAR_MISSING_1": "VAR1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "only all env vars have a value",
|
||||||
|
groups: [][]string{{"TEST_LEGO_VAR_EXIST_1", "TEST_LEGO_VAR_EXIST_2"}},
|
||||||
|
expected: expected{
|
||||||
|
value: map[string]string{"TEST_LEGO_VAR_EXIST_1": "VAR1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
value, err := GetWithFallback(test.groups...)
|
||||||
|
if len(test.expected.error) > 0 {
|
||||||
|
assert.EqualError(t, err, test.expected.error)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, test.expected.value, value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetOrDefaultInt(t *testing.T) {
|
func TestGetOrDefaultInt(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
|
|
|
@ -47,7 +47,9 @@ type DNSProvider struct {
|
||||||
// Credentials must be passed in the environment variables:
|
// Credentials must be passed in the environment variables:
|
||||||
// CLOUDFLARE_EMAIL and CLOUDFLARE_API_KEY.
|
// CLOUDFLARE_EMAIL and CLOUDFLARE_API_KEY.
|
||||||
func NewDNSProvider() (*DNSProvider, error) {
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
values, err := env.Get("CLOUDFLARE_EMAIL", "CLOUDFLARE_API_KEY")
|
values, err := env.GetWithFallback(
|
||||||
|
[]string{"CLOUDFLARE_EMAIL", "CF_API_EMAIL"},
|
||||||
|
[]string{"CLOUDFLARE_API_KEY", "CF_API_KEY"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cloudflare: %v", err)
|
return nil, fmt.Errorf("cloudflare: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -92,8 +94,8 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timeout returns the timeout and interval to use when checking for DNS
|
// Timeout returns the timeout and interval to use when checking for DNS propagation.
|
||||||
// propagation. Adjusting here to cope with spikes in propagation times.
|
// Adjusting here to cope with spikes in propagation times.
|
||||||
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||||
return d.config.PropagationTimeout, d.config.PollingInterval
|
return d.config.PropagationTimeout, d.config.PollingInterval
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue