Skip to content

Commit

Permalink
Treat any annotations with a recognised prefix, but that are not othe…
Browse files Browse the repository at this point in the history
…rwise recognised, as provider properties.

Replace '/' characters in provider property names with '-'.
Add annotation support to the `DNSEndpoint` custom resource source.
  • Loading branch information
Dadeos-Menlo committed Jan 24, 2025
1 parent 0d904fe commit d39ff59
Show file tree
Hide file tree
Showing 18 changed files with 231 additions and 201 deletions.
10 changes: 8 additions & 2 deletions docs/annotations/annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The following table documents which sources support which annotations:
| Connector | | | | | | |
| Contour | Yes | Yes[^1] | | Yes | Yes | Yes |
| CloudFoundry | | | | | | |
| CRD | | | | | | |
| CRD | | Yes | | Yes | Yes | Yes |
| F5 | | | | Yes | Yes | |
| Gateway | Yes | Yes[^1] | | Yes[^4] | Yes | Yes |
| Gloo | | | | Yes | Yes[^5] | Yes[^5] |
Expand Down Expand Up @@ -99,7 +99,13 @@ It must be between 1 and 2,147,483,647 seconds.

## Provider-specific annotations

Some providers define their own annotations. Cloud-specific annotations have keys prefixed as follows:
Provider-specific annotations are prefixed by `external-dns.alpha.kubernetes.io/`
and the provider's name, for example `external-dns.alpha.kubernetes.io/aws-`.

Individual provider implementations should be examined to identify the additional
configuration offered via supported annotations.

Currently, supported Cloud-specific annotations include the following prefixes:

| Cloud | Annotation prefix |
|------------|------------------------------------------------|
Expand Down
21 changes: 7 additions & 14 deletions docs/sources/crd/dnsendpoint-aws-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,10 @@ apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: examplednsrecord
spec:
endpoints:
- dnsName: subdomain.foo.bar.com
providerSpecific:
- name: "aws/failover"
value: "PRIMARY"
- name: "aws/health-check-id"
value: "asdf1234-as12-as12-as12-asdf12345678"
- name: "aws/evaluate-target-health"
value: "true"
recordType: CNAME
setIdentifier: some-unique-id
targets:
- other-subdomain.foo.bar.com
annotations:
external-dns.alpha.kubernetes.io/hostname: "subdomain.foo.bar.com"
external-dns.alpha.kubernetes.io/target: "other-subdomain.foo.bar.com"
external-dns.alpha.kubernetes.io/set-identifier: "some-unique-id"
external-dns.alpha.kubernetes.io/aws-failover: "PRIMARY"
external-dns.alpha.kubernetes.io/aws-health-check-id: "asdf1234-as12-as12-as12-asdf12345678"
external-dns.alpha.kubernetes.io/aws-evaluate-target-health: "true"
16 changes: 5 additions & 11 deletions docs/sources/crd/dnsendpoint-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,8 @@ apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: examplednsrecord
spec:
endpoints:
- dnsName: foo.bar.com
recordTTL: 180
recordType: A
targets:
- 192.168.99.216
# Provider specific configurations are set like an annotation would on other sources
providerSpecific:
- name: external-dns.alpha.kubernetes.io/cloudflare-proxied
value: "true"
annotations:
external-dns.alpha.kubernetes.io/hostname: foo.bar.com
external-dns.alpha.kubernetes.io/target: 192.168.99.216
external-dns.alpha.kubernetes.io/ttl: "180"
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
6 changes: 0 additions & 6 deletions docs/tutorials/webhook-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ The default recommended port for the provider endpoints is `8888`, and should li

The default recommended port for the exposed endpoints is `8080`, and it should be bound to all interfaces (`0.0.0.0`)

## Custom Annotations

The Webhook provider supports custom annotations for DNS records. This feature allows users to define additional configuration options for DNS records managed by the Webhook provider. Custom annotations are defined using the annotation format `external-dns.alpha.kubernetes.io/webhook-<custom-annotation>`.

