AKAMAIEDGEDNS: Add ALIAS and AKAMAITLC support to the Akamai Edge DNS provider (#3836)

This commit is contained in:
Gabe Van Engel 2025-11-14 06:48:42 -08:00 committed by GitHub
parent 9d4cb301f3
commit 97209bc2fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 169 additions and 15 deletions

View file

@ -266,6 +266,38 @@ declare function ADGUARDHOME_A_PASSTHROUGH(source: string, destination: string):
*/ */
declare function AKAMAICDN(name: string, target: string, ...modifiers: RecordModifier[]): DomainModifier; declare function AKAMAICDN(name: string, target: string, ...modifiers: RecordModifier[]): DomainModifier;
/**
* `AKAMAITLC` is a proprietary Top-Level CNAME (TLC) record type specific to Akamai Edge DNS.
* It allows CNAME-like functionality at the zone apex (`@`) of a domain where regular CNAME records
* are not permitted.
*
* The difference between `AKAMAITLC` and `CNAME` is that `AKAMAITLC` records are resolved by Akamai Edge DNS
* servers instead of the client's resolver. This is similar to how `AKAMAICDN` records work, except that `AKAMAITLC`
* records can be pointed to any domain, not just Akamai properties. If you are pointing to an Akamai property,
* you should use `AKAMAICDN` instead.
*
* Important restrictions:
* - Can only be used at the zone apex (`@`)
* - Limited to one `AKAMAITLC` record per zone
* - Cannot coexist with an `AKAMAICDN` record at the apex
*
* The `answer_type` parameter controls which record types are returned when clients resolve the target:
* - `DUAL`: Returns both IPv4 (`A`) and IPv6 (`AAAA`) records
* - `A`: Returns only IPv4 records
* - `AAAA`: Returns only IPv6 records
*
* ## Example
* ```javascript
* D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
* // Redirect example.com to google.com, returning both A and AAAA records
* AKAMAITLC("@", "DUAL", "google.com."),
* );
* ```
*
* @see https://docs.dnscontrol.org/language-reference/domain-modifiers/service-provider-specific/akamai-edge-dns/akamaitlc
*/
declare function AKAMAITLC(name: string, answer_type: "DUAL" | "A" | "AAAA", target: string, ...modifiers: RecordModifier[]): DomainModifier;
/** /**
* ALIAS is a virtual record type that points a record at another record. It is analogous to a CNAME, but is usually resolved at request-time and served as an A record. Unlike CNAMEs, ALIAS records can be used at the zone apex (`@`) * ALIAS is a virtual record type that points a record at another record. It is analogous to a CNAME, but is usually resolved at request-time and served as an A record. Unlike CNAMEs, ALIAS records can be used at the zone apex (`@`)
* *

View file

@ -86,6 +86,7 @@
* [ADGUARDHOME_AAAA_PASSTHROUGH](language-reference/domain-modifiers/ADGUARDHOME_AAAA_PASSTHROUGH.md) * [ADGUARDHOME_AAAA_PASSTHROUGH](language-reference/domain-modifiers/ADGUARDHOME_AAAA_PASSTHROUGH.md)
* Akamai Edge Dns * Akamai Edge Dns
* [AKAMAICDN](language-reference/domain-modifiers/AKAMAICDN.md) * [AKAMAICDN](language-reference/domain-modifiers/AKAMAICDN.md)
* [AKAMAITLC](language-reference/domain-modifiers/AKAMAITLC.md)
* Amazon Route 53 * Amazon Route 53
* [R53_ALIAS](language-reference/domain-modifiers/R53_ALIAS.md) * [R53_ALIAS](language-reference/domain-modifiers/R53_ALIAS.md)
* Azure DNS * Azure DNS

View file

@ -0,0 +1,43 @@
---
name: AKAMAITLC
parameters:
- name
- answer_type
- target
- modifiers...
provider: AKAMAIEDGEDNS
parameter_types:
name: string
answer_type: '"DUAL" | "A" | "AAAA"'
target: string
"modifiers...": RecordModifier[]
---
`AKAMAITLC` is a proprietary Top-Level CNAME (TLC) record type specific to Akamai Edge DNS.
It allows CNAME-like functionality at the zone apex (`@`) of a domain where regular CNAME records
are not permitted.
The difference between `AKAMAITLC` and `CNAME` is that `AKAMAITLC` records are resolved by Akamai Edge DNS
servers instead of the client's resolver. This is similar to how `AKAMAICDN` records work, except that `AKAMAITLC`
records can be pointed to any domain, not just Akamai properties. If you are pointing to an Akamai property,
you should use `AKAMAICDN` instead.
Important restrictions:
- Can only be used at the zone apex (`@`)
- Limited to one `AKAMAITLC` record per zone
- Cannot coexist with an `AKAMAICDN` record at the apex
The `answer_type` parameter controls which record types are returned when clients resolve the target:
- `DUAL`: Returns both IPv4 (`A`) and IPv6 (`AAAA`) records
- `A`: Returns only IPv4 records
- `AAAA`: Returns only IPv6 records
## Example
{% code title="dnsconfig.js" %}
```javascript
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
// Redirect example.com to google.com, returning both A and AAAA records
AKAMAITLC("@", "DUAL", "google.com."),
);
```
{% endcode %}

View file

@ -35,9 +35,35 @@ Example:
``` ```
{% endcode %} {% endcode %}
## Limitations
### Records
#### AKAMAICDN
The AKAMAICDN target must be an Edge Hostname preconfigured in your Akamai account.
The AKAMAICDN record must have a TTL of 20 seconds.
The AKAMAICDN record may only be used at the zone apex (`@`) if an AKAMAITLC record hasn't been used.
#### AKAMAITLC
The AKAMAITLC record can only be used at the zone apex (`@`).
The AKAMAITLC record can only be used once per zone.
#### ALIAS
Akamai Edge DNS does directly support `ALIAS` records. This provider will convert `ALIAS` records used at the
zone apex (`@`) to `AKAMAITLC` records, and any other names to `CNAME` records.
### Secondary zones
This provider only supports creating primary zones in Akamai. If a secondary zone has been manually created, only `AKAMAICDN` and `AKAMAITLC` records can be managed, as all other records are read-only.
## Usage ## Usage
A new zone created by DNSControl: A new primary zone created by DNSControl:
```shell ```shell
dnscontrol create-domains dnscontrol create-domains
@ -70,11 +96,9 @@ var DSP_AKAMAIEDGEDNS = NewDnsProvider("akamaiedgedns");
D("example.com", REG_NONE, DnsProvider(DSP_AKAMAIEDGEDNS), D("example.com", REG_NONE, DnsProvider(DSP_AKAMAIEDGEDNS),
NAMESERVER_TTL(86400), NAMESERVER_TTL(86400),
AUTODNSSEC_ON, AUTODNSSEC_ON,
AKAMAICDN("@", "www.preconfigured.edgesuite.net", TTL(20)), AKAMAICDN("@", "preconfigured.edgesuite.net", TTL(20)),
AKAMAICDN("www", "www.preconfigured.edgesuite.net", TTL(20)),
A("foo", "1.2.3.4"), A("foo", "1.2.3.4"),
); );
``` ```
{% endcode %} {% endcode %}
AKAMAICDN is a proprietary record type that is used to configure [Zone Apex Mapping](https://www.akamai.com/blog/security/edge-dns--zone-apex-mapping---dnssec).
The AKAMAICDN target must be preconfigured in the Akamai network.

View file

@ -147,7 +147,7 @@ Jump to a table:
| Provider name | [`ALIAS`](../language-reference/domain-modifiers/ALIAS.md) | [`DNAME`](../language-reference/domain-modifiers/DNAME.md) | [`LOC`](../language-reference/domain-modifiers/LOC.md) | [`PTR`](../language-reference/domain-modifiers/PTR.md) | [`SOA`](../language-reference/domain-modifiers/SOA.md) | | Provider name | [`ALIAS`](../language-reference/domain-modifiers/ALIAS.md) | [`DNAME`](../language-reference/domain-modifiers/DNAME.md) | [`LOC`](../language-reference/domain-modifiers/LOC.md) | [`PTR`](../language-reference/domain-modifiers/PTR.md) | [`SOA`](../language-reference/domain-modifiers/SOA.md) |
| ------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | | ------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ |
| [`ADGUARDHOME`](adguardhome.md) | ✅ | ❔ | ❔ | ❔ | ❔ | | [`ADGUARDHOME`](adguardhome.md) | ✅ | ❔ | ❔ | ❔ | ❔ |
| [`AKAMAIEDGEDNS`](akamaiedgedns.md) | | ❔ | ✅ | ✅ | ❌ | | [`AKAMAIEDGEDNS`](akamaiedgedns.md) | | ❔ | ✅ | ✅ | ❌ |
| [`AUTODNS`](autodns.md) | ✅ | ❔ | ❔ | ✅ | ❔ | | [`AUTODNS`](autodns.md) | ✅ | ❔ | ❔ | ✅ | ❔ |
| [`AXFRDDNS`](axfrddns.md) | ❌ | ✅ | ✅ | ✅ | ❌ | | [`AXFRDDNS`](axfrddns.md) | ❌ | ✅ | ✅ | ✅ | ❌ |
| [`AZURE_DNS`](azure_dns.md) | ❌ | ❔ | ❌ | ✅ | ❔ | | [`AZURE_DNS`](azure_dns.md) | ❌ | ❔ | ❌ | ✅ | ❔ |

View file

@ -129,7 +129,7 @@ func (dc *DomainConfig) Punycode() error {
// Set the target: // Set the target:
switch rec.Type { // #rtype_variations switch rec.Type { // #rtype_variations
case "ALIAS", "MX", "NS", "CNAME", "DNAME", "PTR", "SRV", "URL", "URL301", "FRAME", "R53_ALIAS", "AKAMAICDN", "CLOUDNS_WR", "PORKBUN_URLFWD", "BUNNY_DNS_RDR": case "ALIAS", "MX", "NS", "CNAME", "DNAME", "PTR", "SRV", "URL", "URL301", "FRAME", "R53_ALIAS", "AKAMAICDN", "AKAMAITLC", "CLOUDNS_WR", "PORKBUN_URLFWD", "BUNNY_DNS_RDR":
// These rtypes are hostnames, therefore need to be converted (unlike, for example, an AAAA record) // These rtypes are hostnames, therefore need to be converted (unlike, for example, an AAAA record)
t, err := idna.ToASCII(rec.GetTargetField()) t, err := idna.ToASCII(rec.GetTargetField())
if err != nil { if err != nil {

View file

@ -147,6 +147,7 @@ type RecordConfig struct {
TlsaMatchingType uint8 `json:"tlsamatchingtype,omitempty"` TlsaMatchingType uint8 `json:"tlsamatchingtype,omitempty"`
R53Alias map[string]string `json:"r53_alias,omitempty"` R53Alias map[string]string `json:"r53_alias,omitempty"`
AzureAlias map[string]string `json:"azure_alias,omitempty"` AzureAlias map[string]string `json:"azure_alias,omitempty"`
AnswerType string `json:"answer_type,omitempty"`
UnknownTypeName string `json:"unknown_type_name,omitempty"` UnknownTypeName string `json:"unknown_type_name,omitempty"`
// Cloudflare-specific fields: // Cloudflare-specific fields:
@ -252,6 +253,7 @@ func (rc *RecordConfig) UnmarshalJSON(b []byte) error {
TlsaMatchingType uint8 `json:"tlsamatchingtype,omitempty"` TlsaMatchingType uint8 `json:"tlsamatchingtype,omitempty"`
R53Alias map[string]string `json:"r53_alias,omitempty"` R53Alias map[string]string `json:"r53_alias,omitempty"`
AzureAlias map[string]string `json:"azure_alias,omitempty"` AzureAlias map[string]string `json:"azure_alias,omitempty"`
AnswerType string `json:"answer_type,omitempty"`
UnknownTypeName string `json:"unknown_type_name,omitempty"` UnknownTypeName string `json:"unknown_type_name,omitempty"`
EnsureAbsent bool `json:"ensure_absent,omitempty"` // Override NO_PURGE and delete this record EnsureAbsent bool `json:"ensure_absent,omitempty"` // Override NO_PURGE and delete this record
@ -647,7 +649,7 @@ func Downcase(recs []*RecordConfig) {
r.Name = strings.ToLower(r.Name) r.Name = strings.ToLower(r.Name)
r.NameFQDN = strings.ToLower(r.NameFQDN) r.NameFQDN = strings.ToLower(r.NameFQDN)
switch r.Type { // #rtype_variations switch r.Type { // #rtype_variations
case "AKAMAICDN", "ALIAS", "AAAA", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "OPENPGPKEY", "SMIMEA", "PTR", "SRV", "TLSA", "AZURE_ALIAS": case "AKAMAICDN", "AKAMAITLC", "ALIAS", "AAAA", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "OPENPGPKEY", "SMIMEA", "PTR", "SRV", "TLSA", "AZURE_ALIAS":
// Target is case insensitive. Downcase it. // Target is case insensitive. Downcase it.
r.target = strings.ToLower(r.target) r.target = strings.ToLower(r.target)
// BUGFIX(tlim): isn't ALIAS in the wrong case statement? // BUGFIX(tlim): isn't ALIAS in the wrong case statement?
@ -675,7 +677,7 @@ func CanonicalizeTargets(recs []*RecordConfig, origin string) {
case "ALIAS", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "PTR", "SRV": case "ALIAS", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "PTR", "SRV":
// Target is a hostname that might be a shortname. Turn it into a FQDN. // Target is a hostname that might be a shortname. Turn it into a FQDN.
r.target = dnsutil.AddOrigin(r.target, originFQDN) r.target = dnsutil.AddOrigin(r.target, originFQDN)
case "A", "AKAMAICDN", "CAA", "DHCID", "CLOUDFLAREAPI_SINGLE_REDIRECT", "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE", "HTTPS", "IMPORT_TRANSFORM", "LOC", "OPENPGPKEY", "SMIMEA", "SSHFP", "SVCB", "TLSA", "TXT", "ADGUARDHOME_A_PASSTHROUGH", "ADGUARDHOME_AAAA_PASSTHROUGH": case "A", "AKAMAICDN", "AKAMAITLC", "CAA", "DHCID", "CLOUDFLAREAPI_SINGLE_REDIRECT", "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE", "HTTPS", "IMPORT_TRANSFORM", "LOC", "OPENPGPKEY", "SMIMEA", "SSHFP", "SVCB", "TLSA", "TXT", "ADGUARDHOME_A_PASSTHROUGH", "ADGUARDHOME_AAAA_PASSTHROUGH":
// Do nothing. // Do nothing.
case "SOA": case "SOA":
if r.target != "DEFAULT_NOT_SET." { if r.target != "DEFAULT_NOT_SET." {

View file

@ -72,7 +72,7 @@ func (rc *RecordConfig) PopulateFromStringFunc(rtype, contents, origin string, t
return fmt.Errorf("invalid IP in AAAA record: %s", contents) return fmt.Errorf("invalid IP in AAAA record: %s", contents)
} }
return rc.SetTargetIP(ip) // Reformat to canonical form. return rc.SetTargetIP(ip) // Reformat to canonical form.
case "AKAMAICDN", "ALIAS", "ANAME", "CNAME", "NS", "PTR": case "AKAMAICDN", "AKAMAITLC", "ALIAS", "ANAME", "CNAME", "NS", "PTR":
return rc.SetTarget(contents) return rc.SetTarget(contents)
case "CAA": case "CAA":
return rc.SetTargetCAAString(contents) return rc.SetTargetCAAString(contents)
@ -181,7 +181,7 @@ func (rc *RecordConfig) PopulateFromString(rtype, contents, origin string) error
return fmt.Errorf("invalid IP in AAAA record: %s", contents) return fmt.Errorf("invalid IP in AAAA record: %s", contents)
} }
return rc.SetTargetIP(ip) // Reformat to canonical form. return rc.SetTargetIP(ip) // Reformat to canonical form.
case "AKAMAICDN", "ALIAS", "ANAME", "CNAME", "NS", "PTR": case "AKAMAICDN", "AKAMAITLC", "ALIAS", "ANAME", "CNAME", "NS", "PTR":
return rc.SetTarget(contents) return rc.SetTarget(contents)
case "CAA": case "CAA":
return rc.SetTargetCAAString(contents) return rc.SetTargetCAAString(contents)

View file

@ -57,6 +57,8 @@ func (rc *RecordConfig) GetTargetCombined() string {
case "AZURE_ALIAS": case "AZURE_ALIAS":
// Differentiate between multiple AZURE_ALIASs on the same label. // Differentiate between multiple AZURE_ALIASs on the same label.
return fmt.Sprintf("%s atype=%s", rc.target, rc.AzureAlias["type"]) return fmt.Sprintf("%s atype=%s", rc.target, rc.AzureAlias["type"])
case "AKAMAITLC":
return fmt.Sprintf("%s %s", rc.AnswerType, rc.target)
default: default:
// Just return the target. // Just return the target.
return rc.target return rc.target

View file

@ -331,6 +331,20 @@ var AAAA = recordBuilder('AAAA');
// AKAMAICDN(name, target, recordModifiers...) // AKAMAICDN(name, target, recordModifiers...)
var AKAMAICDN = recordBuilder('AKAMAICDN'); var AKAMAICDN = recordBuilder('AKAMAICDN');
// AKAMAITLC(name, answer_type, target, recordModifiers...)
var AKAMAITLC = recordBuilder('AKAMAITLC', {
args: [
['name', _.isString],
['answer_type', function(value) { return _.isString(value) && ['DUAL', 'A', 'AAAA'].indexOf(value) !== -1; }],
['target', _.isString],
],
transform: function (record, args, modifier) {
record.name = args.name;
record.answer_type = args.answer_type;
record.target = args.target;
},
});
// ALIAS(name,target, recordModifiers...) // ALIAS(name,target, recordModifiers...)
var ALIAS = recordBuilder('ALIAS'); var ALIAS = recordBuilder('ALIAS');

View file

@ -743,6 +743,7 @@ var providerCapabilityChecks = []pairTypeCapability{
// If a zone uses rType X, the provider must support capability Y. // If a zone uses rType X, the provider must support capability Y.
// {"X", providers.Y}, // {"X", providers.Y},
capabilityCheck("AKAMAICDN", providers.CanUseAKAMAICDN), capabilityCheck("AKAMAICDN", providers.CanUseAKAMAICDN),
capabilityCheck("AKAMAITLC", providers.CanUseAKAMAITLC),
capabilityCheck("ALIAS", providers.CanUseAlias), capabilityCheck("ALIAS", providers.CanUseAlias),
capabilityCheck("AUTODNSSEC", providers.CanAutoDNSSEC), capabilityCheck("AUTODNSSEC", providers.CanAutoDNSSEC),
capabilityCheck("AZURE_ALIAS", providers.CanUseAzureAlias), capabilityCheck("AZURE_ALIAS", providers.CanUseAzureAlias),

View file

@ -28,7 +28,8 @@ var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Can(), providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(), providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAKAMAICDN: providers.Can(), providers.CanUseAKAMAICDN: providers.Can(),
providers.CanUseAlias: providers.Cannot(), providers.CanUseAKAMAITLC: providers.Can(),
providers.CanUseAlias: providers.Can("Akamai Edge DNS does not directly support ALIAS. Apex record will be converted to AKAMAITLC, any others to CNAME."),
providers.CanUseCAA: providers.Can(), providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(), providers.CanUseDS: providers.Cannot(),
providers.CanUseDSForChildren: providers.Can(), providers.CanUseDSForChildren: providers.Can(),
@ -58,6 +59,7 @@ func init() {
} }
providers.RegisterDomainServiceProviderType(providerName, fns, features) providers.RegisterDomainServiceProviderType(providerName, fns, features)
providers.RegisterCustomRecordType("AKAMAICDN", providerName, "") providers.RegisterCustomRecordType("AKAMAICDN", providerName, "")
providers.RegisterCustomRecordType("AKAMAITLC", providerName, "")
providers.RegisterMaintainer(providerName, providerMaintainer) providers.RegisterMaintainer(providerName, providerMaintainer)
} }
@ -109,6 +111,11 @@ func (a *edgeDNSProvider) EnsureZoneExists(domain string, metadata map[string]st
// GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records.
func (a *edgeDNSProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { func (a *edgeDNSProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) {
if err := a.preprocessConfig(dc); err != nil {
return nil, 0, err
}
keysToUpdate, toReport, actualChangeCount, err := diff.NewCompat(dc).ChangedGroups(existingRecords) keysToUpdate, toReport, actualChangeCount, err := diff.NewCompat(dc).ChangedGroups(existingRecords)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
@ -235,3 +242,19 @@ func (a *edgeDNSProvider) ListZones() ([]string, error) {
} }
return zones, nil return zones, nil
} }
func (a *edgeDNSProvider) preprocessConfig(dc *models.DomainConfig) error {
for _, rec := range dc.Records {
// Convert ALIAS records to the Akamai equivalents. AKAMAITLC is only valid
// at the apex, so any other ALIAS must be converted to CNAME.
if rec.Type == "ALIAS" {
if rec.Name == "@" {
rec.ChangeType("AKAMAITLC", dc.Name)
rec.AnswerType = "DUAL"
} else {
rec.ChangeType("CNAME", dc.Name)
}
}
}
return nil
}

View file

@ -11,11 +11,11 @@ https://github.com/akamai/AkamaiOPEN-edgegrid-golang
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/StackExchange/dnscontrol/v4/models" "github.com/StackExchange/dnscontrol/v4/models"
"github.com/StackExchange/dnscontrol/v4/pkg/printer" "github.com/StackExchange/dnscontrol/v4/pkg/printer"
dnsv2 "github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v2" dnsv2 "github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v2"
"github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid" "github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"
"strings"
) )
// initialize initializes the "Akamai OPEN EdgeGrid" library // initialize initializes the "Akamai OPEN EdgeGrid" library
@ -293,6 +293,14 @@ func getRecords(zonename string) ([]*models.RecordConfig, error) {
TTL: uint32(akattl), TTL: uint32(akattl),
} }
rc.SetLabelFromFQDN(akaname, zonename) rc.SetLabelFromFQDN(akaname, zonename)
if akatype == "AKAMAITLC" {
part := strings.Fields(r)
if len(part) != 2 {
return nil, fmt.Errorf("AKAMAITLC value does not contain 2 fields: (%#v)", r)
}
rc.AnswerType = part[0]
r = part[1]
}
err = rc.PopulateFromString(akatype, r, zonename) err = rc.PopulateFromString(akatype, r, zonename)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -111,6 +111,9 @@ const (
// DocOfficiallySupported means it is actively used and maintained by stack exchange // DocOfficiallySupported means it is actively used and maintained by stack exchange
DocOfficiallySupported DocOfficiallySupported
// CanUseAKAMAITLC indicates the provider supports the specific AKAMAITLC records that only the Akamai EdgeDns provider supports
CanUseAKAMAITLC
) )
var providerCapabilities = map[string]map[Capability]bool{} var providerCapabilities = map[string]map[Capability]bool{}

View file

@ -36,11 +36,12 @@ func _() {
_ = x[DocCreateDomains-25] _ = x[DocCreateDomains-25]
_ = x[DocDualHost-26] _ = x[DocDualHost-26]
_ = x[DocOfficiallySupported-27] _ = x[DocOfficiallySupported-27]
_ = x[CanUseAKAMAITLC-28]
} }
const _Capability_name = "CanAutoDNSSECCanConcurCanGetZonesCanOnlyDiff1FeaturesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDHCIDCanUseDNAMECanUseDSCanUseDSForChildrenCanUseHTTPSCanUseLOCCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSMIMEACanUseSOACanUseSRVCanUseSSHFPCanUseSVCBCanUseTLSACanUseDNSKEYCanUseOPENPGPKEYDocCreateDomainsDocDualHostDocOfficiallySupported" const _Capability_name = "CanAutoDNSSECCanConcurCanGetZonesCanOnlyDiff1FeaturesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDHCIDCanUseDNAMECanUseDSCanUseDSForChildrenCanUseHTTPSCanUseLOCCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSMIMEACanUseSOACanUseSRVCanUseSSHFPCanUseSVCBCanUseTLSACanUseDNSKEYCanUseOPENPGPKEYDocCreateDomainsDocDualHostDocOfficiallySupportedCanUseAKAMAITLC"
var _Capability_index = [...]uint16{0, 13, 22, 33, 53, 68, 79, 95, 104, 115, 126, 134, 153, 164, 173, 184, 193, 211, 223, 232, 241, 252, 262, 272, 284, 300, 316, 327, 349} var _Capability_index = [...]uint16{0, 13, 22, 33, 53, 68, 79, 95, 104, 115, 126, 134, 153, 164, 173, 184, 193, 211, 223, 232, 241, 252, 262, 272, 284, 300, 316, 327, 349, 364}
func (i Capability) String() string { func (i Capability) String() string {
idx := int(i) - 0 idx := int(i) - 0