Skip to content

Commit 9f81bbe

Browse files
authored
Merge pull request #4210 from Jeremy-Boyle/feature/azure-add-endpoints-4209
custom Azure Active Directory Authority Host
2 parents 805fecf + 104adb0 commit 9f81bbe

File tree

8 files changed

+29
-14
lines changed

8 files changed

+29
-14
lines changed

docs/tutorials/azure.md

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ The following fields are used:
5858
* `aadClientID` and `aadClientSecret` are associated with the Service Principal. This is only used with Service Principal method documented in the next section.
5959
* `useManagedIdentityExtension` - this is set to `true` if you use either AKS Kubelet Identity or AAD Pod Identities methods documented in the next section.
6060
* `userAssignedIdentityID` - this contains the client id from the Managed identitty when using the AAD Pod Identities method documented in the next setion.
61+
* `activeDirectoryAuthorityHost` - this contains the uri to overwrite the default provided AAD Endpoint. This is useful for providing additional support where the endpoint is not available in the default cloud config from the [azure-sdk-for-go](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud#pkg-variables).
6162
* `useWorkloadIdentityExtension` - this is set to `true` if you use Workload Identity method documented in the next section.
6263

6364
The Azure DNS provider expects, by default, that the configuration file is at `/etc/kubernetes/azure.json`. This can be overridden with the `--azure-config-file` option when starting ExternalDNS.

main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,9 @@ func main() {
253253
}
254254
p, err = awssd.NewAWSSDProvider(domainFilter, cfg.AWSZoneType, cfg.DryRun, cfg.AWSSDServiceCleanup, cfg.TXTOwnerID, sd.New(awsSession))
255255
case "azure-dns", "azure":
256-
p, err = azure.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureSubscriptionID, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.DryRun)
256+
p, err = azure.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureSubscriptionID, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.AzureActiveDirectoryAuthorityHost, cfg.DryRun)
257257
case "azure-private-dns":
258-
p, err = azure.NewAzurePrivateDNSProvider(cfg.AzureConfigFile, domainFilter, zoneIDFilter, cfg.AzureSubscriptionID, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.DryRun)
258+
p, err = azure.NewAzurePrivateDNSProvider(cfg.AzureConfigFile, domainFilter, zoneIDFilter, cfg.AzureSubscriptionID, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.AzureActiveDirectoryAuthorityHost, cfg.DryRun)
259259
case "bluecat":
260260
p, err = bluecat.NewBluecatProvider(cfg.BluecatConfigFile, cfg.BluecatDNSConfiguration, cfg.BluecatDNSServerName, cfg.BluecatDNSDeployType, cfg.BluecatDNSView, cfg.BluecatGatewayHost, cfg.BluecatRootZone, cfg.TXTPrefix, cfg.TXTSuffix, domainFilter, zoneIDFilter, cfg.DryRun, cfg.BluecatSkipTLSVerify)
261261
case "vinyldns":