Custom annotations can be used to influence DNS record creation and updates. Providers implementing the Webhook API should document the custom annotations they support and how they affect DNS record management.

## Provider registry

To simplify the discovery of providers, we will accept pull requests that will add links to providers in this documentation. This list will only serve the purpose of simplifying finding providers and will not constitute an official endorsement of any of the externally implemented providers unless otherwise stated.
Expand Down
20 changes: 10 additions & 10 deletions provider/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,19 @@ const (
route53PageSize int32 = 300
// providerSpecificAlias specifies whether a CNAME endpoint maps to an AWS ALIAS record.
providerSpecificAlias = "alias"
providerSpecificTargetHostedZone = "aws/target-hosted-zone"
providerSpecificTargetHostedZone = "aws-target-hosted-zone"
// providerSpecificEvaluateTargetHealth specifies whether an AWS ALIAS record
// has the EvaluateTargetHealth field set to true. Present iff the endpoint
// has a `providerSpecificAlias` value of `true`.
providerSpecificEvaluateTargetHealth = "aws/evaluate-target-health"
providerSpecificWeight = "aws/weight"
providerSpecificRegion = "aws/region"
providerSpecificFailover = "aws/failover"
providerSpecificGeolocationContinentCode = "aws/geolocation-continent-code"
providerSpecificGeolocationCountryCode = "aws/geolocation-country-code"
providerSpecificGeolocationSubdivisionCode = "aws/geolocation-subdivision-code"
providerSpecificMultiValueAnswer = "aws/multi-value-answer"
providerSpecificHealthCheckID = "aws/health-check-id"
providerSpecificEvaluateTargetHealth = "aws-evaluate-target-health"
providerSpecificWeight = "aws-weight"
providerSpecificRegion = "aws-region"
providerSpecificFailover = "aws-failover"
providerSpecificGeolocationContinentCode = "aws-geolocation-continent-code"
providerSpecificGeolocationCountryCode = "aws-geolocation-country-code"
providerSpecificGeolocationSubdivisionCode = "aws-geolocation-subdivision-code"
providerSpecificMultiValueAnswer = "aws-multi-value-answer"
providerSpecificHealthCheckID = "aws-health-check-id"
sameZoneAlias = "same-zone"
)

Expand Down
12 changes: 7 additions & 5 deletions provider/cloudflare/cloudflare.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
"sigs.k8s.io/external-dns/endpoint"
"sigs.k8s.io/external-dns/plan"
"sigs.k8s.io/external-dns/provider"
"sigs.k8s.io/external-dns/source"
)

