mirror of
https://github.com/coredns/coredns.git
synced 2025-10-28 08:44:17 -04:00
plugins/route53: add AWS credentials file support (#2118)
Automatically submitted.
This commit is contained in:
@@ -16,6 +16,7 @@ The route53 plugin can be used when coredns is deployed on AWS or elsewhere.
|
|||||||
route53 [ZONE:HOSTED_ZONE_ID...] {
|
route53 [ZONE:HOSTED_ZONE_ID...] {
|
||||||
[aws_access_key AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY]
|
[aws_access_key AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY]
|
||||||
upstream [ADDRESS...]
|
upstream [ADDRESS...]
|
||||||
|
credentials PROFILE [FILENAME]
|
||||||
fallthrough [ZONES...]
|
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
|
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
|
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).
|
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.
|
are used.
|
||||||
* `fallthrough` If zone matches and no record can be generated, pass request to the next plugin.
|
* `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
|
If **[ZONES...]** is omitted, then fallthrough happens for all zones for which the plugin
|
||||||
@@ -39,7 +43,7 @@ route53 [ZONE:HOSTED_ZONE_ID...] {
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Enable route53 with implicit aws credentials and an upstream:
|
Enable route53 with implicit AWS credentials and an upstream:
|
||||||
|
|
||||||
~~~ txt
|
~~~ 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
|
~~~ txt
|
||||||
. {
|
. {
|
||||||
@@ -67,3 +71,13 @@ Enable route53 with fallthrough:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
Enable route53 with AWS credentials file:
|
||||||
|
|
||||||
|
~~~ txt
|
||||||
|
. {
|
||||||
|
route53 example.org.:Z1Z2Z3Z4DZ5Z6Z7 {
|
||||||
|
credentials_file some-user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|||||||
@@ -36,7 +36,15 @@ func init() {
|
|||||||
|
|
||||||
func setup(c *caddy.Controller, f func(*credentials.Credentials) route53iface.Route53API) error {
|
func setup(c *caddy.Controller, f func(*credentials.Credentials) route53iface.Route53API) error {
|
||||||
keys := map[string]string{}
|
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
|
var fall fall.F
|
||||||
|
|
||||||
up, _ := upstream.New(nil)
|
up, _ := upstream.New(nil)
|
||||||
@@ -65,7 +73,12 @@ func setup(c *caddy.Controller, f func(*credentials.Credentials) route53iface.Ro
|
|||||||
if len(v) < 2 {
|
if len(v) < 2 {
|
||||||
return c.Errf("invalid access key '%v'", v)
|
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":
|
case "upstream":
|
||||||
args := c.RemainingArgs()
|
args := c.RemainingArgs()
|
||||||
// TODO(dilyevsky): There is a bug that causes coredns to crash
|
// 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 {
|
if err != nil {
|
||||||
return c.Errf("invalid upstream: %v", err)
|
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":
|
case "fallthrough":
|
||||||
fall.SetZonesFromArgs(c.RemainingArgs())
|
fall.SetZonesFromArgs(c.RemainingArgs())
|
||||||
default:
|
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()
|
ctx := context.Background()
|
||||||
h, err := New(ctx, client, keys, &up)
|
h, err := New(ctx, client, keys, &up)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -59,4 +59,36 @@ func TestSetupRoute53(t *testing.T) {
|
|||||||
if err := setup(c, f); err != nil {
|
if err := setup(c, f); err != nil {
|
||||||
t.Fatalf("Unexpected errors: %v", err)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user