pkg/apis/externaldns/types.go

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ type Config struct {
101101
AzureResourceGroup string
102102
AzureSubscriptionID string
103103
AzureUserAssignedIdentityClientID string
104+
AzureActiveDirectoryAuthorityHost string
104105
BluecatDNSConfiguration string
105106
BluecatConfigFile string
106107
BluecatDNSView string

provider/azure/azure.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,16 @@ type AzureProvider struct {
5858
dryRun bool
5959
resourceGroup string
6060
userAssignedIdentityClientID string
61+
activeDirectoryAuthorityHost string
6162
zonesClient ZonesClient
6263
recordSetsClient RecordSetsClient
6364
}
6465

6566
// NewAzureProvider creates a new Azure provider.
6667
//
6768
// Returns the provider or an error if a provider could not be created.
68-
func NewAzureProvider(configFile string, domainFilter endpoint.DomainFilter, zoneNameFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, subscriptionID string, resourceGroup string, userAssignedIdentityClientID string, dryRun bool) (*AzureProvider, error) {
69-
cfg, err := getConfig(configFile, subscriptionID, resourceGroup, userAssignedIdentityClientID)
69+
func NewAzureProvider(configFile string, domainFilter endpoint.DomainFilter, zoneNameFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, subscriptionID string, resourceGroup string, userAssignedIdentityClientID string, activeDirectoryAuthorityHost string, dryRun bool) (*AzureProvider, error) {
70+
cfg, err := getConfig(configFile, subscriptionID, resourceGroup, userAssignedIdentityClientID, activeDirectoryAuthorityHost)
7071
if err != nil {
7172
return nil, fmt.Errorf("failed to read Azure config file '%s': %v", configFile, err)
7273
}
@@ -90,6 +91,7 @@ func NewAzureProvider(configFile string, domainFilter endpoint.DomainFilter, zon
9091
dryRun: dryRun,
9192
resourceGroup: cfg.ResourceGroup,
9293
userAssignedIdentityClientID: cfg.UserAssignedIdentityID,
94+
activeDirectoryAuthorityHost: cfg.ActiveDirectoryAuthorityHost,
9395
zonesClient: zonesClient,
9496
recordSetsClient: recordSetsClient,
9597
}, nil

provider/azure/azure_private_dns.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,16 @@ type AzurePrivateDNSProvider struct {
5252
dryRun bool
5353
resourceGroup string
5454
userAssignedIdentityClientID string
55+
activeDirectoryAuthorityHost string
5556
zonesClient PrivateZonesClient
5657
recordSetsClient PrivateRecordSetsClient
5758
}
5859

5960
// NewAzurePrivateDNSProvider creates a new Azure Private DNS provider.
6061
//
6162
// Returns the provider or an error if a provider could not be created.
62-
func NewAzurePrivateDNSProvider(configFile string, domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, subscriptionID string, resourceGroup string, userAssignedIdentityClientID string, dryRun bool) (*AzurePrivateDNSProvider, error) {
63-
cfg, err := getConfig(configFile, subscriptionID, resourceGroup, userAssignedIdentityClientID)
63+
func NewAzurePrivateDNSProvider(configFile string, domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, subscriptionID string, resourceGroup string, userAssignedIdentityClientID string, activeDirectoryAuthorityHost string, dryRun bool) (*AzurePrivateDNSProvider, error) {
64+
cfg, err := getConfig(configFile, subscriptionID, resourceGroup, userAssignedIdentityClientID, activeDirectoryAuthorityHost)
6465
if err != nil {
6566
return nil, fmt.Errorf("failed to read Azure config file '%s': %v", configFile, err)
6667
}
@@ -83,6 +84,7 @@ func NewAzurePrivateDNSProvider(configFile string, domainFilter endpoint.DomainF
8384
dryRun: dryRun,
8485
resourceGroup: cfg.ResourceGroup,
8586
userAssignedIdentityClientID: cfg.UserAssignedIdentityID,
87+
activeDirectoryAuthorityHost: cfg.ActiveDirectoryAuthorityHost,
8688
zonesClient: zonesClient,
8789
recordSetsClient: recordSetsClient,
8890
}, nil

provider/azure/azure_test.go

+9-6
Original file line numberDiff line numberDiff line change
@@ -222,20 +222,21 @@ func createMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values
222222
}
223223

224224
// newMockedAzureProvider creates an AzureProvider comprising the mocked clients for zones and recordsets
225-
func newMockedAzureProvider(domainFilter endpoint.DomainFilter, zoneNameFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, dryRun bool, resourceGroup string, userAssignedIdentityClientID string, zones []*dns.Zone, recordSets []*dns.RecordSet) (*AzureProvider, error) {
225+
func newMockedAzureProvider(domainFilter endpoint.DomainFilter, zoneNameFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, dryRun bool, resourceGroup string, userAssignedIdentityClientID string, activeDirectoryAuthorityHost string, zones []*dns.Zone, recordSets []*dns.RecordSet) (*AzureProvider, error) {
226226
zonesClient := newMockZonesClient(zones)
227227
recordSetsClient := newMockRecordSetsClient(recordSets)
228-
return newAzureProvider(domainFilter, zoneNameFilter, zoneIDFilter, dryRun, resourceGroup, userAssignedIdentityClientID, &zonesClient, &recordSetsClient), nil
228+
return newAzureProvider(domainFilter, zoneNameFilter, zoneIDFilter, dryRun, resourceGroup, userAssignedIdentityClientID, activeDirectoryAuthorityHost, &zonesClient, &recordSetsClient), nil
229229
}
230230

231-
func newAzureProvider(domainFilter endpoint.DomainFilter, zoneNameFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, dryRun bool, resourceGroup string, userAssignedIdentityClientID string, zonesClient ZonesClient, recordsClient RecordSetsClient) *AzureProvider {
231+
func newAzureProvider(domainFilter endpoint.DomainFilter, zoneNameFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, dryRun bool, resourceGroup string, userAssignedIdentityClientID string, activeDirectoryAuthorityHost string, zonesClient ZonesClient, recordsClient RecordSetsClient) *AzureProvider {
232232
return &AzureProvider{
233233
domainFilter: domainFilter,
234234
zoneNameFilter: zoneNameFilter,
235235
zoneIDFilter: zoneIDFilter,
236236
dryRun: dryRun,
237237
resourceGroup: resourceGroup,
238238
userAssignedIdentityClientID: userAssignedIdentityClientID,
239+
activeDirectoryAuthorityHost: activeDirectoryAuthorityHost,
239240
zonesClient: zonesClient,
240241
recordSetsClient: recordsClient,
241242
}
@@ -246,7 +247,7 @@ func validateAzureEndpoints(t *testing.T, endpoints []*endpoint.Endpoint, expect
246247
}
247248

248249
func TestAzureRecord(t *testing.T) {
249-
provider, err := newMockedAzureProvider(endpoint.NewDomainFilter([]string{"example.com"}), endpoint.NewDomainFilter([]string{}), provider.NewZoneIDFilter([]string{""}), true, "k8s", "",
250+
provider, err := newMockedAzureProvider(endpoint.NewDomainFilter([]string{"example.com"}), endpoint.NewDomainFilter([]string{}), provider.NewZoneIDFilter([]string{""}), true, "k8s", "", "",
250251
[]*dns.Zone{
251252
createMockZone("example.com", "/dnszones/example.com"),
252253
},
@@ -286,7 +287,7 @@ func TestAzureRecord(t *testing.T) {
286287
}
287288

288289
func TestAzureMultiRecord(t *testing.T) {
289-
provider, err := newMockedAzureProvider(endpoint.NewDomainFilter([]string{"example.com"}), endpoint.NewDomainFilter([]string{}), provider.NewZoneIDFilter([]string{""}), true, "k8s", "",
290+
provider, err := newMockedAzureProvider(endpoint.NewDomainFilter([]string{"example.com"}), endpoint.NewDomainFilter([]string{}), provider.NewZoneIDFilter([]string{""}), true, "k8s", "", "",
290291
[]*dns.Zone{
291292
createMockZone("example.com", "/dnszones/example.com"),
292293
},
@@ -381,6 +382,7 @@ func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordSetsC
381382
dryRun,
382383
"group",
383384
"",
385+
"",
384386
&zonesClient,
385387
client,
386388
)
@@ -440,7 +442,7 @@ func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordSetsC
440442
}
441443

442444
func TestAzureNameFilter(t *testing.T) {
443-
provider, err := newMockedAzureProvider(endpoint.NewDomainFilter([]string{"nginx.example.com"}), endpoint.NewDomainFilter([]string{"example.com"}), provider.NewZoneIDFilter([]string{""}), true, "k8s", "",
445+
provider, err := newMockedAzureProvider(endpoint.NewDomainFilter([]string{"nginx.example.com"}), endpoint.NewDomainFilter([]string{"example.com"}), provider.NewZoneIDFilter([]string{""}), true, "k8s", "", "",
444446
[]*dns.Zone{
445447
createMockZone("example.com", "/dnszones/example.com"),
446448
},
@@ -506,6 +508,7 @@ func testAzureApplyChangesInternalZoneName(t *testing.T, dryRun bool, client Rec
506508
dryRun,
507509
"group",
508510
"",
511+
"",
509512
&zonesClient,
510513
client,
511514
)

provider/azure/config.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ type config struct {
4141
UseManagedIdentityExtension bool `json:"useManagedIdentityExtension" yaml:"useManagedIdentityExtension"`
4242
UseWorkloadIdentityExtension bool `json:"useWorkloadIdentityExtension" yaml:"useWorkloadIdentityExtension"`
4343
UserAssignedIdentityID string `json:"userAssignedIdentityID" yaml:"userAssignedIdentityID"`
44+
ActiveDirectoryAuthorityHost string `json:"activeDirectoryAuthorityHost" yaml:"activeDirectoryAuthorityHost"`
4445
}
4546

46-
func getConfig(configFile, subscriptionID, resourceGroup, userAssignedIdentityClientID string) (*config, error) {
47+
func getConfig(configFile, subscriptionID, resourceGroup, userAssignedIdentityClientID, activeDirectoryAuthorityHost string) (*config, error) {
4748
contents, err := os.ReadFile(configFile)
4849
if err != nil {
4950
return nil, fmt.Errorf("failed to read Azure config file '%s': %v", configFile, err)
@@ -65,6 +66,10 @@ func getConfig(configFile, subscriptionID, resourceGroup, userAssignedIdentityCl
6566
if userAssignedIdentityClientID != "" {
6667
cfg.UserAssignedIdentityID = userAssignedIdentityClientID
6768
}
69+
// If activeDirectoryAuthorityHost is provided explicitly, override existing one in config file
70+
if activeDirectoryAuthorityHost != "" {
71+
cfg.ActiveDirectoryAuthorityHost = activeDirectoryAuthorityHost
72+
}
6873
return cfg, nil
6974
}
7075

provider/azure/config_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ func TestGetCloudConfiguration(t *testing.T) {
5151
func TestOverrideConfiguration(t *testing.T) {
5252
_, filename, _, _ := runtime.Caller(0)
5353
configFile := path.Join(path.Dir(filename), "config_test.json")
54-
cfg, err := getConfig(configFile, "subscription-override", "rg-override", "")
54+
cfg, err := getConfig(configFile, "subscription-override", "rg-override", "", "aad-endpoint-override")
5555
if err != nil {
5656
t.Errorf("got unexpected err %v", err)
5757
}
5858
assert.Equal(t, cfg.SubscriptionID, "subscription-override")
5959
assert.Equal(t, cfg.ResourceGroup, "rg-override")
60+
assert.Equal(t, cfg.ActiveDirectoryAuthorityHost, "aad-endpoint-override")
6061
}

0 commit comments

Comments
 (0)