const (
Expand All @@ -44,6 +43,9 @@ const (
cloudFlareUpdate = "UPDATE"
// defaultCloudFlareRecordTTL 1 = automatic
defaultCloudFlareRecordTTL = 1

// providerSpecificProxied specifies whether traffic will go through Cloudflare
providerSpecificProxied = "cloudflare-proxied"
)

// We have to use pointers to bools now, as the upstream cloudflare-go library requires them
Expand Down Expand Up @@ -423,7 +425,7 @@ func (p *CloudFlareProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]
if proxied {
e.RecordTTL = 0
}
e.SetProviderSpecificProperty(source.CloudflareProxiedKey, strconv.FormatBool(proxied))
e.SetProviderSpecificProperty(providerSpecificProxied, strconv.FormatBool(proxied))

adjustedEndpoints = append(adjustedEndpoints, e)
}
Expand Down Expand Up @@ -520,10 +522,10 @@ func shouldBeProxied(endpoint *endpoint.Endpoint, proxiedByDefault bool) bool {
proxied := proxiedByDefault

for _, v := range endpoint.ProviderSpecific {
if v.Name == source.CloudflareProxiedKey {
if v.Name == providerSpecificProxied {
b, err := strconv.ParseBool(v.Value)
if err != nil {
log.Errorf("Failed to parse annotation [%s]: %v", source.CloudflareProxiedKey, err)
log.Errorf("Failed parsing value of %s: %v", providerSpecificProxied, err)
} else {
proxied = b
}
Expand Down Expand Up @@ -568,7 +570,7 @@ func groupByNameAndType(records []cloudflare.DNSRecord) []*endpoint.Endpoint {
records[0].Type,
endpoint.TTL(records[0].TTL),
targets...).
WithProviderSpecific(source.CloudflareProxiedKey, strconv.FormatBool(*records[0].Proxied)),
WithProviderSpecific(providerSpecificProxied, strconv.FormatBool(*records[0].Proxied)),
)
}

Expand Down
26 changes: 13 additions & 13 deletions provider/cloudflare/cloudflare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ func TestCloudflareProxiedOverrideTrue(t *testing.T) {
Targets: endpoint.Targets{"127.0.0.1"},
ProviderSpecific: endpoint.ProviderSpecific{
endpoint.ProviderSpecificProperty{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "true",
},
},
Expand Down Expand Up @@ -511,7 +511,7 @@ func TestCloudflareProxiedOverrideFalse(t *testing.T) {
Targets: endpoint.Targets{"127.0.0.1"},
ProviderSpecific: endpoint.ProviderSpecific{
endpoint.ProviderSpecificProperty{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "false",
},
},
Expand Down Expand Up @@ -543,7 +543,7 @@ func TestCloudflareProxiedOverrideIllegal(t *testing.T) {
Targets: endpoint.Targets{"127.0.0.1"},
ProviderSpecific: endpoint.ProviderSpecific{
endpoint.ProviderSpecificProperty{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "asfasdfa",
},
},
Expand Down Expand Up @@ -594,7 +594,7 @@ func TestCloudflareSetProxied(t *testing.T) {
Targets: endpoint.Targets{"127.0.0.1"},
ProviderSpecific: endpoint.ProviderSpecific{
endpoint.ProviderSpecificProperty{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "true",
},
},
Expand Down Expand Up @@ -964,7 +964,7 @@ func TestCloudflareGroupByNameAndType(t *testing.T) {
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "false",
},
},
Expand Down Expand Up @@ -998,7 +998,7 @@ func TestCloudflareGroupByNameAndType(t *testing.T) {
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "false",
},
},
Expand Down Expand Up @@ -1046,7 +1046,7 @@ func TestCloudflareGroupByNameAndType(t *testing.T) {
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "false",
},
},
Expand All @@ -1059,7 +1059,7 @@ func TestCloudflareGroupByNameAndType(t *testing.T) {
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "false",
},
},
Expand Down Expand Up @@ -1100,7 +1100,7 @@ func TestCloudflareGroupByNameAndType(t *testing.T) {
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "false",
},
},
Expand All @@ -1113,7 +1113,7 @@ func TestCloudflareGroupByNameAndType(t *testing.T) {
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "false",
},
},
Expand Down Expand Up @@ -1154,7 +1154,7 @@ func TestCloudflareGroupByNameAndType(t *testing.T) {
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "false",
},
},
Expand Down Expand Up @@ -1293,7 +1293,7 @@ func TestCloudflareComplexUpdate(t *testing.T) {
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "true",
},
},
Expand Down Expand Up @@ -1388,7 +1388,7 @@ func TestCustomTTLWithEnabledProxyNotChanged(t *testing.T) {
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: providerSpecificProxied,
Value: "true",
},
},
Expand Down
2 changes: 1 addition & 1 deletion provider/ibmcloud/ibmcloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ func shouldBeProxied(endpoint *endpoint.Endpoint, proxiedByDefault bool) bool {
if v.Name == proxyFilter {
b, err := strconv.ParseBool(v.Value)
if err != nil {
log.Errorf("Failed to parse annotation [%s]: %v", proxyFilter, err)
log.Errorf("Failed parsing value of %s: %v", proxyFilter, err)
} else {
proxied = b
}
Expand Down
14 changes: 7 additions & 7 deletions provider/ibmcloud/ibmcloud_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func newTestIBMCloudProvider(private bool) *IBMCloudProvider {
Targets: endpoint.Targets{"4.3.2.1"},
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "ibmcloud-vpc",
Name: vpcFilter,
Value: "crn:v1:staging:public:is:us-south:a/0821fa9f9ebcc7b7c9a0d6e9bf9442a4::vpc:be33cdad-9a03-4bfa-82ca-eadb9f1de688",
},
},
Expand Down Expand Up @@ -223,7 +223,7 @@ func TestPublic_ApplyChanges(t *testing.T) {
Targets: endpoint.NewTargets("4.3.2.1"),
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "ibmcloud-proxied",
Name: proxyFilter,
Value: "false",
},
},
Expand All @@ -237,7 +237,7 @@ func TestPublic_ApplyChanges(t *testing.T) {
Targets: endpoint.NewTargets("1.2.3.4"),
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "ibmcloud-proxied",
Name: proxyFilter,
Value: "false",
},
},
Expand All @@ -251,7 +251,7 @@ func TestPublic_ApplyChanges(t *testing.T) {
Targets: endpoint.NewTargets("1.2.3.4", "5.6.7.8"),
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "ibmcloud-proxied",
Name: proxyFilter,
Value: "true",
},
},
Expand Down Expand Up @@ -284,7 +284,7 @@ func TestPrivate_ApplyChanges(t *testing.T) {
Targets: endpoint.NewTargets("4.3.2.1"),
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "ibmcloud-vpc",
Name: vpcFilter,
Value: "crn:v1:staging:public:is:us-south:a/0821fa9f9ebcc7b7c9a0d6e9bf9442a4::vpc:be33cdad-9a03-4bfa-82ca-eadb9f1de688",
},
},
Expand Down Expand Up @@ -352,7 +352,7 @@ func TestAdjustEndpoints(t *testing.T) {
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
{
Name: "ibmcloud-proxied",
Name: proxyFilter,
Value: "1",
},
},
Expand All @@ -364,7 +364,7 @@ func TestAdjustEndpoints(t *testing.T) {

assert.Equal(t, endpoint.TTL(0), ep[0].RecordTTL)
assert.Equal(t, "test.example.com", ep[0].DNSName)
proxied, _ := ep[0].GetProviderSpecificProperty("ibmcloud-proxied")
proxied, _ := ep[0].GetProviderSpecificProperty(proxyFilter)
assert.Equal(t, "true", proxied)
}

Expand Down
2 changes: 1 addition & 1 deletion provider/scaleway/scaleway.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import (
const (
scalewyRecordTTL uint32 = 300
scalewayDefaultPriority uint32 = 0
scalewayPriorityKey string = "scw/priority"
scalewayPriorityKey string = "scw-priority"
)

// ScalewayProvider implements the DNS provider for Scaleway DNS
Expand Down
4 changes: 2 additions & 2 deletions source/ambassador_host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ func TestAmbassadorHostSource(t *testing.T) {
Name: "basic-host",
Annotations: map[string]string{
ambHostAnnotation: hostAnnotation,
CloudflareProxiedKey: "true",
"external-dns.alpha.kubernetes.io/cloudflare-proxied": "true",
},
},
Spec: &ambassador.HostSpec{
Expand All @@ -272,7 +272,7 @@ func TestAmbassadorHostSource(t *testing.T) {
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"1.1.1.1"},
ProviderSpecific: endpoint.ProviderSpecific{{
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
Name: "cloudflare-proxied",
Value: "true",
}},
},
Expand Down
Loading

0 comments on commit d39ff59

Please sign in to comment.