aboutsummaryrefslogtreecommitdiff
path: root/plugin/route53
diff options
context:
space:
mode:
authorGravatar Can Yucel <can.yucel@gmail.com> 2018-09-25 15:57:16 -0700
committerGravatar corbot[bot] <corbot[bot]@users.noreply.github.com> 2018-09-25 22:57:16 +0000
commit81484083010aca7a22cfb0d9de480bdb1c05545f (patch)
treef9a0d1c56af07605480cc70e91ab2f8b24275f98 /plugin/route53
parenta0396e267321ac7e0854b90fd9d882fe41be9048 (diff)
downloadcoredns-81484083010aca7a22cfb0d9de480bdb1c05545f.tar.gz
coredns-81484083010aca7a22cfb0d9de480bdb1c05545f.tar.zst
coredns-81484083010aca7a22cfb0d9de480bdb1c05545f.zip
plugins/route53: add AWS credentials file support (#2118)
Automatically submitted.
Diffstat (limited to 'plugin/route53')
-rw-r--r--plugin/route53/README.md18
-rw-r--r--plugin/route53/setup.go30
-rw-r--r--plugin/route53/setup_test.go32
3 files changed, 75 insertions, 5 deletions
diff --git a/plugin/route53/README.md b/plugin/route53/README.md
index 07bd2bd77..0363df696 100644
--- a/plugin/route53/README.md
+++ b/plugin/route53/README.md
@@ -16,6 +16,7 @@ The route53 plugin can be used when coredns is deployed on AWS or elsewhere.
route53 [ZONE:HOSTED_ZONE_ID...] {
[aws_access_key AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY]
upstream [ADDRESS...]
+ credentials PROFILE [FILENAME]
fallthrough [ZONES...]
}
~~~
@@ -30,6 +31,9 @@ route53 [ZONE:HOSTED_ZONE_ID...] {
to external hosts (eg. used to resolve CNAMEs). If no **ADDRESS** is given, CoreDNS will resolve
against itself. **ADDRESS** can be an IP, an IP:port or a path to a file structured like
resolv.conf (**NB**: Currently a bug (#2099) is preventing the use of self-resolver).
+* `credentials` used for reading the credential file and setting the profile name for a given zone.
+* **PROFILE** AWS account profile name. Defaults to `default`.
+* **FILENAME** AWS credentials filename. Defaults to `~/.aws/credentials`
are used.
* `fallthrough` If zone matches and no record can be generated, pass request to the next plugin.
If **[ZONES...]** is omitted, then fallthrough happens for all zones for which the plugin
@@ -39,7 +43,7 @@ route53 [ZONE:HOSTED_ZONE_ID...] {
## Examples
-Enable route53 with implicit aws credentials and an upstream:
+Enable route53 with implicit AWS credentials and an upstream:
~~~ txt
. {
@@ -48,7 +52,7 @@ Enable route53 with implicit aws credentials and an upstream:
}
~~~
-Enable route53 with explicit aws credentials:
+Enable route53 with explicit AWS credentials:
~~~ txt
. {
@@ -67,3 +71,13 @@ Enable route53 with fallthrough:
}
}
~~~
+
+Enable route53 with AWS credentials file:
+
+~~~ txt
+. {
+ route53 example.org.:Z1Z2Z3Z4DZ5Z6Z7 {
+ credentials_file some-user
+ }
+}
+~~~
diff --git a/plugin/route53/setup.go b/plugin/route53/setup.go
index 765a2ceee..494f4f1b6 100644
--- a/plugin/route53/setup.go
+++ b/plugin/route53/setup.go
@@ -36,7 +36,15 @@ func init() {
func setup(c *caddy.Controller, f func(*credentials.Credentials) route53iface.Route53API) error {
keys := map[string]string{}
- credential := credentials.NewEnvCredentials()
+
+ // Route53 plugin attempts to find AWS credentials by using ChainCredentials.
+ // And the order of that provider chain is as follows:
+ // Static AWS keys -> Environment Variables -> Credentials file -> IAM role
+ // With that said, even though a user doesn't define any credentials in
+ // Corefile, we should still attempt to read the default credentials file,
+ // ~/.aws/credentials with the default profile.
+ sharedProvider := &credentials.SharedCredentialsProvider{}
+ var providers []credentials.Provider
var fall fall.F
up, _ := upstream.New(nil)
@@ -65,7 +73,12 @@ func setup(c *caddy.Controller, f func(*credentials.Credentials) route53iface.Ro
if len(v) < 2 {
return c.Errf("invalid access key '%v'", v)
}
- credential = credentials.NewStaticCredentials(v[0], v[1], "")
+ providers = append(providers, &credentials.StaticProvider{
+ Value: credentials.Value{
+ AccessKeyID: v[0],
+ SecretAccessKey: v[1],
+ },
+ })
case "upstream":
args := c.RemainingArgs()
// TODO(dilyevsky): There is a bug that causes coredns to crash
@@ -78,6 +91,15 @@ func setup(c *caddy.Controller, f func(*credentials.Credentials) route53iface.Ro
if err != nil {
return c.Errf("invalid upstream: %v", err)
}
+ case "credentials":
+ if c.NextArg() {
+ sharedProvider.Profile = c.Val()
+ } else {
+ return c.ArgErr()
+ }
+ if c.NextArg() {
+ sharedProvider.Filename = c.Val()
+ }
case "fallthrough":
fall.SetZonesFromArgs(c.RemainingArgs())
default:
@@ -85,7 +107,9 @@ func setup(c *caddy.Controller, f func(*credentials.Credentials) route53iface.Ro
}
}
}
- client := f(credential)
+ providers = append(providers, &credentials.EnvProvider{}, sharedProvider)
+
+ client := f(credentials.NewChainCredentials(providers))
ctx := context.Background()
h, err := New(ctx, client, keys, &up)
if err != nil {
diff --git a/plugin/route53/setup_test.go b/plugin/route53/setup_test.go
index 139da1fa0..a0b13b3d6 100644
--- a/plugin/route53/setup_test.go
+++ b/plugin/route53/setup_test.go
@@ -59,4 +59,36 @@ func TestSetupRoute53(t *testing.T) {
if err := setup(c, f); err != nil {
t.Fatalf("Unexpected errors: %v", err)
}
+
+ c = caddy.NewTestController("dns", `route53 example.org:12345678 {
+ credentials
+ upstream 1.2.3.4
+ }`)
+ if err := setup(c, f); err == nil {
+ t.Fatalf("Expected errors, but got: %v", err)
+ }
+
+ c = caddy.NewTestController("dns", `route53 example.org:12345678 {
+ credentials default
+ upstream 1.2.3.4
+ }`)
+ if err := setup(c, f); err != nil {
+ t.Fatalf("Unexpected errors: %v", err)
+ }
+
+ c = caddy.NewTestController("dns", `route53 example.org:12345678 {
+ credentials default credentials
+ upstream 1.2.3.4
+ }`)
+ if err := setup(c, f); err != nil {
+ t.Fatalf("Unexpected errors: %v", err)
+ }
+
+ c = caddy.NewTestController("dns", `route53 example.org:12345678 {
+ credentials default credentials extra-arg
+ upstream 1.2.3.4
+ }`)
+ if err := setup(c, f); err == nil {
+ t.Fatalf("Expected errors, but got: %v", err)
+ }
}