NEW FEATURE: Support DNS LOC record type (#2174)

This commit is contained in:
Paul Dee 2023-03-16 19:04:20 +01:00 committed by GitHub
parent 31765b0bef
commit 3b6591fd95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 1554 additions and 62 deletions

View file

@ -79,6 +79,7 @@ func matrixData() *FeatureMatrix {
DomainModifierAlias = "ALIAS"
DomainModifierDnssec = "AUTODNSSEC"
DomainModifierCaa = "CAA"
DomainModifierLoc = "LOC"
DomainModifierPtr = "PTR"
DomainModifierNaptr = "NAPTR"
DomainModifierSoa = "SOA"
@ -101,6 +102,7 @@ func matrixData() *FeatureMatrix {
DomainModifierAlias,
DomainModifierDnssec,
DomainModifierCaa,
DomainModifierLoc,
DomainModifierPtr,
DomainModifierNaptr,
DomainModifierSoa,
@ -182,6 +184,10 @@ func matrixData() *FeatureMatrix {
DomainModifierDs,
providers.CanUseDS,
)
setCapability(
DomainModifierLoc,
providers.CanUseLOC,
)
setCapability(
DomainModifierNaptr,
providers.CanUseNAPTR,

View file

@ -684,6 +684,60 @@ declare function IGNORE_TARGET(pattern: string, rType: string): DomainModifier;
*/
declare function INCLUDE(domain: string): DomainModifier;
/**
* ## Description ##
*
* Strictly follows [RFC 1876](https://datatracker.ietf.org/doc/html/rfc1876).
*
* Fairly intuitive.
*
* There are some behaviours that you should be aware of, however:
*
* > If omitted, minutes and seconds default to zero, size defaults to 1m,
* horizontal precision defaults to 10000m, and vertical precision
* defaults to 10m. These defaults are chosen to represent typical
* ZIP/postal code area sizes, since it is often easy to find
* approximate geographical location by ZIP/postal code.
*
* Alas, the world does not revolve around US ZIP codes, but here we are. Internally,
* the LOC record type will supply defaults where values were absent on DNS import.
* One must supply the `LOC()` js helper all parameters. If that seems like too
* much work, see also helper functions:
*
* * [`LOC_BUILDER_DD()`](../record/LOC_BUILDER_DD.md) - build a `LOC` by supplying only **d**ecimal **d**egrees.
* * [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131S 151°1251E
* * [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
* * [`LOC_BUILDER_STR({})`](LOC_BUILDER_STR.md) - tries LOC_BUILDER_DM*STR()
*
* ## Format ##
*
* The coordinate format for `LOC()` is:
*
* `degrees,minutes,seconds,[NnSs],deg,min,sec,[EeWw],altitude,size,horizontal_precision,vertical_precision`
*
* ## Examples ##
*
* ```javascript
* D("foo.com","none"
* // LOC "subdomain", d1, m1, s1, "[NnSs]", d2, m2, s2, "[EeWw]", alt, siz, hp, vp)
* //42 21 54 N 71 06 18 W -24m 30m
* , LOC("@", 42, 21, 54, "N", 71, 6, 18, "W", -24, 30, 0, 0)
* //42 21 43.952 N 71 5 6.344 W -24m 1m 200m 10m
* , LOC("a", 42, 21, 43.952, "N", 71, 5, 6.344, "W", -24, 1, 200, 10)
* //52 14 05 N 00 08 50 E 10m
* , LOC("b", 52, 14, 5, "N", 0, 8, 50, "E", 10, 0, 0, 0)
* //32 7 19 S 116 2 25 E 10m
* , LOC("c", 32, 7, 19, "S",116, 2, 25, "E", 10, 0, 0, 0)
* //42 21 28.764 N 71 00 51.617 W -44m 2000m
* , LOC("d", 42, 21, 28.764, "N", 71, 0, 51.617, "W", -44, 2000, 0, 0)
* );
*
* ```
*
* @see https://dnscontrol.org/js#LOC
*/
declare function LOC(deg1: uint32, min1: uint32, sec1: float32, deg2: uint32, min2: uint32, sec2: float32, altitude: uint32, size: float32, horizontal_precision: float32, vertical_precision: float32): DomainModifier;
/**
* MX adds an MX record to the domain.
*
@ -2122,6 +2176,177 @@ declare function CAA_BUILDER(opts: { label?: string; iodef: string; iodef_critic
*/
declare function DMARC_BUILDER(opts: { label?: string; version?: string; policy: 'none' | 'quarantine' | 'reject'; subdomainPolicy?: 'none' | 'quarantine' | 'reject'; alignmentSPF?: 'strict' | 's' | 'relaxed' | 'r'; alignmentDKIM?: 'strict' | 's' | 'relaxed' | 'r'; percent?: number; rua?: string[]; ruf?: string[]; failureOptions?: { SPF: boolean, DKIM: boolean } | string; failureFormat?: string; reportInterval?: Duration; ttl?: Duration }): RecordModifier;
/**
* `LOC_BUILDER_DD({})` actually takes an object with the mentioned properties.
*
* A helper to build [`LOC`](../domain/LOC.md) records. Supply four parameters instead of 12.
*
* Internally assumes some defaults for [`LOC`](../domain/LOC.md) records.
*
* The cartesian coordinates are decimal degrees, like you typically find in e.g. Google Maps.
*
* Examples.
*
* Big Ben:
* `51.50084265331501, -0.12462541415599787`
*
* The White House:
* `38.89775977858357, -77.03655125982903`
*
* ```javascript
* D("example.com","none"
* , LOC_BUILDER_DD({
* label: "big-ben",
* x: 51.50084265331501,
* y: -0.12462541415599787,
* alt: 6,
* })
* , LOC_BUILDER_DD({
* label: "white-house",
* x: 38.89775977858357,
* y: -77.03655125982903,
* alt: 19,
* })
* , LOC_BUILDER_DD({
* label: "white-house-ttl",
* x: 38.89775977858357,
* y: -77.03655125982903,
* alt: 19,
* ttl: "5m",
* })
* );
*
* ```
*
* Part of the series:
* * [`LOC()`](LOC.md) - build a `LOC` by supplying all 12 parameters
* * [`LOC_BUILDER_DD({})`](../record/LOC_BUILDER_DD.md) - accepts cartesian x, y
* * [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131S 151°1251E
* * [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
* * [`LOC_BUILDER_STR({})`](LOC_BUILDER_STR.md) - tries LOC_BUILDER_DM*STR()
*
* @see https://dnscontrol.org/js#LOC_BUILDER_DD
*/
declare function LOC_BUILDER_DD(subdomain: string, decimal_degrees_x: float32, decimal_degrees_y: float32, altitude: float32, ttl: int): RecordModifier;
/**
* `LOC_BUILDER_DMM({})` actually takes an object with the mentioned properties.
*
* A helper to build [`LOC`](../domain/LOC.md) records. Supply three parameters instead of 12.
*
* Internally assumes some defaults for [`LOC`](../domain/LOC.md) records.
*
* Accepts a string with decimal minutes (DMM) coordinates in the form: 25.24°S 153.15°E
*
* Note that the following are acceptable forms (symbols differ):
* * `25.24°S 153.15°E`
* * `25.24 S 153.15 E`
* * `25.24° S 153.15° E`
* * `25.24S 153.15E`
*
* ```javascript
* D("example.com","none"
* LOC_BUILDER_STR({
* label: "tasmania",
* str: '42°S 147°E',
* alt: 3,
* })
* );
*
* ```
*
* Part of the series:
* * [`LOC()`](LOC.md) - build a `LOC` by supplying all 12 parameters
* * [`LOC_BUILDER_DD({})`](../record/LOC_BUILDER_DD.md) - accepts cartesian x, y
* * [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131S 151°1251E
* * [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
* * [`LOC_BUILDER_STR({})`](LOC_BUILDER_STR.md) - tries LOC_BUILDER_DM*STR()
*
* @see https://dnscontrol.org/js#LOC_BUILDER_DMM
*/
declare function LOC_BUILDER_DMM(subdomain: string, input_string: string, altitude: float32, ttl: int): RecordModifier;
/**
* `LOC_BUILDER_DMS_STR({})` actually takes an object with the mentioned properties.
*
* A helper to build [`LOC`](../domain/LOC.md) records. Supply three parameters instead of 12.
*
* Internally assumes some defaults for [`LOC`](../domain/LOC.md) records.
*
* Accepts a string with degrees, minutes, and seconds (DMS) coordinates in the form: 41°24'12.2"N 2°10'26.5"E
*
* Note that the following are acceptable forms (symbols differ):
* * `33°5131″S 151°1251″E`
* * `33°51'31"S 151°12'51"E`
* * `33d51m31sS 151d12m51sE`
* * `33d51m31s S 151d12m51s E`
*
* ```javascript
* D("example.com","none"
* LOC_BUILDER_DMS_STR({
* label: "sydney-opera-house",
* str: '33°5131″S 151°1251″E',
* alt: 4,
* ttl: "5m",
* })
* );
*
* ```
*
* Part of the series:
* * [`LOC()`](LOC.md) - build a `LOC` by supplying all 12 parameters
* * [`LOC_BUILDER_DD({})`](../record/LOC_BUILDER_DD.md) - accepts cartesian x, y
* * [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131S 151°1251E
* * [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
* * [`LOC_BUILDER_STR({})`](LOC_BUILDER_STR.md) - tries LOC_BUILDER_DM*STR()
*
* @see https://dnscontrol.org/js#LOC_BUILDER_DMS_STR
*/
declare function LOC_BUILDER_DMS_STR(subdomain: string, input_string: string, altitude: float32, ttl: int): RecordModifier;
/**
* `LOC_BUILDER_STR({})` actually takes an object with the mentioned properties.
*
* A helper to build [`LOC`](../domain/LOC.md) records. Supply three parameters instead of 12.
*
* Internally assumes some defaults for [`LOC`](../domain/LOC.md) records.
*
* Accepts a string and tries all `LOC_BUILDER_DM*_STR({})` methods:
* * [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131S 151°1251E
* * [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
*
* ```javascript
* D("example.com","none"
* , LOC_BUILDER_STR({
* label: "old-faithful",
* str: '44.46046°N 110.82815°W',
* alt: 2240,
* })
* , LOC_BUILDER_STR({
* label: "ribblehead-viaduct",
* str: '54.210436°N 2.370231°W',
* alt: 300,
* })
* , LOC_BUILDER_STR({
* label: "guinness-brewery",
* str: '53°2040″N 6°1720″W',
* alt: 300,
* })
* );
*
* ```
*
* Part of the series:
* * [`LOC()`](LOC.md) - build a `LOC` by supplying all 12 parameters
* * [`LOC_BUILDER_DD({})`](../record/LOC_BUILDER_DD.md) - accepts cartesian x, y
* * [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131S 151°1251E
* * [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
* * [`LOC_BUILDER_STR({})`](LOC_BUILDER_STR.md) - tries LOC_BUILDER_DM*STR()
*
* @see https://dnscontrol.org/js#LOC_BUILDER_STR
*/
declare function LOC_BUILDER_STR(subdomain: string, input_string: string, altitude: float32, ttl: int): RecordModifier;
/**
* R53_ZONE lets you specify the AWS Zone ID for an entire domain (D()) or a specific R53_ALIAS() record.
*

View file

@ -0,0 +1,103 @@
---
name: LOC
parameters:
- deg1
- min1
- sec1
- deg2
- min2
- sec2
- altitude
- size
- horizontal_precision
- vertical_precision
parameter_types:
name: string
target: string
deg1: uint32
min1: uint32
sec1: float32
deg2: uint32
min2: uint32
sec2: float32
altitude: uint32
size: float32
horizontal_precision: float32
vertical_precision: float32
---
## Description ##
Strictly follows [RFC 1876](https://datatracker.ietf.org/doc/html/rfc1876).
A LOC record holds a geographical position. In the zone file, it may look like:
```text
;
pipex.net. LOC 52 14 05 N 00 08 50 E 10m
```
On the wire, it is in a binary format.
A use case for LOC is suggested in the RFC:
> Some uses for the LOC RR have already been suggested, including the
USENET backbone flow maps, a "visual traceroute" application showing
the geographical path of an IP packet, and network management
applications that could use LOC RRs to generate a map of hosts and
routers being managed.
There is the UK based [https://find.me.uk](https://find.me.uk/) whereby you can do:
```sh
dig loc <uk-postcode>.find.me.uk
```
There are some behaviours that you should be aware of, however:
> If omitted, minutes and seconds default to zero, size defaults to 1m,
horizontal precision defaults to 10000m, and vertical precision
defaults to 10m. These defaults are chosen to represent typical
ZIP/postal code area sizes, since it is often easy to find
approximate geographical location by ZIP/postal code.
Alas, the world does not revolve around US ZIP codes, but here we are. Internally,
the LOC record type will supply defaults where values were absent on DNS import.
One must supply the `LOC()` js helper all parameters. If that seems like too
much work, see also helper functions:
* [`LOC_BUILDER_DD()`](../record/LOC_BUILDER_DD.md) - build a `LOC` by supplying only **d**ecimal **d**egrees.
* [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131″S 151°1251″E
* [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
* [`LOC_BUILDER_STR({})`](LOC_BUILDER_STR.md) - tries LOC_BUILDER_DM*STR()
## Format ##
The coordinate format for `LOC()` is:
`degrees,minutes,seconds,[NnSs],deg,min,sec,[EeWw],altitude,size,horizontal_precision,vertical_precision`
## Examples ##
{% code title="dnsconfig.js" %}
```javascript
D("foo.com","none"
// LOC "subdomain", d1, m1, s1, "[NnSs]", d2, m2, s2, "[EeWw]", alt, siz, hp, vp)
//42 21 54 N 71 06 18 W -24m 30m
, LOC("@", 42, 21, 54, "N", 71, 6, 18, "W", -24, 30, 0, 0)
//42 21 43.952 N 71 5 6.344 W -24m 1m 200m 10m
, LOC("a", 42, 21, 43.952, "N", 71, 5, 6.344, "W", -24, 1, 200, 10)
//52 14 05 N 00 08 50 E 10m
, LOC("b", 52, 14, 5, "N", 0, 8, 50, "E", 10, 0, 0, 0)
//32 7 19 S 116 2 25 E 10m
, LOC("c", 32, 7, 19, "S",116, 2, 25, "E", 10, 0, 0, 0)
//42 21 28.764 N 71 00 51.617 W -44m 2000m
, LOC("d", 42, 21, 28.764, "N", 71, 0, 51.617, "W", -44, 2000, 0, 0)
);
```
{% endcode %}

View file

@ -0,0 +1,68 @@
---
name: LOC_BUILDER_DD
parameters:
- subdomain
- decimal_degrees_x
- decimal_degrees_y
- altitude
- ttl
parameter_types:
subdomain: string
decimal_degrees_x: float32
decimal_degrees_y: float32
altitude: float32
ttl: int
---
`LOC_BUILDER_DD({})` actually takes an object with the mentioned properties.
A helper to build [`LOC`](../domain/LOC.md) records. Supply four parameters instead of 12.
Internally assumes some defaults for [`LOC`](../domain/LOC.md) records.
The cartesian coordinates are decimal degrees, like you typically find in e.g. Google Maps.
Examples.
Big Ben:
`51.50084265331501, -0.12462541415599787`
The White House:
`38.89775977858357, -77.03655125982903`
{% code title="dnsconfig.js" %}
```javascript
D("example.com","none"
, LOC_BUILDER_DD({
label: "big-ben",
x: 51.50084265331501,
y: -0.12462541415599787,
alt: 6,
})
, LOC_BUILDER_DD({
label: "white-house",
x: 38.89775977858357,
y: -77.03655125982903,
alt: 19,
})
, LOC_BUILDER_DD({
label: "white-house-ttl",
x: 38.89775977858357,
y: -77.03655125982903,
alt: 19,
ttl: "5m",
})
);
```
{% endcode %}
Part of the series:
* [`LOC()`](LOC.md) - build a `LOC` by supplying all 12 parameters
* [`LOC_BUILDER_DD({})`](../record/LOC_BUILDER_DD.md) - accepts cartesian x, y
* [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131″S 151°1251″E
* [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
* [`LOC_BUILDER_STR({})`](LOC_BUILDER_STR.md) - tries LOC_BUILDER_DM*STR()

View file

@ -0,0 +1,49 @@
---
name: LOC_BUILDER_DMM
parameters:
- subdomain
- input_string
- altitude
- ttl
parameter_types:
subdomain: string
input_string: string
altitude: float32
ttl: int
---
`LOC_BUILDER_DMM({})` actually takes an object with the mentioned properties.
A helper to build [`LOC`](../domain/LOC.md) records. Supply three parameters instead of 12.
Internally assumes some defaults for [`LOC`](../domain/LOC.md) records.
Accepts a string with decimal minutes (DMM) coordinates in the form: 25.24°S 153.15°E
Note that the following are acceptable forms (symbols differ):
* `25.24°S 153.15°E`
* `25.24 S 153.15 E`
* `25.24° S 153.15° E`
* `25.24S 153.15E`
{% code title="dnsconfig.js" %}
```javascript
D("example.com","none"
LOC_BUILDER_STR({
label: "tasmania",
str: '42°S 147°E',
alt: 3,
})
);
```
{% endcode %}
Part of the series:
* [`LOC()`](LOC.md) - build a `LOC` by supplying all 12 parameters
* [`LOC_BUILDER_DD({})`](../record/LOC_BUILDER_DD.md) - accepts cartesian x, y
* [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131″S 151°1251″E
* [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
* [`LOC_BUILDER_STR({})`](LOC_BUILDER_STR.md) - tries LOC_BUILDER_DM*STR()

View file

@ -0,0 +1,50 @@
---
name: LOC_BUILDER_DMS_STR
parameters:
- subdomain
- input_string
- altitude
- ttl
parameter_types:
subdomain: string
input_string: string
altitude: float32
ttl: int
---
`LOC_BUILDER_DMS_STR({})` actually takes an object with the mentioned properties.
A helper to build [`LOC`](../domain/LOC.md) records. Supply three parameters instead of 12.
Internally assumes some defaults for [`LOC`](../domain/LOC.md) records.
Accepts a string with degrees, minutes, and seconds (DMS) coordinates in the form: 41°24'12.2"N 2°10'26.5"E
Note that the following are acceptable forms (symbols differ):
* `33°5131″S 151°1251″E`
* `33°51'31"S 151°12'51"E`
* `33d51m31sS 151d12m51sE`
* `33d51m31s S 151d12m51s E`
{% code title="dnsconfig.js" %}
```javascript
D("example.com","none"
LOC_BUILDER_DMS_STR({
label: "sydney-opera-house",
str: '33°5131″S 151°1251″E',
alt: 4,
ttl: "5m",
})
);
```
{% endcode %}
Part of the series:
* [`LOC()`](LOC.md) - build a `LOC` by supplying all 12 parameters
* [`LOC_BUILDER_DD({})`](../record/LOC_BUILDER_DD.md) - accepts cartesian x, y
* [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131″S 151°1251″E
* [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
* [`LOC_BUILDER_STR({})`](LOC_BUILDER_STR.md) - tries LOC_BUILDER_DM*STR()

View file

@ -0,0 +1,57 @@
---
name: LOC_BUILDER_STR
parameters:
- subdomain
- input_string
- altitude
- ttl
parameter_types:
subdomain: string
input_string: string
altitude: float32
ttl: int
---
`LOC_BUILDER_STR({})` actually takes an object with the mentioned properties.
A helper to build [`LOC`](../domain/LOC.md) records. Supply three parameters instead of 12.
Internally assumes some defaults for [`LOC`](../domain/LOC.md) records.
Accepts a string and tries all `LOC_BUILDER_DM*_STR({})` methods:
* [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131″S 151°1251″E
* [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
{% code title="dnsconfig.js" %}
```javascript
D("example.com","none"
, LOC_BUILDER_STR({
label: "old-faithful",
str: '44.46046°N 110.82815°W',
alt: 2240,
})
, LOC_BUILDER_STR({
label: "ribblehead-viaduct",
str: '54.210436°N 2.370231°W',
alt: 300,
})
, LOC_BUILDER_STR({
label: "guinness-brewery",
str: '53°2040″N 6°1720″W',
alt: 300,
})
);
```
{% endcode %}
Part of the series:
* [`LOC()`](LOC.md) - build a `LOC` by supplying all 12 parameters
* [`LOC_BUILDER_DD({})`](../record/LOC_BUILDER_DD.md) - accepts cartesian x, y
* [`LOC_BUILDER_DMS_STR({})`](LOC_BUILDER_DMS_STR.md) - accepts DMS 33°5131″S 151°1251″E
* [`LOC_BUILDER_DMM_STR({})`](LOC_BUILDER_DMM_STR.md) - accepts DMM 25.24°S 153.15°E
* [`LOC_BUILDER_STR({})`](LOC_BUILDER_STR.md) - tries LOC_BUILDER_DM*STR()

View file

@ -12,53 +12,53 @@ a provider that supports it, we'd love your contribution to ensure it works corr
If a feature is definitively not supported for whatever reason, we would also like a PR to clarify why it is not supported, and fill in this entire matrix.
<!-- provider-matrix-start -->
| Provider name | Official Support | DNS Provider | Registrar | ALIAS | AUTODNSSEC | CAA | PTR | NAPTR | SOA | SRV | SSHFP | TLSA | DS | dual host | create-domains | NO_PURGE | get-zones |
| ------------- | ---------------- | ------------ | --------- | ----- | ---------- | --- | --- | ----- | --- | --- | ----- | ---- | -- | --------- | -------------- | -------- | --------- |
| `AKAMAIEDGEDNS` | ❌ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ |
| `AUTODNS` | ❌ | ✅ | ❌ | ✅ | ❔ | ❌ | ❌ | ❔ | ❔ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
| `AXFRDDNS` | ❌ | ✅ | ❌ | ❔ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ❔ | ❌ | ❌ | ❌ | ❌ |
| `AZURE_DNS` | ✅ | ✅ | ❌ | ❌ | ❔ | ✅ | ✅ | ❌ | ❔ | ✅ | ❌ | ❌ | ❔ | ✅ | ✅ | ✅ | ✅ |
| `BIND` | ✅ | ✅ | ❌ | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| `CLOUDFLAREAPI` | ✅ | ✅ | ❌ | ✅ | ❔ | ✅ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ❔ | ❌ | ✅ | ✅ | ✅ |
| `CLOUDNS` | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ |
| `CSCGLOBAL` | ✅ | ✅ | ✅ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ✅ |
| `DESEC` | ❌ | ✅ | ❌ | ❔ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ |
| `DIGITALOCEAN` | ❌ | ✅ | ❌ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❔ | ✅ | ✅ | ✅ |
| `DNSIMPLE` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
| `DNSMADEEASY` | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ✅ | ❔ | ❔ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `DNSOVERHTTPS` | ❌ | ❌ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ❔ |
| `DOMAINNAMESHOP` | ❌ | ✅ | ❌ | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❔ | ❔ | ❔ | ❔ | ✅ | ❔ |
| `EASYNAME` | ❌ | ❌ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ❔ |
| `EXOSCALE` | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ✅ | ❔ | ❔ | ✅ | ❔ | ❌ | ❔ | ❌ | ❌ | ✅ | ❔ |
| `GANDI_V5` | ❌ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ❌ | ❔ | ❌ | ❌ | ✅ |
| `GCLOUD` | ✅ | ✅ | ❌ | ❔ | ❔ | ✅ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ |
| `GCORE` | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❔ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `HEDNS` | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `HETZNER` | ❌ | ✅ | ❌ | ❌ | ❔ | ✅ | ❌ | ❔ | ❔ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `HEXONET` | ❌ | ✅ | ✅ | ❌ | ❔ | ✅ | ✅ | ❔ | ❔ | ✅ | ❔ | ✅ | ❔ | ✅ | ✅ | ✅ | ❔ |
| `HOSTINGDE` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `INTERNETBS` | ❌ | ❌ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ❔ |
| `INWX` | ❌ | ✅ | ✅ | ❌ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ |
| `LINODE` | ❌ | ✅ | ❌ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❌ | ❌ | ✅ | ✅ |
| `LOOPIA` | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ |
| `LUADNS` | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ |
| `MSDNS` | ✅ | ✅ | ❌ | ❌ | ❔ | ❌ | ✅ | ✅ | ❔ | ✅ | ❔ | ❔ | ❔ | ❌ | ❌ | ✅ | ✅ |
| `NAMECHEAP` | ❌ | ✅ | ✅ | ✅ | ❔ | ✅ | ❌ | ❔ | ❔ | ❌ | ❔ | ❌ | ❔ | ❌ | ❌ | ❌ | ✅ |
| `NAMEDOTCOM` | ❌ | ✅ | ✅ | ✅ | ❔ | ❔ | ❌ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ✅ | ❌ | ✅ | ✅ |
| `NETCUP` | ❌ | ✅ | ❌ | ❔ | ❔ | ✅ | ❌ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❌ | ❌ | ✅ | ❌ |
| `NETLIFY` | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❔ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
| `NS1` | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `OPENSRS` | ❌ | ❌ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ❔ |
| `ORACLE` | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `OVH` | ❌ | ✅ | ✅ | ❌ | ❔ | ✅ | ❌ | ❔ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ❌ | ✅ | ✅ |
| `PACKETFRAME` | ❌ | ✅ | ❌ | ❔ | ❔ | ❔ | ✅ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❌ | ❌ | ✅ | ❔ |
| `PORKBUN` | ❌ | ✅ | ❌ | ✅ | ❌ | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ |
| `POWERDNS` | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `ROUTE53` | ✅ | ✅ | ✅ | ❌ | ❔ | ✅ | ✅ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ✅ | ✅ | ✅ | ✅ |
| `RWTH` | ❌ | ✅ | ❌ | ❌ | ❔ | ✅ | ✅ | ❌ | ❔ | ✅ | ✅ | ❌ | ❔ | ❌ | ❌ | ✅ | ✅ |
| `SOFTLAYER` | ❌ | ✅ | ❌ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ❔ |
| `TRANSIP` | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ❔ | ✅ | ✅ | ✅ | ❌ | ❔ | ❌ | ✅ | ✅ |
| `VULTR` | ❌ | ✅ | ❌ | ❌ | ❔ | ✅ | ❌ | ❔ | ❔ | ✅ | ✅ | ❌ | ❔ | ❔ | ✅ | ✅ | ✅ |
| Provider name | Official Support | DNS Provider | Registrar | ALIAS | AUTODNSSEC | CAA | LOC | PTR | NAPTR | SOA | SRV | SSHFP | TLSA | DS | dual host | create-domains | NO_PURGE | get-zones |
| ------------- | ---------------- | ------------ | --------- | ----- | ---------- | --- | --- | --- | ----- | --- | --- | ----- | ---- | -- | --------- | -------------- | -------- | --------- |
| `AKAMAIEDGEDNS` | ❌ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ |
| `AUTODNS` | ❌ | ✅ | ❌ | ✅ | ❔ | ❌ | ❔ | ❌ | ❔ | ❔ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
| `AXFRDDNS` | ❌ | ✅ | ❌ | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ❔ | ❌ | ❌ | ❌ | ❌ |
| `AZURE_DNS` | ✅ | ✅ | ❌ | ❌ | ❔ | ✅ | ❌ | ✅ | ❌ | ❔ | ✅ | ❌ | ❌ | ❔ | ✅ | ✅ | ✅ | ✅ |
| `BIND` | ✅ | ✅ | ❌ | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| `CLOUDFLAREAPI` | ✅ | ✅ | ❌ | ✅ | ❔ | ✅ | ❌ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ❔ | ❌ | ✅ | ✅ | ✅ |
| `CLOUDNS` | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ✅ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ |
| `CSCGLOBAL` | ✅ | ✅ | ✅ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ✅ |
| `DESEC` | ❌ | ✅ | ❌ | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ |
| `DIGITALOCEAN` | ❌ | ✅ | ❌ | ❔ | ❔ | ✅ | ❌ | ❔ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❔ | ✅ | ✅ | ✅ |
| `DNSIMPLE` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❔ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
| `DNSMADEEASY` | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ❌ | ✅ | ❔ | ❔ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `DNSOVERHTTPS` | ❌ | ❌ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ❔ |
| `DOMAINNAMESHOP` | ❌ | ✅ | ❌ | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❔ | ❔ | ❔ | ❔ | ✅ | ❔ |
| `EASYNAME` | ❌ | ❌ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ❔ |
| `EXOSCALE` | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ❌ | ✅ | ❔ | ❔ | ✅ | ❔ | ❌ | ❔ | ❌ | ❌ | ✅ | ❔ |
| `GANDI_V5` | ❌ | ✅ | ✅ | ✅ | ❔ | ✅ | ❌ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ❌ | ❔ | ❌ | ❌ | ✅ |
| `GCLOUD` | ✅ | ✅ | ❌ | ❔ | ❔ | ✅ | ❌ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ |
| `GCORE` | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❔ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `HEDNS` | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `HETZNER` | ❌ | ✅ | ❌ | ❌ | ❔ | ✅ | ❌ | ❌ | ❔ | ❔ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `HEXONET` | ❌ | ✅ | ✅ | ❌ | ❔ | ✅ | ❔ | ✅ | ❔ | ❔ | ✅ | ❔ | ✅ | ❔ | ✅ | ✅ | ✅ | ❔ |
| `HOSTINGDE` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `INTERNETBS` | ❌ | ❌ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ❔ |
| `INWX` | ❌ | ✅ | ✅ | ❌ | ❔ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ |
| `LINODE` | ❌ | ✅ | ❌ | ❔ | ❔ | ✅ | ❌ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❌ | ❌ | ✅ | ✅ |
| `LOOPIA` | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ |
| `LUADNS` | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ❌ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ |
| `MSDNS` | ✅ | ✅ | ❌ | ❌ | ❔ | ❌ | ❌ | ✅ | ✅ | ❔ | ✅ | ❔ | ❔ | ❔ | ❌ | ❌ | ✅ | ✅ |
| `NAMECHEAP` | ❌ | ✅ | ✅ | ✅ | ❔ | ✅ | ❌ | ❌ | ❔ | ❔ | ❌ | ❔ | ❌ | ❔ | ❌ | ❌ | ❌ | ✅ |
| `NAMEDOTCOM` | ❌ | ✅ | ✅ | ✅ | ❔ | ❔ | ❌ | ❌ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ✅ | ❌ | ✅ | ✅ |
| `NETCUP` | ❌ | ✅ | ❌ | ❔ | ❔ | ✅ | ❌ | ❌ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❌ | ❌ | ✅ | ❌ |
| `NETLIFY` | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❔ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
| `NS1` | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❔ | ✅ | ❔ | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `OPENSRS` | ❌ | ❌ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ❔ |
| `ORACLE` | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `OVH` | ❌ | ✅ | ✅ | ❌ | ❔ | ✅ | ✅ | ❌ | ❔ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ❌ | ✅ | ✅ |
| `PACKETFRAME` | ❌ | ✅ | ❌ | ❔ | ❔ | ❔ | ❔ | ✅ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❌ | ❌ | ✅ | ❔ |
| `PORKBUN` | ❌ | ✅ | ❌ | ✅ | ❌ | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ |
| `POWERDNS` | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `ROUTE53` | ✅ | ✅ | ✅ | ❌ | ❔ | ✅ | ❌ | ✅ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ✅ | ✅ | ✅ | ✅ |
| `RWTH` | ❌ | ✅ | ❌ | ❌ | ❔ | ✅ | ❌ | ✅ | ❌ | ❔ | ✅ | ✅ | ❌ | ❔ | ❌ | ❌ | ✅ | ✅ |
| `SOFTLAYER` | ❌ | ✅ | ❌ | ❔ | ❔ | ❔ | ❌ | ❔ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ | ❔ |
| `TRANSIP` | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❔ | ✅ | ❔ | ✅ | ✅ | ✅ | ❌ | ❔ | ❌ | ✅ | ✅ |
| `VULTR` | ❌ | ✅ | ❌ | ❌ | ❔ | ✅ | ❌ | ❌ | ❔ | ❔ | ✅ | ✅ | ❌ | ❔ | ❔ | ✅ | ✅ | ✅ |
<!-- provider-matrix-end -->
### Providers with "official support"

View file

@ -437,6 +437,13 @@ func cfWorkerRoute(pattern, target string) *models.RecordConfig {
return r
}
func loc(name string, d1 uint8, m1 uint8, s1 float32, ns string,
d2 uint8, m2 uint8, s2 float32, ew string, al int32, sz float32, hp float32, vp float32) *models.RecordConfig {
r := makeRec(name, "", "LOC")
r.SetLOCParams(d1, m1, s1, ns, d2, m2, s2, ew, al, sz, hp, vp)
return r
}
func ns(name, target string) *models.RecordConfig {
return makeRec(name, target, "NS")
}
@ -1438,6 +1445,25 @@ func makeTests(t *testing.T) []*TestGroup {
// CNAME at the apex. If we extend IGNORE_TARGET to support other
// types of records, we should add a test at the apex.
// LOCation records. // No.47
testgroup("LOC",
//42 21 54 N 71 06 18 W -24m 30m
tc("Single LOC record", loc("@", 42, 21, 54, "N", 71, 6, 18, "W", -24, 30, 0, 0)),
//42 21 54 N 71 06 18 W -24m 30m
tc("Update single LOC record", loc("@", 42, 21, 54, "N", 71, 6, 18, "W", -24, 30, 10, 0)),
tc("Multiple LOC records-create a-d modify apex", //create a-d, modify @
//42 21 54 N 71 06 18 W -24m 30m
loc("@", 42, 21, 54, "N", 71, 6, 18, "W", -24, 30, 0, 0),
//42 21 43.952 N 71 5 6.344 W -24m 1m 200m
loc("a", 42, 21, 43.952, "N", 71, 5, 6.344, "W", -24, 1, 200, 10),
//52 14 05 N 00 08 50 E 10m
loc("b", 52, 14, 5, "N", 0, 8, 50, "E", 10, 0, 0, 0),
//32 7 19 S 116 2 25 E 10m
loc("c", 32, 7, 19, "S", 116, 2, 25, "E", 10, 0, 0, 0),
//42 21 28.764 N 71 00 51.617 W -44m 2000m
loc("d", 42, 21, 28.764, "N", 71, 0, 51.617, "W", -44, 2000, 0, 0),
),
),
}
return tests

View file

@ -76,6 +76,8 @@ func RRtoRC(rr dns.RR, origin string) (RecordConfig, error) {
err = rc.SetTarget(v.Target)
case *dns.DS:
err = rc.SetTargetDS(v.KeyTag, v.Algorithm, v.DigestType, v.Digest)
case *dns.LOC:
err = rc.SetTargetLOC(v.Version, v.Latitude, v.Longitude, v.Altitude, v.Size, v.HorizPre, v.VertPre)
case *dns.MX:
err = rc.SetTargetMX(v.Preference, v.Mx)
case *dns.NS:

View file

@ -22,6 +22,7 @@ import (
// ANAME // Technically not an official rtype yet.
// CAA
// CNAME
// LOC
// MX
// NAPTR
// NS
@ -103,6 +104,13 @@ type RecordConfig struct {
DsAlgorithm uint8 `json:"dsalgorithm,omitempty"`
DsDigestType uint8 `json:"dsdigesttype,omitempty"`
DsDigest string `json:"dsdigest,omitempty"`
LocVersion uint8 `json:"locversion,omitempty"`
LocSize uint8 `json:"locsize,omitempty"`
LocHorizPre uint8 `json:"lochorizpre,omitempty"`
LocVertPre uint8 `json:"locvertpre,omitempty"`
LocLatitude uint32 `json:"loclatitude,omitempty"`
LocLongitude uint32 `json:"loclongitude,omitempty"`
LocAltitude uint32 `json:"localtitude,omitempty"`
NaptrOrder uint16 `json:"naptrorder,omitempty"`
NaptrPreference uint16 `json:"naptrpreference,omitempty"`
NaptrFlags string `json:"naptrflags,omitempty"`
@ -164,6 +172,13 @@ func (rc *RecordConfig) UnmarshalJSON(b []byte) error {
DsAlgorithm uint8 `json:"dsalgorithm,omitempty"`
DsDigestType uint8 `json:"dsdigesttype,omitempty"`
DsDigest string `json:"dsdigest,omitempty"`
LocVersion uint8 `json:"locversion,omitempty"`
LocSize uint8 `json:"locsize,omitempty"`
LocHorizPre uint8 `json:"lochorizpre,omitempty"`
LocVertPre uint8 `json:"locvertpre,omitempty"`
LocLatitude int `json:"loclatitude,omitempty"`
LocLongitude int `json:"loclongitude,omitempty"`
LocAltitude uint32 `json:"localtitude,omitempty"`
NaptrOrder uint16 `json:"naptrorder,omitempty"`
NaptrPreference uint16 `json:"naptrpreference,omitempty"`
NaptrFlags string `json:"naptrflags,omitempty"`
@ -376,6 +391,17 @@ func (rc *RecordConfig) ToRR() dns.RR {
rr.(*dns.DS).DigestType = rc.DsDigestType
rr.(*dns.DS).Digest = rc.DsDigest
rr.(*dns.DS).KeyTag = rc.DsKeyTag
case dns.TypeLOC:
//this is for records from .js files and read from API
// fmt.Printf("ToRR long: %d, lat:%d, sz: %d, hz:%d, vt:%d\n", rc.LocLongitude, rc.LocLatitude, rc.LocSize, rc.LocHorizPre, rc.LocVertPre)
// fmt.Printf("ToRR rc: %+v\n", *rc)
rr.(*dns.LOC).Version = rc.LocVersion
rr.(*dns.LOC).Longitude = rc.LocLongitude
rr.(*dns.LOC).Latitude = rc.LocLatitude
rr.(*dns.LOC).Altitude = rc.LocAltitude
rr.(*dns.LOC).Size = rc.LocSize
rr.(*dns.LOC).HorizPre = rc.LocHorizPre
rr.(*dns.LOC).VertPre = rc.LocVertPre
case dns.TypePTR:
rr.(*dns.PTR).Ptr = rc.GetTargetField()
case dns.TypeNAPTR:
@ -542,6 +568,8 @@ func downcase(recs []*RecordConfig) {
case "ANAME", "CNAME", "DS", "MX", "NS", "PTR", "NAPTR", "SRV", "TLSA", "AKAMAICDN":
// These record types have a target that is case insensitive, so we downcase it.
r.target = strings.ToLower(r.target)
case "LOC":
// Do nothing to affect case of letters.
case "A", "AAAA", "ALIAS", "CAA", "IMPORT_TRANSFORM", "TXT", "SSHFP", "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE":
// These record types have a target that is case sensitive, or is an IP address. We leave them alone.
// Do nothing.

187
models/t_loc.go Normal file
View file

@ -0,0 +1,187 @@
package models
import (
"fmt"
"strconv"
"strings"
"github.com/miekg/dns"
)
// SetTargetLOC sets the LOC fields from the rr.LOC type properties.
func (rc *RecordConfig) SetTargetLOC(ver uint8, lat uint32, lon uint32, alt uint32, siz uint8, hzp uint8, vtp uint8) error {
rc.LocVersion = ver
rc.LocLatitude = lat
rc.LocLongitude = lon
rc.LocAltitude = alt
rc.LocSize = siz
rc.LocHorizPre = hzp
rc.LocVertPre = vtp
if rc.Type == "" {
rc.Type = "LOC"
}
if rc.Type != "LOC" {
panic("assertion failed: SetTargetLOC called when .Type is not LOC")
}
return nil
}
// SetLOCParams is an intermediate function which passes the 12 input parameters
// for further processing to the LOC native 7 input binary format:
// LocVersion (0), LocLatitude, LocLongitude, LocAltitude, LocSize, LocVertPre, LocHorizPre
func (rc *RecordConfig) SetLOCParams(d1 uint8, m1 uint8, s1 float32, ns string,
d2 uint8, m2 uint8, s2 float32, ew string, al int32, sz float32, hp float32, vp float32) error {
err := rc.calculateLOCFields(d1, m1, s1, ns, d2, m2, s2, ew, al, sz, hp, vp)
return err
}
// SetTargetLOCString is like SetTargetLOC but accepts one big string and origin
// Normally this is used when we receive a record string from provider records
// because e.g. the provider API passed rc.PopulateFromString()
func (rc *RecordConfig) SetTargetLOCString(origin string, contents string) error {
// This is where text from provider records ingresses into the target field.
// Fill the other fields derived from the TEXT here. LOC is special, and
// needs more math.
// We have to re-invent the wheel because the miekg dns library gives no
// access to the objects properties, and internally the object is represented
// by the dns.LOC format 💩
// Build a string with which to init the rr.LOC object:
str := fmt.Sprintf("%s. LOC %s\n", origin, contents)
loc, err := dns.NewRR(str)
if err != nil {
return fmt.Errorf("can't parse LOC data: %w", err)
}
// We 'normalize' the record thru rr.LOC, to get defaults for absent properties.
loctext := loc.String()
loctext = strings.TrimSpace(strings.Split(loctext, "LOC")[1])
err = rc.extractLOCFieldsFromStringInput(loctext)
if err != nil {
return fmt.Errorf("can't extractLOCFieldsFromStringInput from LOC data: %w", err)
}
rc.target = loctext
if rc.Type == "" {
rc.Type = "LOC"
}
if rc.Type != "LOC" {
panic("assertion failed: SetTargetLOC called when .Type is not LOC")
}
return nil
}
// extractLOCFieldsFromStringInput is a helper to split an input string to
// the 12 variable inputs of integers and strings.
func (rc *RecordConfig) extractLOCFieldsFromStringInput(input string) error {
var d1, m1, d2, m2 uint8
var al int32
var s1, s2 float32
var ns, ew string
var sz, hp, vp float32
var err error
_, err = fmt.Sscanf(input+"~", "%d %d %f %s %d %d %f %s %dm %fm %fm %fm~",
&d1, &m1, &s1, &ns, &d2, &m2, &s2, &ew, &al, &sz, &hp, &vp)
if err != nil {
return fmt.Errorf("extractLOCFieldsFromStringInput: can't unpack LOC tex input data: %w", err)
}
// fmt.Printf("\ngot: %d %d %g %s %d %d %g %s %dm %0.2fm %0.2fm %0.2fm \n", d1, m1, s1, ns, d2, m2, s2, ew, al, sz, hp, vp)
rc.calculateLOCFields(d1, m1, s1, ns, d2, m2, s2, ew, al, sz, hp, vp)
return nil
}
// calculateLOCFields converts from 12 user inputs to the LOC 7 binary fields
func (rc *RecordConfig) calculateLOCFields(d1 uint8, m1 uint8, s1 float32, ns string,
d2 uint8, m2 uint8, s2 float32, ew string, al int32, sz float32, hp float32, vp float32) error {
// Crazy hairy shit happens here.
// We already got the useful "string" version earlier. ¯\_(ツ)_/¯ code golf...
const LOCEquator uint64 = 0x80000000 // 1 << 31 // RFC 1876, Section 2.
const LOCPrimeMeridian uint64 = 0x80000000 // 1 << 31 // RFC 1876, Section 2.
const LOCHours uint32 = 60 * 1000
const LOCDegrees = 60 * LOCHours
const LOCAltitudeBase int32 = 100000
lat := uint64((uint32(d1) * LOCDegrees) + (uint32(m1) * LOCHours) + uint32(s1*1000))
lon := uint64((uint32(d2) * LOCDegrees) + (uint32(m2) * LOCHours) + uint32(s2*1000))
if strings.ToUpper(ns) == "N" {
rc.LocLatitude = uint32(LOCEquator + lat)
} else { // "S"
rc.LocLatitude = uint32(LOCEquator - lat)
}
if strings.ToUpper(ew) == "E" {
rc.LocLongitude = uint32(LOCPrimeMeridian + lon)
} else { // "W"
rc.LocLongitude = uint32(LOCPrimeMeridian - lon)
}
// Altitude
rc.LocAltitude = uint32(al+LOCAltitudeBase) * 100
var err error
// Size
rc.LocSize, err = getENotationInt(sz)
if err != nil {
return err
}
// Horizontal Precision
rc.LocHorizPre, err = getENotationInt(hp)
if err != nil {
return err
}
// Vertical Precision
rc.LocVertPre, err = getENotationInt(vp)
if err != nil {
return err
}
// if hp != 0 {
// } else {
// rc.LocHorizPre = 22 // 1e6 10,000m default
// }
// if vp != 0 {
// } else {
// rc.LocVertPre = 19 // 1e3 10m default
// }
return nil
}
// getENotationInt produces a mantissa_exponent 4bits:4bits into a uint8
func getENotationInt(x float32) (uint8, error) {
/*
9000000000cm = 9e9 == 153 (9^4 + 9) or 9<<4 + 9
800000000cm = 8e8 == 136 (8^4 + 8) or 8<<4 + 8
70000000cm = 7e7 == 119 (7^4 + 7) or 7<<4 + 7
6000000cm = 6e6 == 102 (6^4 + 6) or 6<<4 + 6
1000000cm = 1e6 == 22 (1^4 + 6) or 1<<4 + 6
500000cm = 5e5 == 85 (5^4 + 5) or 5<<4 + 5
40000cm = 4e4 == 68 (4^4 + 4) or 4<<4 + 4
3000cm = 3e3 == 51 (3^4 + 3) or 3<<4 + 3
1000cm = 1e3 == 19 (1^4 + 3) or 1<<4 + 1
200cm = 2e2 == 34 (2^4 + 2) or 2<<4 + 2
100cm = 1e2 == 18 (1^4 + 2) or 1<<4 + 2
10cm = 1e1 == 17 (1^4 + 1) or 1<<4 + 1
1cm = 1e0 == 16 (1^4 + 0) or 0<<4 + 0
0cm = 0e0 == 0
*/
// get int from cm value:
num := strconv.Itoa(int(x * 100))
// fmt.Printf("num: %s\n", num)
// split string on zeroes to count zeroes:
arr := strings.Split(num, "0")
// fmt.Printf("arr: %s\n", arr)
// get the leading digit:
prefix, err := strconv.Atoi(arr[0])
if err != nil {
return 0, fmt.Errorf("can't unpack LOC base/mantissa: %w", err)
}
// fmt.Printf("prefix: %d\n", prefix)
// fmt.Printf("lenArr-1: %d\n", len(arr)-1)
// construct our x^e uint8
value := uint8((prefix << 4) | (len(arr) - 1))
// fmt.Printf("m_e: %d\n", value)
return value, err
}

View file

@ -55,6 +55,8 @@ func (rc *RecordConfig) PopulateFromString(rtype, contents, origin string) error
return rc.SetTargetCAAString(contents)
case "DS":
return rc.SetTargetDSString(contents)
case "LOC":
return rc.SetTargetLOCString(origin, contents)
case "MX":
return rc.SetTargetMXString(contents)
case "NAPTR":

View file

@ -532,6 +532,216 @@ var TXT = recordBuilder('TXT', {
},
});
// Parses coordinates of the form 41°24'12.2"N 2°10'26.5"E
function parseDMSCoordinatesString(inputString) {
var lat = inputString.match(/(-?\d+).(\d+).([\d\.]+).?\ ?([NS])/);
var lon = inputString.match(/(-?\d+).(\d+).([\d\.]+).?\ ?([EW])/);
if (!lat || !lon) {
return null;
}
return {
lati: {
dg: parseInt(lat[1]),
mn: parseInt(lat[2]),
sc: parseFloat(lat[3]),
hemi: lat[4],
},
long: {
dg: parseInt(lon[1]),
mn: parseInt(lon[2]),
sc: parseFloat(lon[3]),
hemi: lon[4],
},
};
}
// // Parses coordinates of the form 25.24°S 153.15°E
function parseDMMCoordinatesString(inputString) {
var lat = inputString.match(/(-?\d+(\.\d+)?)°?\s*([NS])/i);
var lon = inputString.match(/(-?\d+(\.\d+)?)°?\s*([EW])/i);
if (!lat || !lon) {
return null;
}
var latDeg = Math.floor(parseFloat(lat[1]));
var latMin = Math.floor((parseFloat(lat[1]) - latDeg) * 60);
var latSec = Math.round(((parseFloat(lat[1]) - latDeg) * 60 - latMin) * 60);
var lonDeg = Math.floor(parseFloat(lon[1]));
var lonMin = Math.floor((parseFloat(lon[1]) - lonDeg) * 60);
var lonSec = Math.round(((parseFloat(lon[1]) - lonDeg) * 60 - lonMin) * 60);
var lati = {
dg: latDeg,
mn: latMin,
sc: latSec,
hemi: lat[3],
};
var long = {
dg: lonDeg,
mn: lonMin,
sc: lonSec,
hemi: lon[3],
};
return {
lati: lati,
long: long,
};
}
// builds a uint8 with 4 bit mantissa, 4 bit exponent from a float.
function getENotationInt(x) {
/*
9000000000cm = 9e9 == 153 (9^4 + 9) or 9<<4 + 9
800000000cm = 8e8 == 136 (8^4 + 8) or 8<<4 + 8
70000000cm = 7e7 == 119 (7^4 + 7) or 7<<4 + 7
6000000cm = 6e6 == 102 (6^4 + 6) or 6<<4 + 6
1000000cm = 1e6 == 22 (1^4 + 6) or 1<<4 + 6
500000cm = 5e5 == 85 (5^4 + 5) or 5<<4 + 5
40000cm = 4e4 == 68 (4^4 + 4) or 4<<4 + 4
3000cm = 3e3 == 51 (3^4 + 3) or 3<<4 + 3
1000cm = 1e3 == 19 (1^4 + 3) or 1<<4 + 1
200cm = 2e2 == 34 (2^4 + 2) or 2<<4 + 2
10cm = 1e1 == 17 (1^4 + 1) or 1<<4 + 1
1cm = 1e0 == 16 (1^4 + 0) or 0<<4 + 0
0cm = 0e0 == 0
*/
size = x * 100; // get cm value
// get the m^e version of size
array = size.toExponential(0).split('e+').map(Number);
// convert it to 4bit:4bit uint8
m_e = (array[0] << 4) | array[1];
return m_e;
}
// Checks LOC parameters and if all is well, renders them into a 'target' string.
// The LOC record has no target string parameter. It only renders one via String().
function locStringBuilder(record, args) {
record.name = args.name;
// technically, we don't need this part to build the text target, but
// it is a good sanity check to compare with later on down the chain
// when you're in the weeds with maths.
// Tests depend on it being present. Changes here must reflect in tests.
nsstring = '';
ewstring = '';
precisionbuffer = '';
ns = args.ns.toUpperCase();
ew = args.ew.toUpperCase();
// Handle N/S coords - can use also s1.toFixed(3)
nsstring =
args.d1.toString() +
' ' +
args.m1.toString() +
' ' +
args.s1.toString() +
' ';
var nsmatches = args.ns.match(/^([NnSs])$/);
if (nsmatches == null) {
throw v + ' is not a valid latitude modifier';
} else {
nsstring += ns + ' ';
}
// Handle E/W coords - can use also s2.toFixed(3)
ewstring =
args.d2.toString() +
' ' +
args.m2.toString() +
' ' +
args.s2.toString() +
' ';
var nsmatches = args.ew.match(/^([EeWw])$/);
if (nsmatches == null) {
throw v + ' is not a valid longitude modifier';
} else {
ewstring += ew + ' ';
}
// handle altitude, size, horizontal precision, vertical precision
precisionbuffer = args.alt.toString() + 'm';
precisionbuffer += ' ' + args.siz.toString() + 'm';
precisionbuffer += ' ' + args.hp.toString() + 'm';
precisionbuffer += ' ' + args.vp.toString() + 'm';
record.target = nsstring + ewstring + precisionbuffer;
return record;
}
// Renders LOC type internal properties from D˚M'S" parameters.
// Change anything here at your peril.
function locDMSBuilder(record, args) {
LOCEquator = 1 << 31; // RFC 1876, Section 2.
LOCPrimeMeridian = 1 << 31; // RFC 1876, Section 2.
LOCHours = 60 * 1000;
LOCDegrees = 60 * LOCHours;
LOCAltitudeBase = 100000;
lat = args.d1 * LOCDegrees + args.m1 * LOCHours + args.s1 * 1000;
lon = args.d2 * LOCDegrees + args.m2 * LOCHours + args.s2 * 1000;
if (ns == 'N') record.loclatitude = LOCEquator + lat;
// S
else record.loclatitude = LOCEquator - lat;
if (ew == 'E') record.loclongitude = LOCPrimeMeridian + lon;
// W
else record.loclongitude = LOCPrimeMeridian - lon;
// Altitude
record.localtitude = (args.alt + LOCAltitudeBase) * 100;
// Size
record.locsize = getENotationInt(args.siz);
// Horizontal Precision
m_e = args.hp;
record.lochorizpre = getENotationInt(args.hp);
// if (m_e != 0) {
// } else {
// record.lochorizpre = 22; // 10,000m default
// }
// Vertical Precision
m_e = args.vp;
record.locvertpre = getENotationInt(args.vp);
// if (m_e != 0) {
// } else {
// record.lochorizpre = 19; // 10m default
// }
}
// LOC(name,d1,m1,s1,ns,d2,m2,s2,ew,alt,siz,hp,vp, recordModifiers...)
var LOC = recordBuilder('LOC', {
args: [
['name', _.isString], //i.e. subdomain
['d1', _.isNumber], // N/S degrees
['m1', _.isNumber], // N/S minutes
['s1', _.isNumber], // N/S seconds
['ns', _.isString], // N/S
['d2', _.isNumber], // E/W degrees
['m2', _.isNumber], // E/W minutes
['s2', _.isNumber], // E/W seconds
['ew', _.isString], // E/W
['alt', _.isNumber], // altitude
['siz', _.isNumber], // size/precision
['hp', _.isNumber], // horizontal precision
['vp', _.isNumber], // vertical precision
],
transform: function (record, args, modifiers) {
record = locStringBuilder(record, args);
record = locDMSBuilder(record, args);
},
});
function ConvertDDToDMS(D, longitude) {
//stackoverflow, baby. do not re-order the rows.
return {
hemi: D < 0 ? (longitude ? 'W' : 'S') : longitude ? 'E' : 'N',
dg: 0 | (D < 0 ? (D = -D) : D),
mn: 0 | (((D += 1e-9) % 1) * 60),
sc: (0 | (((D * 60) % 1) * 60000)) / 1000,
};
}
// MX(name,priority,target, recordModifiers...)
var MX = recordBuilder('MX', {
args: [
@ -987,6 +1197,182 @@ var FRAME = recordBuilder('FRAME');
var NS1_URLFWD = recordBuilder('NS1_URLFWD');
var CLOUDNS_WR = recordBuilder('CLOUDNS_WR');
// LOC_BUILDER_DD takes an object:
// label: The DNS label for the LOC record. (default: '@')
// x: Decimal X coordinate.
// y: Decimal Y coordinate.
// alt: Altitude in m. You imperial measurement system people are suckers for punishment.
// ttl: The time for TTL, integer or string. (default: not defined, using DefaultTTL)
function LOC_BUILDER_DD(value) {
if (!value.x && !value.y) {
throw 'LOC_BUILDER_DD requires x and y elements';
}
if (!value.label) {
value.label = '@';
}
var lati = ConvertDDToDMS(value.x, false);
var long = ConvertDDToDMS(value.y, true);
dms = { lati: lati, long: long };
return LOC_builder_push(value, dms);
}
// LOC_BUILDER_DMM_STR takes an object:
// label: The DNS label for the LOC record. (default: '@')
// str: Input string of Degrees and decimal minutes (DMM) coordinates in the form: 25.24°S 153.15°E
// alt: Altitude in m. You imperial measurement system people are suckers for punishment.
// ttl: The time for TTL, integer or string. (default: not defined, using DefaultTTL)
function LOC_BUILDER_DMM_STR(value) {
if (!value.str) {
throw 'LOC_BUILDER_DMM_STR requires a string of the form 25.24°S 153.15°E';
}
if (!value.label) {
value.label = '@';
}
var dms = parseDMMCoordinatesString(value.str);
return LOC_builder_push(value, dms);
}
// LOC_BUILDER_DMS_STR takes an object:
// label: The DNS label for the LOC record. (default: '@')
// str: Input string of degrees, minutes, and seconds (DMS) coordinates in the form: 41°24'12.2"N 2°10'26.5"E
// alt: Altitude in m. You imperial measurement system people are suckers for punishment.
// ttl: The time for TTL, integer or string. (default: not defined, using DefaultTTL)
function LOC_BUILDER_DMS_STR(value) {
if (!value.str) {
throw 'LOC_BUILDER_DMS_STR requires a string of the form 33°5131″S 151°1251″Es (or 33°51\'31"S 151°12\'51"Es)';
}
if (!value.label) {
value.label = '@';
}
var dms = parseDMSCoordinatesString(value.str);
return LOC_builder_push(value, dms);
}
// LOC_BUILDER_STR takes an object:
// label: The DNS label for the LOC record. (default: '@')
// str: Input string of degrees, minutes, and seconds (DMS) coordinates in the form: 41°24'12.2"N 2°10'26.5"E
// alt: Altitude in m. You imperial measurement system people are suckers for punishment.
// ttl: The time for TTL, integer or string. (default: not defined, using DefaultTTL)
function LOC_BUILDER_STR(value) {
if (!value.str) {
throw 'LOC_BUILDER_STR requires a string';
}
if (!value.label) {
value.label = '@';
}
var dms = parseDMMCoordinatesString(value.str);
if (!dms) dms = parseDMSCoordinatesString(value.str);
return LOC_builder_push(value, dms);
}
function LOC_builder_push(value, dms) {
r = []; // The list of records to return.
p = {}; // The metaparameters to set on the LOC record.
// rawloc = "";
// Generate a LOC record with the metaparameters.
if (value.ttl) {
if (value.alt)
r.push(
LOC(
value.label,
dms.lati.dg,
dms.lati.mn,
dms.lati.sc,
dms.lati.hemi,
dms.long.dg,
dms.long.mn,
dms.long.sc,
dms.long.hemi,
value.alt,
0,
0,
0,
p,
TTL(value.ttl)
)
);
else
r.push(
LOC(
value.label,
dms.lati.dg,
dms.lati.mn,
dms.lati.sc,
dms.lati.hemi,
dms.long.dg,
dms.long.mn,
dms.long.sc,
dms.long.hemi,
0,
0,
0,
0,
p,
TTL(value.ttl)
)
);
} else {
if (value.alt)
r.push(
LOC(
value.label,
dms.lati.dg,
dms.lati.mn,
dms.lati.sc,
dms.lati.hemi,
dms.long.dg,
dms.long.mn,
dms.long.sc,
dms.long.hemi,
value.alt,
0,
0,
0,
p
)
);
else
r.push(
LOC(
value.label,
dms.lati.dg,
dms.lati.mn,
dms.lati.sc,
dms.lati.hemi,
dms.long.dg,
dms.long.mn,
dms.long.sc,
dms.long.hemi,
0,
0,
0,
0,
p
)
);
}
return r;
}
// SPF_BUILDER takes an object:
// parts: The parts of the SPF record (to be joined with ' ').
// label: The DNS label for the primary SPF record. (default: '@')

View file

@ -0,0 +1,79 @@
D("foo.com","none"
// LOC "subdomain", d1, m1, s1, "[NnSs]", d2, m2, s2, "[EeWw]", alt, siz, hp, vp)
, LOC("@", 42, 21, 54, "N", 71, 6, 18, "W", -24, 30, 0, 0) //42 21 54 N 71 06 18 W -24m 30m
, LOC("a", 42, 21, 43.952, "N", 71, 5, 6.344, "W", -24, 1, 200, 10) //42 21 43.952 N 71 5 6.344 W -24m 1m 200m
, LOC("b", 52, 14, 5, "N", 0, 8, 50, "E", 10, 0, 0, 0) //52 14 05 N 00 08 50 E 10m
, LOC("c", 32, 7, 19, "S",116, 2, 25, "E", 10, 0, 0, 0) //32 7 19 S 116 2 25 E 10m
, LOC("d", 42, 21, 28.764, "N", 71, 0, 51.617, "W", -44, 2000, 0, 0) //42 21 28.764 N 71 00 51.617 W -44m 2000m
// via the Decimal degrees to LOC builder.
, LOC_BUILDER_DD({
label: "big-ben",
x: 51.50084265331501,
y: -0.12462541415599787,
alt: 6,
})
, LOC_BUILDER_DD({
label: "white-house",
x: 38.89775977858357,
y: -77.03655125982903,
alt: 19,
ttl: "5m",
})
, LOC_BUILDER_DMS_STR({
label: "opera-house",
str: '33°5131″S 151°1251″E',
alt: 4,
ttl: "5m",
})
, LOC_BUILDER_DMS_STR({
label: "opera-house2",
str: '33°51\'31"S 151°12\'51"E',
alt: 4,
ttl: "5m",
})
, LOC_BUILDER_DMS_STR({
label: "opera-house3",
str: '33d51m31sS 151d12m51sE',
alt: 4,
ttl: "5m",
})
, LOC_BUILDER_DMS_STR({
label: "opera-house4",
str: '33d51m31s S 151d12m51s E',
alt: 4,
ttl: "5m",
})
, LOC_BUILDER_DMM_STR({
label: "fraser-island",
str: '25.24°S 153.15°E',
alt: 3,
})
, LOC_BUILDER_STR({
label: "tasmania",
str: '42°S 147°E',
alt: 3,
})
, LOC_BUILDER_STR({
label: "hawaii",
str: '21.5°N 158.0°W',
alt: 920,
})
, LOC_BUILDER_STR({
label: "old-faithful",
str: '44.46046°N 110.82815°W',
alt: 2240,
})
, LOC_BUILDER_STR({
label: "ribblehead-viaduct",
str: '54.210436°N 2.370231°W',
alt: 300,
})
, LOC_BUILDER_STR({
label: "guinness-brewery",
str: '53°2040″N 6°1720″W',
alt: 300,
})
);

View file

@ -0,0 +1,160 @@
{
"registrars": [],
"dns_providers": [],
"domains": [
{
"name": "foo.com",
"registrar": "none",
"dnsProviders": {},
"records": [
{
"type": "LOC",
"name": "@",
"locsize": 51,
"loclatitude": 2299997648,
"loclongitude": 1891505648,
"localtitude": 9997600,
"target": "42 21 54 N 71 6 18 W -24m 30m 0m 0m"
},
{
"type": "LOC",
"name": "a",
"locsize": 18,
"lochorizpre": 36,
"locvertpre": 19,
"loclatitude": 2299987600,
"loclongitude": 1891577304,
"localtitude": 9997600,
"target": "42 21 43.952 N 71 5 6.344 W -24m 1m 200m 10m"
},
{
"type": "LOC",
"name": "b",
"loclatitude": 2335528648,
"loclongitude": 2148013648,
"localtitude": 10001000,
"target": "52 14 5 N 0 8 50 E 10m 0m 0m 0m"
},
{
"type": "LOC",
"name": "c",
"loclatitude": 2031844648,
"loclongitude": 2565228648,
"localtitude": 10001000,
"target": "32 7 19 S 116 2 25 E 10m 0m 0m 0m"
},
{
"type": "LOC",
"name": "d",
"locsize": 37,
"loclatitude": 2299972412,
"loclongitude": 1891832031,
"localtitude": 9995600,
"target": "42 21 28.764 N 71 0 51.617 W -44m 2000m 0m 0m"
},
{
"type": "LOC",
"name": "big-ben",
"loclatitude": 2332886681,
"loclongitude": 2147034997,
"localtitude": 10000600,
"target": "51 30 3.033 N 0 7 28.651 W 6m 0m 0m 0m"
},
{
"type": "LOC",
"name": "white-house",
"ttl": 300,
"loclatitude": 2287515583,
"loclongitude": 1870152064,
"localtitude": 10001900,
"target": "38 53 51.935 N 77 2 11.584 W 19m 0m 0m 0m"
},
{
"type": "LOC",
"name": "opera-house",
"ttl": 300,
"loclatitude": 2025592648,
"loclongitude": 2691854648,
"localtitude": 10000400,
"target": "33 51 31 S 151 12 51 E 4m 0m 0m 0m"
},
{
"type": "LOC",
"name": "opera-house2",
"ttl": 300,
"loclatitude": 2025592648,
"loclongitude": 2691854648,
"localtitude": 10000400,
"target": "33 51 31 S 151 12 51 E 4m 0m 0m 0m"
},
{
"type": "LOC",
"name": "opera-house3",
"ttl": 300,
"loclatitude": 2025592648,
"loclongitude": 2691854648,
"localtitude": 10000400,
"target": "33 51 31 S 151 12 51 E 4m 0m 0m 0m"
},
{
"type": "LOC",
"name": "opera-house4",
"ttl": 300,
"loclatitude": 2025592648,
"loclongitude": 2691854648,
"localtitude": 10000400,
"target": "33 51 31 S 151 12 51 E 4m 0m 0m 0m"
},
{
"type": "LOC",
"name": "fraser-island",
"loclatitude": 2056619648,
"loclongitude": 2698823648,
"localtitude": 10000300,
"target": "25 14 24 S 153 9 0 E 3m 0m 0m 0m"
},
{
"type": "LOC",
"name": "tasmania",
"loclatitude": 1996283648,
"loclongitude": 2676683648,
"localtitude": 10000300,
"target": "42 0 0 S 147 0 0 E 3m 0m 0m 0m"
},
{
"type": "LOC",
"name": "hawaii",
"loclatitude": 2224883648,
"loclongitude": 1578683648,
"localtitude": 10092000,
"target": "21 30 0 N 158 0 0 W 920m 0m 0m 0m"
},
{
"type": "LOC",
"name": "old-faithful",
"loclatitude": 2307541648,
"loclongitude": 1748502648,
"localtitude": 10224000,
"target": "44 27 38 N 110 49 41 W 2240m 0m 0m 0m"
},
{
"type": "LOC",
"name": "ribblehead-viaduct",
"loclatitude": 2342641648,
"loclongitude": 2138950648,
"localtitude": 10030000,
"target": "54 12 38 N 2 22 13 W 300m 0m 0m 0m"
},
{
"type": "LOC",
"name": "guinness-brewery",
"loclatitude": 2339523648,
"loclongitude": 2124843648,
"localtitude": 10030000,
"target": "53 20 40 N 6 17 20 W 300m 0m 0m 0m"
}
]
}
]
}

View file

@ -0,0 +1,18 @@
$TTL 300
@ IN LOC 42 21 54.000 N 71 06 18.000 W -24m 30m 0.00m 0.00m
a IN LOC 42 21 43.952 N 71 05 6.344 W -24m 1m 200m 10m
b IN LOC 52 14 5.000 N 00 08 50.000 E 10m 0.00m 0.00m 0.00m
big-ben IN LOC 51 30 3.033 N 00 07 28.651 W 6m 0.00m 0.00m 0.00m
c IN LOC 32 07 19.000 S 116 02 25.000 E 10m 0.00m 0.00m 0.00m
d IN LOC 42 21 28.764 N 71 00 51.617 W -44m 2000m 0.00m 0.00m
fraser-island IN LOC 25 14 24.000 S 153 09 0.000 E 3m 0.00m 0.00m 0.00m
guinness-brewery IN LOC 53 20 40.000 N 06 17 20.000 W 300m 0.00m 0.00m 0.00m
hawaii IN LOC 21 30 0.000 N 158 00 0.000 W 920m 0.00m 0.00m 0.00m
old-faithful IN LOC 44 27 38.000 N 110 49 41.000 W 2240m 0.00m 0.00m 0.00m
opera-house IN LOC 33 51 31.000 S 151 12 51.000 E 4m 0.00m 0.00m 0.00m
opera-house2 IN LOC 33 51 31.000 S 151 12 51.000 E 4m 0.00m 0.00m 0.00m
opera-house3 IN LOC 33 51 31.000 S 151 12 51.000 E 4m 0.00m 0.00m 0.00m
opera-house4 IN LOC 33 51 31.000 S 151 12 51.000 E 4m 0.00m 0.00m 0.00m
ribblehead-viaduct IN LOC 54 12 38.000 N 02 22 13.000 W 300m 0.00m 0.00m 0.00m
tasmania IN LOC 42 00 0.000 S 147 00 0.000 E 3m 0.00m 0.00m 0.00m
white-house IN LOC 38 53 51.935 N 77 02 11.584 W 19m 0.00m 0.00m 0.00m

View file

@ -61,6 +61,7 @@ func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []strin
"CNAME": true,
"DS": true,
"IMPORT_TRANSFORM": false,
"LOC": true,
"MX": true,
"NAPTR": true,
"NS": true,
@ -192,6 +193,7 @@ func checkTargets(rec *models.RecordConfig, domain string) (errs []error) {
if labelFQDN == targetFQDN {
check(fmt.Errorf("CNAME loop (target points at itself)"))
}
case "LOC":
case "MX":
check(checkTarget(target))
case "NAPTR":
@ -277,6 +279,8 @@ func importTransform(srcDomain, dstDomain *models.DomainConfig, transforms []tra
case "AKAMAICDN", "MX", "NAPTR", "NS", "SOA", "SRV", "TXT", "CAA", "TLSA":
// Not imported.
continue
case "LOC":
continue
default:
return fmt.Errorf("import_transform: Unimplemented record type %v (%v)",
rec.Type, rec.GetLabel())
@ -721,6 +725,7 @@ var providerCapabilityChecks = []pairTypeCapability{
capabilityCheck("AUTODNSSEC", providers.CanAutoDNSSEC),
capabilityCheck("AZURE_ALIAS", providers.CanUseAzureAlias),
capabilityCheck("CAA", providers.CanUseCAA),
capabilityCheck("LOC", providers.CanUseLOC),
capabilityCheck("NAPTR", providers.CanUseNAPTR),
capabilityCheck("PTR", providers.CanUsePTR),
capabilityCheck("R53_ALIAS", providers.CanUseRoute53Alias),

View file

@ -32,6 +32,7 @@ var features = providers.DocumentationNotes{
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(),
providers.CanUseDSForChildren: providers.Can(),
providers.CanUseLOC: providers.Can(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSOA: providers.Cannot(),

View file

@ -42,6 +42,7 @@ var features = providers.DocumentationNotes{
providers.CanAutoDNSSEC: providers.Can("Just warn when DNSSEC is requested but no RRSIG is found in the AXFR or warn when DNSSEC is not requested but RRSIG are found in the AXFR."),
providers.CanGetZones: providers.Cannot(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Can(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),

View file

@ -60,6 +60,7 @@ var features = providers.DocumentationNotes{
providers.CanUseAlias: providers.Cannot("Azure DNS does not provide a generic ALIAS functionality. Use AZURE_ALIAS instead."),
providers.CanUseAzureAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Cannot(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),

View file

@ -37,6 +37,7 @@ var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Can(),
providers.CanUseLOC: providers.Can(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSOA: providers.Can(),

View file

@ -40,6 +40,9 @@ const (
// only for children records, not at the root of the zone.
CanUseDSForChildren
// CanUseLOC indicates whether service provider handles LOC records
CanUseLOC
// CanUseNAPTR indicates the provider can handle NAPTR records
CanUseNAPTR

View file

@ -16,22 +16,23 @@ func _() {
_ = x[CanUseCAA-5]
_ = x[CanUseDS-6]
_ = x[CanUseDSForChildren-7]
_ = x[CanUseNAPTR-8]
_ = x[CanUsePTR-9]
_ = x[CanUseRoute53Alias-10]
_ = x[CanUseSOA-11]
_ = x[CanUseSRV-12]
_ = x[CanUseSSHFP-13]
_ = x[CanUseTLSA-14]
_ = x[CantUseNOPURGE-15]
_ = x[DocCreateDomains-16]
_ = x[DocDualHost-17]
_ = x[DocOfficiallySupported-18]
_ = x[CanUseLOC-8]
_ = x[CanUseNAPTR-9]
_ = x[CanUsePTR-10]
_ = x[CanUseRoute53Alias-11]
_ = x[CanUseSOA-12]
_ = x[CanUseSRV-13]
_ = x[CanUseSSHFP-14]
_ = x[CanUseTLSA-15]
_ = x[CantUseNOPURGE-16]
_ = x[DocCreateDomains-17]
_ = x[DocDualHost-18]
_ = x[DocOfficiallySupported-19]
}
const _Capability_name = "CanAutoDNSSECCanGetZonesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDSCanUseDSForChildrenCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSOACanUseSRVCanUseSSHFPCanUseTLSACantUseNOPURGEDocCreateDomainsDocDualHostDocOfficiallySupported"
const _Capability_name = "CanAutoDNSSECCanGetZonesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDSCanUseDSForChildrenCanUseLOCCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSOACanUseSRVCanUseSSHFPCanUseTLSACantUseNOPURGEDocCreateDomainsDocDualHostDocOfficiallySupported"
var _Capability_index = [...]uint8{0, 13, 24, 39, 50, 66, 75, 83, 102, 113, 122, 140, 149, 158, 169, 179, 193, 209, 220, 242}
var _Capability_index = [...]uint8{0, 13, 24, 39, 50, 66, 75, 83, 102, 111, 122, 131, 149, 158, 167, 178, 188, 202, 218, 229, 251}
func (i Capability) String() string {
if i >= Capability(len(_Capability_index)-1) {

View file

@ -42,6 +42,7 @@ var features = providers.DocumentationNotes{
providers.CanUseAlias: providers.Can("CF automatically flattens CNAME records into A records dynamically"),
providers.CanUseCAA: providers.Can(),
providers.CanUseDSForChildren: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Can(),

View file

@ -44,6 +44,7 @@ var features = providers.DocumentationNotes{
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDSForChildren: providers.Can(),
providers.CanUseLOC: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Can(),

View file

@ -45,6 +45,7 @@ var features = providers.DocumentationNotes{
providers.CanUseAlias: providers.Unimplemented("Apex aliasing is supported via new SVCB and HTTPS record types. For details, check the deSEC docs."),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Can(),
providers.CanUseLOC: providers.Can(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),

View file

@ -74,6 +74,7 @@ retry:
var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseSRV: providers.Can(),
providers.DocCreateDomains: providers.Can(),
providers.DocOfficiallySupported: providers.Cannot(),

View file

@ -25,6 +25,7 @@ var features = providers.DocumentationNotes{
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(),
providers.CanUseDSForChildren: providers.Cannot(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),

View file

@ -19,6 +19,7 @@ var features = providers.DocumentationNotes{
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(),
providers.CanUseDSForChildren: providers.Cannot(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Cannot(),

View file

@ -27,8 +27,9 @@ var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Unimplemented(), //
providers.CanUseAlias: providers.Unimplemented("Needs custom implementation"), // Can possibly be implemented, needs further research
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Unimplemented(), // Seems to support but needs to be implemented
providers.CanUseDSForChildren: providers.Unimplemented(), // Seems to support but needs to be implemented
providers.CanUseDS: providers.Unimplemented(), // Seems to support but needs to be implemented
providers.CanUseDSForChildren: providers.Unimplemented(), // Seems to support but needs to be implemented
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Cannot("According to Domainnameshop this will probably never be supported"), // Does not seem to support it
providers.CanUsePTR: providers.Cannot("According to Domainnameshop this will probably never be supported"), // Seems to support but needs to be implemented
providers.CanUseSOA: providers.Cannot(), // Does not seem to support it

View file

@ -58,6 +58,7 @@ var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Unimplemented(),
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can("SRV records with empty targets are not supported"),
providers.CanUseTLSA: providers.Cannot(),

View file

@ -51,6 +51,7 @@ var features = providers.DocumentationNotes{
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot("Only supports DS records at the apex"),
providers.CanUseDSForChildren: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Can(),

View file

@ -25,6 +25,7 @@ var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDSForChildren: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Can(),

View file

@ -47,6 +47,7 @@ var features = providers.DocumentationNotes{
providers.CanUseAlias: providers.Cannot(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Cannot(),
providers.CanUsePTR: providers.Cannot(),
providers.CanUseSRV: providers.Can("G-Core doesn't support SRV records with empty targets"),

View file

@ -49,6 +49,7 @@ var features = providers.DocumentationNotes{
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(),
providers.CanUseDSForChildren: providers.Cannot(),
providers.CanUseLOC: providers.Can(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSOA: providers.Cannot(),

View file

@ -17,6 +17,7 @@ var features = providers.DocumentationNotes{
providers.CanUseAlias: providers.Cannot(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Cannot(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Cannot(),

View file

@ -23,6 +23,7 @@ var features = providers.DocumentationNotes{
providers.CanUseCAA: providers.Can(),
providers.CanUseSOA: providers.Can(),
providers.CanUseDS: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Cannot(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),

View file

@ -48,6 +48,7 @@ var features = providers.DocumentationNotes{
providers.CanUseAlias: providers.Cannot("INWX does not support the ALIAS or ANAME record type."),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Unimplemented("DS records are only supported at the apex and require a different API call that hasn't been implemented yet."),
providers.CanUseLOC: providers.Can(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can("PTR records with empty targets are not supported"),
providers.CanUseSRV: providers.Can("SRV records with empty targets are not supported."),

View file

@ -88,6 +88,7 @@ func NewLinode(m map[string]string, metadata json.RawMessage) (providers.DNSServ
var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Can(),
providers.CanUseCAA: providers.Can("Linode doesn't support changing the CAA flag"),
providers.CanUseLOC: providers.Cannot(),
providers.DocDualHost: providers.Cannot(),
providers.DocOfficiallySupported: providers.Cannot(),
}

View file

@ -53,6 +53,7 @@ var features = providers.DocumentationNotes{
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot("Only supports DS records at the apex, only for .se and .nu domains; done automatically at back-end."),
providers.CanUseDSForChildren: providers.Cannot(),
providers.CanUseLOC: providers.Can(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Cannot(),
providers.CanUseSOA: providers.Cannot("💩"),

View file

@ -23,6 +23,7 @@ var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Can(),
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Can(),

View file

@ -24,6 +24,7 @@ var features = providers.DocumentationNotes{
providers.CanUseAlias: providers.Cannot(),
providers.CanUseCAA: providers.Cannot(),
providers.CanUseDS: providers.Unimplemented(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),

View file

@ -30,6 +30,7 @@ var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Can(),
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Cannot(),
providers.CanUseSRV: providers.Cannot("The namecheap web console allows you to make SRV records, but their api does not let you read or set them"),
providers.CanUseTLSA: providers.Cannot(),

View file

@ -23,6 +23,7 @@ type namedotcomProvider struct {
var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Can(),
providers.CanUseAlias: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Cannot("PTR records are not supported (See Link)", "https://www.name.com/support/articles/205188508-Reverse-DNS-records"),
providers.CanUseSRV: providers.Can("SRV records with empty targets are not supported"),
providers.DocCreateDomains: providers.Cannot("New domains require registration"),

View file

@ -13,6 +13,7 @@ import (
var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Cannot(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Cannot(),
providers.CanUseSRV: providers.Can(),
providers.DocCreateDomains: providers.Cannot(),

View file

@ -24,6 +24,7 @@ var features = providers.DocumentationNotes{
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(),
providers.CanUseDSForChildren: providers.Cannot(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Cannot(),
providers.CanUsePTR: providers.Cannot(),
providers.CanUseSRV: providers.Can(),

View file

@ -23,6 +23,7 @@ var docNotes = providers.DocumentationNotes{
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Can(),
providers.CanUseDSForChildren: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.DocCreateDomains: providers.Can(),

View file

@ -22,6 +22,7 @@ var features = providers.DocumentationNotes{
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(), // should be supported, but getting 500s in tests
providers.CanUseLOC: providers.Can(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),

View file

@ -22,6 +22,7 @@ var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Can(),
providers.CanUseAlias: providers.Cannot(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Can(),
providers.CanUsePTR: providers.Cannot(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Can(),

View file

@ -50,6 +50,7 @@ var features = providers.DocumentationNotes{
providers.CanUseCAA: providers.Unimplemented(), // CAA record for base domain is pinning to a fixed set once configure
providers.CanUseDS: providers.Cannot(),
providers.CanUseDSForChildren: providers.Cannot(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Cannot(),
providers.CanUsePTR: providers.Cannot(),
providers.CanUseSOA: providers.Cannot(),

View file

@ -15,6 +15,7 @@ var features = providers.DocumentationNotes{
providers.CanUseAlias: providers.Can("Needs to be enabled in PowerDNS first", "https://doc.powerdns.com/authoritative/guides/alias.html"),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Can(),
providers.CanUseLOC: providers.Can(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),

View file

@ -79,6 +79,7 @@ var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Can(),
providers.CanUseAlias: providers.Cannot("R53 does not provide a generic ALIAS functionality. Use R53_ALIAS instead."),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Can(),
providers.CanUseRoute53Alias: providers.Can(),
providers.CanUseSRV: providers.Can(),

View file

@ -19,6 +19,7 @@ var features = providers.DocumentationNotes{
providers.CanUseAlias: providers.Cannot(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Unimplemented("DS records are only supported at the apex and require a different API call that hasn't been implemented yet."),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Cannot(),
providers.CanUsePTR: providers.Can("PTR records with empty targets are not supported"),
providers.CanUseSRV: providers.Can("SRV records with empty targets are not supported."),

View file

@ -24,6 +24,7 @@ type softlayerProvider struct {
var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Unimplemented(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseSRV: providers.Can(),
}

View file

@ -36,6 +36,7 @@ var features = providers.DocumentationNotes{
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(),
providers.CanUseDSForChildren: providers.Cannot(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Can(),

View file

@ -30,6 +30,7 @@ var features = providers.DocumentationNotes{
providers.CanGetZones: providers.Can(),
providers.CanUseAlias: providers.Cannot(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Cannot(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Can(),