1
0
mirror of https://github.com/go-acme/lego.git synced 2024-12-23 09:15:11 +02:00
lego/providers/dns/route53/route53_test.go
Chris Marchesi 0122506c23
route53: Allow static credentials to be supplied (#1746)
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
2023-01-15 22:50:35 +00:00

310 lines
7.2 KiB
Go

package route53
import (
"os"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/route53"
"github.com/go-acme/lego/v4/platform/tester"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const envDomain = "R53_DOMAIN"
var envTest = tester.NewEnvTest(
EnvAccessKeyID,
EnvSecretAccessKey,
EnvRegion,
EnvHostedZoneID,
EnvMaxRetries,
EnvTTL,
EnvPropagationTimeout,
EnvPollingInterval).
WithDomain(envDomain).
WithLiveTestRequirements(EnvAccessKeyID, EnvSecretAccessKey, EnvRegion, envDomain)
func makeTestProvider(t *testing.T, serverURL string) *DNSProvider {
t.Helper()
config := &aws.Config{
Credentials: credentials.NewStaticCredentials("abc", "123", " "),
Endpoint: aws.String(serverURL),
Region: aws.String("mock-region"),
MaxRetries: aws.Int(1),
}
sess, err := session.NewSession(config)
require.NoError(t, err)
return &DNSProvider{
client: route53.New(sess),
config: NewDefaultConfig(),
}
}
func Test_loadCredentials_FromEnv(t *testing.T) {
defer envTest.RestoreEnv()
envTest.ClearEnv()
_ = os.Setenv(EnvAccessKeyID, "123")
_ = os.Setenv(EnvSecretAccessKey, "456")
_ = os.Setenv(EnvRegion, "us-east-1")
config := &aws.Config{
CredentialsChainVerboseErrors: aws.Bool(true),
}
sess, err := session.NewSession(config)
require.NoError(t, err)
value, err := sess.Config.Credentials.Get()
require.NoError(t, err, "Expected credentials to be set from environment")
expected := credentials.Value{
AccessKeyID: "123",
SecretAccessKey: "456",
SessionToken: "",
ProviderName: "EnvConfigCredentials",
}
assert.Equal(t, expected, value)
}
func Test_loadRegion_FromEnv(t *testing.T) {
defer envTest.RestoreEnv()
envTest.ClearEnv()
os.Setenv(EnvRegion, route53.CloudWatchRegionUsEast1)
sess, err := session.NewSession(aws.NewConfig())
require.NoError(t, err)
region := aws.StringValue(sess.Config.Region)
assert.Equal(t, route53.CloudWatchRegionUsEast1, region, "Region")
}
func Test_getHostedZoneID_FromEnv(t *testing.T) {
defer envTest.RestoreEnv()
envTest.ClearEnv()
expectedZoneID := "zoneID"
os.Setenv(EnvHostedZoneID, expectedZoneID)
provider, err := NewDNSProvider()
require.NoError(t, err)
hostedZoneID, err := provider.getHostedZoneID("whatever")
require.NoError(t, err, "HostedZoneID")
assert.Equal(t, expectedZoneID, hostedZoneID)
}
func TestNewDefaultConfig(t *testing.T) {
defer envTest.RestoreEnv()
testCases := []struct {
desc string
envVars map[string]string
expected *Config
}{
{
desc: "default configuration",
expected: &Config{
MaxRetries: 5,
TTL: 10,
PropagationTimeout: 2 * time.Minute,
PollingInterval: 4 * time.Second,
},
},
{
desc: "",
envVars: map[string]string{
EnvMaxRetries: "10",
EnvTTL: "99",
EnvPropagationTimeout: "60",
EnvPollingInterval: "60",
EnvHostedZoneID: "abc123",
},
expected: &Config{
MaxRetries: 10,
TTL: 99,
PropagationTimeout: 60 * time.Second,
PollingInterval: 60 * time.Second,
HostedZoneID: "abc123",
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
envTest.ClearEnv()
for key, value := range test.envVars {
os.Setenv(key, value)
}
config := NewDefaultConfig()
assert.Equal(t, test.expected, config)
})
}
}
func TestDNSProvider_Present(t *testing.T) {
mockResponses := MockResponseMap{
"/2013-04-01/hostedzonesbyname": {StatusCode: 200, Body: ListHostedZonesByNameResponse},
"/2013-04-01/hostedzone/ABCDEFG/rrset/": {StatusCode: 200, Body: ChangeResourceRecordSetsResponse},
"/2013-04-01/change/123456": {StatusCode: 200, Body: GetChangeResponse},
"/2013-04-01/hostedzone/ABCDEFG/rrset?name=_acme-challenge.example.com.&type=TXT": {
StatusCode: 200,
Body: "",
},
}
serverURL := setupTest(t, mockResponses)
defer envTest.RestoreEnv()
envTest.ClearEnv()
provider := makeTestProvider(t, serverURL)
domain := "example.com"
keyAuth := "123456d=="
err := provider.Present(domain, "", keyAuth)
require.NoError(t, err, "Expected Present to return no error")
}
func TestCreateSession(t *testing.T) {
testCases := []struct {
desc string
env map[string]string
config *Config
wantCreds credentials.Value
wantDefaultChain bool
wantRegion string
wantErr string
}{
{
desc: "config is nil",
wantErr: "config is nil",
},
{
desc: "session token without access key id or secret access key",
config: &Config{SessionToken: "foo"},
wantErr: "SessionToken must be supplied with AccessKeyID and SecretAccessKey",
},
{
desc: "access key id without secret access key",
config: &Config{AccessKeyID: "foo"},
wantErr: "AccessKeyID and SecretAccessKey must be supplied together",
},
{
desc: "access key id without secret access key",
config: &Config{SecretAccessKey: "foo"},
wantErr: "AccessKeyID and SecretAccessKey must be supplied together",
},
{
desc: "credentials from default chain",
config: &Config{},
wantDefaultChain: true,
},
{
desc: "static credentials",
config: &Config{
AccessKeyID: "one",
SecretAccessKey: "two",
},
wantCreds: credentials.Value{
AccessKeyID: "one",
SecretAccessKey: "two",
SessionToken: "",
ProviderName: credentials.StaticProviderName,
},
},
{
desc: "static credentials with session token",
config: &Config{
AccessKeyID: "one",
SecretAccessKey: "two",
SessionToken: "three",
},
wantCreds: credentials.Value{
AccessKeyID: "one",
SecretAccessKey: "two",
SessionToken: "three",
ProviderName: credentials.StaticProviderName,
},
},
{
desc: "region from env",
config: &Config{},
env: map[string]string{
"AWS_REGION": "foo",
},
wantDefaultChain: true,
wantRegion: "foo",
},
{
desc: "static region",
config: &Config{
Region: "one",
},
env: map[string]string{
"AWS_REGION": "foo",
},
wantDefaultChain: true,
wantRegion: "one",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
defer envTest.RestoreEnv()
envTest.ClearEnv()
envTest.Apply(test.env)
sess, err := createSession(test.config)
requireErr(t, err, test.wantErr)
if err != nil {
return
}
gotCreds, err := sess.Config.Credentials.Get()
if test.wantDefaultChain {
assert.NotEqual(t, credentials.StaticProviderName, gotCreds.ProviderName)
} else {
require.NoError(t, err)
assert.Equal(t, test.wantCreds, gotCreds)
}
if test.wantRegion != "" {
assert.Equal(t, test.wantRegion, aws.StringValue(sess.Config.Region))
}
})
}
}
func requireErr(t *testing.T, err error, wantErr string) {
t.Helper()
switch {
case err != nil && wantErr == "":
// force the assertion error.
require.NoError(t, err)
case err == nil && wantErr != "":
// force the assertion error.
require.EqualError(t, err, wantErr)
case err != nil && wantErr != "":
require.EqualError(t, err, wantErr)
}
}