mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2026-05-05 14:46:10 +02:00
Merge pull request #4274 from IntegralProgrammer/dnsimple-user-api-token
feat(DNSimple): User API tokens
This commit is contained in:
commit
aee99e21f3
@ -5,11 +5,15 @@ This tutorial describes how to setup ExternalDNS for usage with DNSimple.
|
||||
|
||||
Make sure to use **>=0.4.6** version of ExternalDNS for this tutorial.
|
||||
|
||||
## Created a DNSimple API Access Token
|
||||
## Create a DNSimple API Access Token
|
||||
|
||||
A DNSimple API access token can be acquired by following the [provided documentation from DNSimple](https://support.dnsimple.com/articles/api-access-token/)
|
||||
|
||||
The environment variable `DNSIMPLE_OAUTH` must be set to the API token generated for to run ExternalDNS with DNSimple.
|
||||
The environment variable `DNSIMPLE_OAUTH` must be set to the generated API token to run ExternalDNS with DNSimple.
|
||||
|
||||
When the generated DNSimple API access token is a _User token_, as opposed to an _Account token_, the following environment variables must also be set:
|
||||
- `DNSIMPLE_ACCOUNT_ID`: Set this to the account ID which the domains to be managed by ExternalDNS belong to (eg. `1001234`).
|
||||
- `DNSIMPLE_ZONES`: Set this to a comma separated list of DNS zones to be managed by ExternalDNS (eg. `mydomain.com,example.com`).
|
||||
|
||||
## Deploy ExternalDNS
|
||||
|
||||
@ -44,6 +48,10 @@ spec:
|
||||
env:
|
||||
- name: DNSIMPLE_OAUTH
|
||||
value: "YOUR_DNSIMPLE_API_KEY"
|
||||
- name: DNSIMPLE_ACCOUNT_ID
|
||||
value: "SET THIS IF USING A DNSIMPLE USER ACCESS TOKEN"
|
||||
- name: DNSIMPLE_ZONES
|
||||
value: "SET THIS IF USING A DNSIMPLE USER ACCESS TOKEN"
|
||||
```
|
||||
|
||||
### Manifest (for clusters with RBAC enabled)
|
||||
@ -109,6 +117,10 @@ spec:
|
||||
env:
|
||||
- name: DNSIMPLE_OAUTH
|
||||
value: "YOUR_DNSIMPLE_API_KEY"
|
||||
- name: DNSIMPLE_ACCOUNT_ID
|
||||
value: "SET THIS IF USING A DNSIMPLE USER ACCESS TOKEN"
|
||||
- name: DNSIMPLE_ZONES
|
||||
value: "SET THIS IF USING A DNSIMPLE USER ACCESS TOKEN"
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -118,11 +118,14 @@ func NewDnsimpleProvider(domainFilter endpoint.DomainFilter, zoneIDFilter provid
|
||||
dryRun: dryRun,
|
||||
}
|
||||
|
||||
whoamiResponse, err := provider.identity.Whoami(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
provider.accountID = os.Getenv("DNSIMPLE_ACCOUNT_ID")
|
||||
if provider.accountID == "" {
|
||||
whoamiResponse, err := provider.identity.Whoami(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
provider.accountID = int64ToString(whoamiResponse.Data.Account.ID)
|
||||
}
|
||||
provider.accountID = int64ToString(whoamiResponse.Data.Account.ID)
|
||||
return provider, nil
|
||||
}
|
||||
|
||||
@ -136,9 +139,29 @@ func (p *dnsimpleProvider) GetAccountID(ctx context.Context) (accountID string,
|
||||
return int64ToString(whoamiResponse.Data.Account.ID), nil
|
||||
}
|
||||
|
||||
func ZonesFromZoneString(zonestring string) map[string]dnsimple.Zone {
|
||||
zones := make(map[string]dnsimple.Zone)
|
||||
zoneNames := strings.Split(zonestring, ",")
|
||||
for indexId, zoneName := range zoneNames {
|
||||
zone := dnsimple.Zone{Name: zoneName, ID: int64(indexId)}
|
||||
zones[int64ToString(zone.ID)] = zone
|
||||
}
|
||||
return zones
|
||||
}
|
||||
|
||||
// Returns a list of filtered Zones
|
||||
func (p *dnsimpleProvider) Zones(ctx context.Context) (map[string]dnsimple.Zone, error) {
|
||||
zones := make(map[string]dnsimple.Zone)
|
||||
|
||||
// If the DNSIMPLE_ZONES environment variable is specified, generate a list of Zones from it
|
||||
// This is useful for when the DNSIMPLE_OAUTH environment variable is a User API token and
|
||||
// not an Account API token as the User API token will not have permissions to list Zones
|
||||
// belong to another account which the User has access permissions for.
|
||||
envZonesStr := os.Getenv("DNSIMPLE_ZONES")
|
||||
if envZonesStr != "" {
|
||||
return ZonesFromZoneString(envZonesStr), nil
|
||||
}
|
||||
|
||||
page := 1
|
||||
listOptions := &dnsimple.ZoneListOptions{}
|
||||
for {
|
||||
|
||||
@ -33,9 +33,10 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
mockProvider dnsimpleProvider
|
||||
dnsimpleListRecordsResponse dnsimple.ZoneRecordsResponse
|
||||
dnsimpleListZonesResponse dnsimple.ZonesResponse
|
||||
mockProvider dnsimpleProvider
|
||||
dnsimpleListRecordsResponse dnsimple.ZoneRecordsResponse
|
||||
dnsimpleListZonesResponse dnsimple.ZonesResponse
|
||||
dnsimpleListZonesFromEnvResponse dnsimple.ZonesResponse
|
||||
)
|
||||
|
||||
func TestDnsimpleServices(t *testing.T) {
|
||||
@ -55,6 +56,16 @@ func TestDnsimpleServices(t *testing.T) {
|
||||
Response: dnsimple.Response{Pagination: &dnsimple.Pagination{}},
|
||||
Data: zones,
|
||||
}
|
||||
firstEnvDefinedZone := dnsimple.Zone{
|
||||
ID: 0,
|
||||
AccountID: 12345,
|
||||
Name: "example-from-env.com",
|
||||
}
|
||||
envDefinedZones := []dnsimple.Zone{firstEnvDefinedZone}
|
||||
dnsimpleListZonesFromEnvResponse = dnsimple.ZonesResponse{
|
||||
Response: dnsimple.Response{Pagination: &dnsimple.Pagination{}},
|
||||
Data: envDefinedZones,
|
||||
}
|
||||
firstRecord := dnsimple.ZoneRecord{
|
||||
ID: 2,
|
||||
ZoneID: "example.com",
|
||||
@ -151,6 +162,15 @@ func testDnsimpleProviderZones(t *testing.T) {
|
||||
mockProvider.accountID = "2"
|
||||
_, err = mockProvider.Zones(ctx)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockProvider.accountID = "3"
|
||||
os.Setenv("DNSIMPLE_ZONES", "example-from-env.com")
|
||||
result, err = mockProvider.Zones(ctx)
|
||||
assert.Nil(t, err)
|
||||
validateDnsimpleZones(t, result, dnsimpleListZonesFromEnvResponse.Data)
|
||||
|
||||
mockProvider.accountID = "2"
|
||||
os.Unsetenv("DNSIMPLE_ZONES")
|
||||
}
|
||||
|
||||
func testDnsimpleProviderRecords(t *testing.T) {
|
||||
@ -207,6 +227,17 @@ func testDnsimpleSuitableZone(t *testing.T) {
|
||||
|
||||
zone := dnsimpleSuitableZone("example-beta.example.com", zones)
|
||||
assert.Equal(t, zone.Name, "example.com")
|
||||
|
||||
os.Setenv("DNSIMPLE_ZONES", "environment-example.com,example.environment-example.com")
|
||||
mockProvider.accountID = "3"
|
||||
zones, err = mockProvider.Zones(ctx)
|
||||
assert.Nil(t, err)
|
||||
|
||||
zone = dnsimpleSuitableZone("hello.example.environment-example.com", zones)
|
||||
assert.Equal(t, zone.Name, "example.environment-example.com")
|
||||
|
||||
os.Unsetenv("DNSIMPLE_ZONES")
|
||||
mockProvider.accountID = "1"
|
||||
}
|
||||
|
||||
func TestNewDnsimpleProvider(t *testing.T) {
|
||||
@ -215,10 +246,23 @@ func TestNewDnsimpleProvider(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Errorf("Expected to fail new provider on bad token")
|
||||
}
|
||||
|
||||
os.Unsetenv("DNSIMPLE_OAUTH")
|
||||
_, err = NewDnsimpleProvider(endpoint.NewDomainFilter([]string{"example.com"}), provider.NewZoneIDFilter([]string{""}), true)
|
||||
if err == nil {
|
||||
t.Errorf("Expected to fail new provider on empty token")
|
||||
}
|
||||
|
||||
os.Setenv("DNSIMPLE_OAUTH", "xxxxxxxxxxxxxxxxxxxxxxxxxx")
|
||||
os.Setenv("DNSIMPLE_ACCOUNT_ID", "12345678")
|
||||
providerTypedProvider, err := NewDnsimpleProvider(endpoint.NewDomainFilter([]string{"example.com"}), provider.NewZoneIDFilter([]string{""}), true)
|
||||
dnsimpleTypedProvider := providerTypedProvider.(*dnsimpleProvider)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error thrown when testing NewDnsimpleProvider with the DNSIMPLE_ACCOUNT_ID environment variable set")
|
||||
}
|
||||
assert.Equal(t, dnsimpleTypedProvider.accountID, "12345678")
|
||||
os.Unsetenv("DNSIMPLE_OAUTH")
|
||||
os.Unsetenv("DNSIMPLE_ACCOUNT_ID")
|
||||
}
|
||||
|
||||
func testDnsimpleGetRecordID(t *testing.T) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user