From 8c8948e69ac709283088461c55605a7f50d767ff Mon Sep 17 00:00:00 2001 From: Georg Date: Mon, 11 Aug 2025 14:44:12 +0000 Subject: [PATCH] NEW RECORD TYPE: OPENPGPKEY (basic) (#3718) Signed-off-by: Georg Pfuetzenreuter Co-authored-by: Tom Limoncelli --- build/generate/featureMatrix.go | 51 ++++++++++--------- commands/types/dnscontrol.d.ts | 16 ++++++ documentation/SUMMARY.md | 1 + .../domain-modifiers/OPENPGPKEY.md | 24 +++++++++ integrationTest/helpers_integration_test.go | 4 ++ integrationTest/integration_test.go | 10 ++++ models/dnsrr.go | 2 + models/domain.go | 2 +- models/record.go | 6 ++- models/t_parse.go | 4 ++ models/target.go | 2 +- pkg/js/helpers.js | 3 ++ pkg/js/parse_tests/056-openpgpkey.js | 3 ++ pkg/js/parse_tests/056-openpgpkey.json | 23 +++++++++ pkg/normalize/validate.go | 4 +- pkg/prettyzone/prettyzone_test.go | 1 + providers/bind/bindProvider.go | 1 + providers/capabilities.go | 3 ++ providers/capability_string.go | 11 ++-- providers/powerdns/powerdnsProvider.go | 1 + 20 files changed, 139 insertions(+), 33 deletions(-) create mode 100644 documentation/language-reference/domain-modifiers/OPENPGPKEY.md create mode 100644 pkg/js/parse_tests/056-openpgpkey.js create mode 100644 pkg/js/parse_tests/056-openpgpkey.json diff --git a/build/generate/featureMatrix.go b/build/generate/featureMatrix.go index aa2c99a08..deec90459 100644 --- a/build/generate/featureMatrix.go +++ b/build/generate/featureMatrix.go @@ -99,29 +99,30 @@ func featureEmoji( func matrixData() *FeatureMatrix { const ( - OfficialSupport = "Official Support" // vs. community supported - ProviderDNSProvider = "DNS Provider" - ProviderRegistrar = "Registrar" - ProviderThreadSafe = "[Concurrency Verified](../advanced-features/concurrency-verified.md)" - DomainModifierAlias = "[`ALIAS`](../language-reference/domain-modifiers/ALIAS.md)" - DomainModifierCaa = "[`CAA`](../language-reference/domain-modifiers/CAA.md)" - DomainModifierDnssec = "[`AUTODNSSEC`](../language-reference/domain-modifiers/AUTODNSSEC_ON.md)" - DomainModifierHTTPS = "[`HTTPS`](../language-reference/domain-modifiers/HTTPS.md)" - DomainModifierLoc = "[`LOC`](../language-reference/domain-modifiers/LOC.md)" - DomainModifierNaptr = "[`NAPTR`](../language-reference/domain-modifiers/NAPTR.md)" - DomainModifierPtr = "[`PTR`](../language-reference/domain-modifiers/PTR.md)" - DomainModifierSoa = "[`SOA`](../language-reference/domain-modifiers/SOA.md)" - DomainModifierSrv = "[`SRV`](../language-reference/domain-modifiers/SRV.md)" - DomainModifierSshfp = "[`SSHFP`](../language-reference/domain-modifiers/SSHFP.md)" - DomainModifierSvcb = "[`SVCB`](../language-reference/domain-modifiers/SVCB.md)" - DomainModifierTlsa = "[`TLSA`](../language-reference/domain-modifiers/TLSA.md)" - DomainModifierDs = "[`DS`](../language-reference/domain-modifiers/DS.md)" - DomainModifierDhcid = "[`DHCID`](../language-reference/domain-modifiers/DHCID.md)" - DomainModifierDname = "[`DNAME`](../language-reference/domain-modifiers/DNAME.md)" - DomainModifierDnskey = "[`DNSKEY`](../language-reference/domain-modifiers/DNSKEY.md)" - DualHost = "[dual host](../advanced-features/dual-host.md)" - CreateDomains = "create-domains" - GetZones = "get-zones" + OfficialSupport = "Official Support" // vs. community supported + ProviderDNSProvider = "DNS Provider" + ProviderRegistrar = "Registrar" + ProviderThreadSafe = "[Concurrency Verified](../advanced-features/concurrency-verified.md)" + DomainModifierAlias = "[`ALIAS`](../language-reference/domain-modifiers/ALIAS.md)" + DomainModifierCaa = "[`CAA`](../language-reference/domain-modifiers/CAA.md)" + DomainModifierDhcid = "[`DHCID`](../language-reference/domain-modifiers/DHCID.md)" + DomainModifierDname = "[`DNAME`](../language-reference/domain-modifiers/DNAME.md)" + DomainModifierDnskey = "[`DNSKEY`](../language-reference/domain-modifiers/DNSKEY.md)" + DomainModifierDnssec = "[`AUTODNSSEC`](../language-reference/domain-modifiers/AUTODNSSEC_ON.md)" + DomainModifierDs = "[`DS`](../language-reference/domain-modifiers/DS.md)" + DomainModifierHTTPS = "[`HTTPS`](../language-reference/domain-modifiers/HTTPS.md)" + DomainModifierLoc = "[`LOC`](../language-reference/domain-modifiers/LOC.md)" + DomainModifierNaptr = "[`NAPTR`](../language-reference/domain-modifiers/NAPTR.md)" + DomainModifierOpenpgpkey = "[`DNSKEY`](../language-reference/domain-modifiers/OPENPGPKEY.md)" + DomainModifierPtr = "[`PTR`](../language-reference/domain-modifiers/PTR.md)" + DomainModifierSoa = "[`SOA`](../language-reference/domain-modifiers/SOA.md)" + DomainModifierSrv = "[`SRV`](../language-reference/domain-modifiers/SRV.md)" + DomainModifierSshfp = "[`SSHFP`](../language-reference/domain-modifiers/SSHFP.md)" + DomainModifierSvcb = "[`SVCB`](../language-reference/domain-modifiers/SVCB.md)" + DomainModifierTlsa = "[`TLSA`](../language-reference/domain-modifiers/TLSA.md)" + DualHost = "[dual host](../advanced-features/dual-host.md)" + CreateDomains = "create-domains" + GetZones = "get-zones" ) matrix := &FeatureMatrix{ @@ -269,6 +270,10 @@ func matrixData() *FeatureMatrix { DomainModifierNaptr, providers.CanUseNAPTR, ) + setCapability( + DomainModifierOpenpgpkey, + providers.CanUseOPENPGPKEY, + ) setCapability( DomainModifierPtr, providers.CanUsePTR, diff --git a/commands/types/dnscontrol.d.ts b/commands/types/dnscontrol.d.ts index 50805bfcd..0d3549d19 100644 --- a/commands/types/dnscontrol.d.ts +++ b/commands/types/dnscontrol.d.ts @@ -2492,6 +2492,22 @@ declare function NewDnsProvider(name: string, type?: string, meta?: object): str */ declare function NewRegistrar(name: string, type?: string, meta?: object): string; +/** + * OPENPGPKEY adds a OPENPGPKEY record to the domain. + * + * So far, no transformation is applied to the parameters. The data will be passed to the DNS server as-is. + * Reference RFC 7929 for details. + * + * ```javascript + * D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER), + * OPENPGPKEY("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15._openpgpkey", "9901a204447450b7110400d9bef554b145128ccc90d9f52df14bb878626e3db32112d47fbc5ee9cc5ffcbbd06bee487a580481674d9d31e368a85ccf4d4ef3bfa3e23fdde238bc32d8c40d39204b912f8cb1c47a7f34ba64bf3598dafe0f080e17facb678b6e700b0163d677960471d265a197e5ee9d53d71e1911f47f518a0e303abaf3c01b188e37d7bf00a0b90d4f43af944202fc49356a35a367955633cd4503ff7dfa21fb70a201ffb4aa7a755fc560ffd5a4b1d7b7015e7b4bdc0a1e45c1c28fd2f628f4d21f07a091da0d29c98b070566e178c5974554e509a5153a16b271df835e8c8a97715cc4beb5383d05fdf7a0d9412a1fb9f572c195d8c0c696a5ec179bab29d3d8701446e7aca79565ecdd6ec3ceef4937cb248564a75ddb4115adc10400a8f820174b32c99c5ac6ee483c0184fed24fa44d2fd4c9dc00af9ed048b51cfdb95747ab1e35df933382b08f8223da934bfcba59cb356b0d2f4158d647ab76d09c444fadf5e92b95d65f4aae667f33835226170c6625db872a6b72cb13638cf4754941730f5117a4f7c262044bea453839f95b806a0bd98a668073ba2d0fce1ab4326f70656e53555345204275696c642053657276696365203c6275696c6473657276696365406f70656e737573652e6f72673e8864041311020024021b03060b09080703020315020303160201021e01021780050253674e3b050921bf0084000a09103b3011b76b9d65234a5b00a095c38bcfaa29f80adefc0cf9ba2abf3a3e9b516b009e367296e1a96af211f8cded2493f7f6ac09de41"), + * ); + * ``` + * + * @see https://docs.dnscontrol.org/language-reference/domain-modifiers/openpgpkey + */ +declare function OPENPGPKEY(name: string, target: string, ...modifiers: RecordModifier[]): DomainModifier; + /** * `PANIC` terminates the script and therefore DNSControl with an exit code of 1. This should be used if your script cannot gather enough information to generate records, for example when a HTTP request failed. * diff --git a/documentation/SUMMARY.md b/documentation/SUMMARY.md index 59cca1db8..acaeb9c23 100644 --- a/documentation/SUMMARY.md +++ b/documentation/SUMMARY.md @@ -67,6 +67,7 @@ * [NAPTR](language-reference/domain-modifiers/NAPTR.md) * [NO_PURGE](language-reference/domain-modifiers/NO_PURGE.md) * [NS](language-reference/domain-modifiers/NS.md) + * [OPENPGPKEY](language-reference/domain-modifiers/OPENPGPKEY.md) * [PTR](language-reference/domain-modifiers/PTR.md) * [PURGE](language-reference/domain-modifiers/PURGE.md) * [SOA](language-reference/domain-modifiers/SOA.md) diff --git a/documentation/language-reference/domain-modifiers/OPENPGPKEY.md b/documentation/language-reference/domain-modifiers/OPENPGPKEY.md new file mode 100644 index 000000000..27e968259 --- /dev/null +++ b/documentation/language-reference/domain-modifiers/OPENPGPKEY.md @@ -0,0 +1,24 @@ +--- +name: OPENPGPKEY +parameters: + - name + - target + - modifiers... +parameter_types: + name: string + target: string + "modifiers...": RecordModifier[] +--- + +OPENPGPKEY adds a OPENPGPKEY record to the domain. + +So far, no transformation is applied to the parameters. The data will be passed to the DNS server as-is. +Reference RFC 7929 for details. + +{% code title="dnsconfig.js" %} +```javascript +D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER), + OPENPGPKEY("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15._openpgpkey", "9901a204447450b7110400d9bef554b145128ccc90d9f52df14bb878626e3db32112d47fbc5ee9cc5ffcbbd06bee487a580481674d9d31e368a85ccf4d4ef3bfa3e23fdde238bc32d8c40d39204b912f8cb1c47a7f34ba64bf3598dafe0f080e17facb678b6e700b0163d677960471d265a197e5ee9d53d71e1911f47f518a0e303abaf3c01b188e37d7bf00a0b90d4f43af944202fc49356a35a367955633cd4503ff7dfa21fb70a201ffb4aa7a755fc560ffd5a4b1d7b7015e7b4bdc0a1e45c1c28fd2f628f4d21f07a091da0d29c98b070566e178c5974554e509a5153a16b271df835e8c8a97715cc4beb5383d05fdf7a0d9412a1fb9f572c195d8c0c696a5ec179bab29d3d8701446e7aca79565ecdd6ec3ceef4937cb248564a75ddb4115adc10400a8f820174b32c99c5ac6ee483c0184fed24fa44d2fd4c9dc00af9ed048b51cfdb95747ab1e35df933382b08f8223da934bfcba59cb356b0d2f4158d647ab76d09c444fadf5e92b95d65f4aae667f33835226170c6625db872a6b72cb13638cf4754941730f5117a4f7c262044bea453839f95b806a0bd98a668073ba2d0fce1ab4326f70656e53555345204275696c642053657276696365203c6275696c6473657276696365406f70656e737573652e6f72673e8864041311020024021b03060b09080703020315020303160201021e01021780050253674e3b050921bf0084000a09103b3011b76b9d65234a5b00a095c38bcfaa29f80adefc0cf9ba2abf3a3e9b516b009e367296e1a96af211f8cded2493f7f6ac09de41"), +); +``` +{% endcode %} diff --git a/integrationTest/helpers_integration_test.go b/integrationTest/helpers_integration_test.go index c9ec1caac..1b0755295 100644 --- a/integrationTest/helpers_integration_test.go +++ b/integrationTest/helpers_integration_test.go @@ -462,6 +462,10 @@ func naptr(name string, order uint16, preference uint16, flags string, service s return r } +func openpgpkey(name, target string) *models.RecordConfig { + return makeRec(name, target, "OPENPGPKEY") +} + func ptr(name, target string) *models.RecordConfig { return makeRec(name, target, "PTR") } diff --git a/integrationTest/integration_test.go b/integrationTest/integration_test.go index ffc240a0e..812385d7f 100644 --- a/integrationTest/integration_test.go +++ b/integrationTest/integration_test.go @@ -2002,6 +2002,16 @@ func makeTests() []*TestGroup { ).ExpectNoChanges(), ), + testgroup("OPENPGPKEY", + requires(providers.CanUseOPENPGPKEY), + tc("OPENPGPKEY record", + openpgpkey("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15._openpgpkey", "9901a204447450b7110400d9bef554b145128ccc90d9f52df14bb878626e3db32112d47fbc5ee9cc5ffcbbd06bee487a580481674d9d31e368a85ccf4d4ef3bfa3e23fdde238bc32d8c40d39204b912f8cb1c47a7f34ba64bf3598dafe0f080e17facb678b6e700b0163d677960471d265a197e5ee9d53d71e1911f47f518a0e303abaf3c01b188e37d7bf00a0b90d4f43af944202fc49356a35a367955633cd4503ff7dfa21fb70a201ffb4aa7a755fc560ffd5a4b1d7b7015e7b4bdc0a1e45c1c28fd2f628f4d21f07a091da0d29c98b070566e178c5974554e509a5153a16b271df835e8c8a97715cc4beb5383d05fdf7a0d9412a1fb9f572c195d8c0c696a5ec179bab29d3d8701446e7aca79565ecdd6ec3ceef4937cb248564a75ddb4115adc10400a8f820174b32c99c5ac6ee483c0184fed24fa44d2fd4c9dc00af9ed048b51cfdb95747ab1e35df933382b08f8223da934bfcba59cb356b0d2f4158d647ab76d09c444fadf5e92b95d65f4aae667f33835226170c6625db872a6b72cb13638cf4754941730f5117a4f7c262044bea453839f95b806a0bd98a668073ba2d0fce1ab4326f70656e53555345204275696c642053657276696365203c6275696c6473657276696365406f70656e737573652e6f72673e8864041311020024021b03060b09080703020315020303160201021e01021780050253674e3b050921bf0084000a09103b3011b76b9d65234a5b00a095c38bcfaa29f80adefc0cf9ba2abf3a3e9b516b009e367296e1a96af211f8cded2493f7f6ac09de41"), + ), + tc("OPENPGPKEY record change", + openpgpkey("2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db._openpgpkey", "99010d045ae3116a010800c426db68c752d5a5c3f6608b0b20ee6a2a6c1f321ca3490f8be044f3b671512ca1489629f8d7d4e273f96517dca642bd8cc652a5460773159f52707d6b839d9b996771cbed9367c248b125785f27d24d926f33e9d7606c4440126b6257117c2e617b4b411931301be869ea45c7e7adc5f97538bb31949a1d6b0616af0ec5a378ca3db2369fb2a9fae890099f126b40e72a8cdbdacd88e9a448c5cf27bf1daaaedabe5c9c3fdb3e732f40466da4dd63ce75a42216b60dd6a9559ab66ff4a6753315ef31d1a90be1111536b92e1214b368a72b7f730ba38f75d35aa080aef4204536a21c088be07637954a43587f699b14fecaee5fec520d73ea6b466be74356290011010001b43d6f70656e5355534520436f6e7461696e6572205369676e696e67204b6579203c6275696c642d636f6e7461696e6572406f70656e737573652e6f72673e89013e04130102002805025ae3116a021b03050912cc0300060b090807030206150802090a0b0416020301021e01021780000a0910d754694f9ab48ce976dd07fc0e63f41edf7aa4d12b8f53588b2029310b1bee9a73858bfaebd9b381e650f80e31ef5f910be626d3cc1904f76b00927a3107bafabbb0cb0e3805c9de5a150cd90958eb64a2147225febefa5bf32f6e2f0296f348b7f16b58a7b6c732a09d20f00d95f8dcc6e36f1c300ccbe519dfd5c9229839303a08c50530eac2ad673c50d0fb4d7001e9c33cb76e2c04bae7ebab98c10e221a010773a97397ea3ca594fb0f2a6aff187d85236907007c67acc2dfba9b9e155d893ca6b982b927c51eaf588bc4f6f9531c2047474183a7e27561ccd63d993cc9e0208661d2e16a9e3f3fcff11ee894b95ac0447782a1389049cd45c234f5417694fb2624d522c58b42da3e04"), + ), + ), + // This MUST be the last test. testgroup("final", tc("final", txt("final", `TestDNSProviders was successful!`)), diff --git a/models/dnsrr.go b/models/dnsrr.go index 7c7c4f9c5..f88841723 100644 --- a/models/dnsrr.go +++ b/models/dnsrr.go @@ -62,6 +62,8 @@ func helperRRtoRC(rr dns.RR, origin string, fixBug bool) (RecordConfig, error) { err = rc.SetTargetMX(v.Preference, v.Mx) case *dns.NAPTR: err = rc.SetTargetNAPTR(v.Order, v.Preference, v.Flags, v.Service, v.Regexp, v.Replacement) + case *dns.OPENPGPKEY: + err = rc.SetTarget(v.PublicKey) case *dns.NS: err = rc.SetTarget(v.Ns) case *dns.PTR: diff --git a/models/domain.go b/models/domain.go index 151ea73e8..e3e460a7a 100644 --- a/models/domain.go +++ b/models/domain.go @@ -142,7 +142,7 @@ func (dc *DomainConfig) Punycode() error { if err := rec.SetTarget(rec.GetTargetField()); err != nil { return err } - case "A", "AAAA", "CAA", "DHCID", "DNSKEY", "DS", "HTTPS", "LOC", "NAPTR", "SOA", "SSHFP", "SVCB", "TXT", "TLSA", "AZURE_ALIAS": + case "A", "AAAA", "CAA", "DHCID", "DNSKEY", "DS", "HTTPS", "LOC", "NAPTR", "OPENPGPKEY", "SOA", "SSHFP", "SVCB", "TXT", "TLSA", "AZURE_ALIAS": // Nothing to do. default: return fmt.Errorf("Punycode rtype %v unimplemented", rec.Type) diff --git a/models/record.go b/models/record.go index 1b18c20e6..6eb154987 100644 --- a/models/record.go +++ b/models/record.go @@ -444,6 +444,8 @@ func (rc *RecordConfig) ToRR() dns.RR { rr.(*dns.NAPTR).Replacement = rc.GetTargetField() case dns.TypeNS: rr.(*dns.NS).Ns = rc.GetTargetField() + case dns.TypeOPENPGPKEY: + rr.(*dns.OPENPGPKEY).PublicKey = rc.GetTargetField() case dns.TypePTR: rr.(*dns.PTR).Ptr = rc.GetTargetField() case dns.TypeSOA: @@ -615,7 +617,7 @@ func Downcase(recs []*RecordConfig) { r.Name = strings.ToLower(r.Name) r.NameFQDN = strings.ToLower(r.NameFQDN) switch r.Type { // #rtype_variations - case "AKAMAICDN", "ALIAS", "AAAA", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "PTR", "SRV", "TLSA", "AZURE_ALIAS": + case "AKAMAICDN", "ALIAS", "AAAA", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "OPENPGPKEY", "PTR", "SRV", "TLSA", "AZURE_ALIAS": // Target is case insensitive. Downcase it. r.target = strings.ToLower(r.target) // BUGFIX(tlim): isn't ALIAS in the wrong case statement? @@ -643,7 +645,7 @@ func CanonicalizeTargets(recs []*RecordConfig, origin string) { 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. 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", "SSHFP", "SVCB", "TLSA", "TXT", "ADGUARDHOME_A_PASSTHROUGH", "ADGUARDHOME_AAAA_PASSTHROUGH": + case "A", "AKAMAICDN", "CAA", "DHCID", "CLOUDFLAREAPI_SINGLE_REDIRECT", "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE", "HTTPS", "IMPORT_TRANSFORM", "LOC", "OPENPGPKEY", "SSHFP", "SVCB", "TLSA", "TXT", "ADGUARDHOME_A_PASSTHROUGH", "ADGUARDHOME_AAAA_PASSTHROUGH": // Do nothing. case "SOA": if r.target != "DEFAULT_NOT_SET." { diff --git a/models/t_parse.go b/models/t_parse.go index fbbc95196..54f1a1dd9 100644 --- a/models/t_parse.go +++ b/models/t_parse.go @@ -90,6 +90,8 @@ func (rc *RecordConfig) PopulateFromStringFunc(rtype, contents, origin string, t return rc.SetTargetMXString(contents) case "NAPTR": return rc.SetTargetNAPTRString(contents) + case "OPENPGPKEY": + return rc.SetTarget(contents) case "SOA": return rc.SetTargetSOAString(contents) case "SPF", "TXT": @@ -180,6 +182,8 @@ func (rc *RecordConfig) PopulateFromString(rtype, contents, origin string) error return rc.SetTargetMXString(contents) case "NAPTR": return rc.SetTargetNAPTRString(contents) + case "OPENPGPKEY": + return rc.SetTarget(contents) case "SOA": return rc.SetTargetSOAString(contents) case "SPF", "TXT": diff --git a/models/target.go b/models/target.go index b298a1028..a8f7b99ea 100644 --- a/models/target.go +++ b/models/target.go @@ -108,7 +108,7 @@ func (rc *RecordConfig) GetTargetDebug() string { } content := fmt.Sprintf("%s %s %s %d", rc.Type, rc.NameFQDN, target, rc.TTL) switch rc.Type { // #rtype_variations - case "A", "AAAA", "AKAMAICDN", "CNAME", "DHCID", "NS", "PTR", "TXT": + case "A", "AAAA", "AKAMAICDN", "CNAME", "DHCID", "NS", "OPENPGPKEY", "PTR", "TXT": // Nothing special. case "AZURE_ALIAS": content += " type=" + rc.AzureAlias["type"] diff --git a/pkg/js/helpers.js b/pkg/js/helpers.js index 0d93f0b59..4f54504ba 100644 --- a/pkg/js/helpers.js +++ b/pkg/js/helpers.js @@ -533,6 +533,9 @@ var NAPTR = recordBuilder('NAPTR', { }, }); +// OPENPGPKEY(name,target, recordModifiers...) +var OPENPGPKEY = recordBuilder('OPENPGPKEY'); + // SOA(name,ns,mbox,refresh,retry,expire,minimum, recordModifiers...) var SOA = recordBuilder('SOA', { args: [ diff --git a/pkg/js/parse_tests/056-openpgpkey.js b/pkg/js/parse_tests/056-openpgpkey.js new file mode 100644 index 000000000..f8ff18491 --- /dev/null +++ b/pkg/js/parse_tests/056-openpgpkey.js @@ -0,0 +1,3 @@ +D("foo.com", "none", + OPENPGPKEY("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15._openpgpkey", "9901a204447450b7110400d9bef554b145128ccc90d9f52df14bb878626e3db32112d47fbc5ee9cc5ffcbbd06bee487a580481674d9d31e368a85ccf4d4ef3bfa3e23fdde238bc32d8c40d39204b912f8cb1c47a7f34ba64bf3598dafe0f080e17facb678b6e700b0163d677960471d265a197e5ee9d53d71e1911f47f518a0e303abaf3c01b188e37d7bf00a0b90d4f43af944202fc49356a35a367955633cd4503ff7dfa21fb70a201ffb4aa7a755fc560ffd5a4b1d7b7015e7b4bdc0a1e45c1c28fd2f628f4d21f07a091da0d29c98b070566e178c5974554e509a5153a16b271df835e8c8a97715cc4beb5383d05fdf7a0d9412a1fb9f572c195d8c0c696a5ec179bab29d3d8701446e7aca79565ecdd6ec3ceef4937cb248564a75ddb4115adc10400a8f820174b32c99c5ac6ee483c0184fed24fa44d2fd4c9dc00af9ed048b51cfdb95747ab1e35df933382b08f8223da934bfcba59cb356b0d2f4158d647ab76d09c444fadf5e92b95d65f4aae667f33835226170c6625db872a6b72cb13638cf4754941730f5117a4f7c262044bea453839f95b806a0bd98a668073ba2d0fce1ab4326f70656e53555345204275696c642053657276696365203c6275696c6473657276696365406f70656e737573652e6f72673e8864041311020024021b03060b09080703020315020303160201021e01021780050253674e3b050921bf0084000a09103b3011b76b9d65234a5b00a095c38bcfaa29f80adefc0cf9ba2abf3a3e9b516b009e367296e1a96af211f8cded2493f7f6ac09de41"), +); diff --git a/pkg/js/parse_tests/056-openpgpkey.json b/pkg/js/parse_tests/056-openpgpkey.json new file mode 100644 index 000000000..946943c08 --- /dev/null +++ b/pkg/js/parse_tests/056-openpgpkey.json @@ -0,0 +1,23 @@ +{ + "dns_providers": [], + "domains": [ + { + "dnsProviders": {}, + "meta": { + "dnscontrol_tag": "", + "dnscontrol_uniquename": "foo.com" + }, + "name": "foo.com", + "records": [ + { + "name": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15._openpgpkey", + "target": "9901a204447450b7110400d9bef554b145128ccc90d9f52df14bb878626e3db32112d47fbc5ee9cc5ffcbbd06bee487a580481674d9d31e368a85ccf4d4ef3bfa3e23fdde238bc32d8c40d39204b912f8cb1c47a7f34ba64bf3598dafe0f080e17facb678b6e700b0163d677960471d265a197e5ee9d53d71e1911f47f518a0e303abaf3c01b188e37d7bf00a0b90d4f43af944202fc49356a35a367955633cd4503ff7dfa21fb70a201ffb4aa7a755fc560ffd5a4b1d7b7015e7b4bdc0a1e45c1c28fd2f628f4d21f07a091da0d29c98b070566e178c5974554e509a5153a16b271df835e8c8a97715cc4beb5383d05fdf7a0d9412a1fb9f572c195d8c0c696a5ec179bab29d3d8701446e7aca79565ecdd6ec3ceef4937cb248564a75ddb4115adc10400a8f820174b32c99c5ac6ee483c0184fed24fa44d2fd4c9dc00af9ed048b51cfdb95747ab1e35df933382b08f8223da934bfcba59cb356b0d2f4158d647ab76d09c444fadf5e92b95d65f4aae667f33835226170c6625db872a6b72cb13638cf4754941730f5117a4f7c262044bea453839f95b806a0bd98a668073ba2d0fce1ab4326f70656e53555345204275696c642053657276696365203c6275696c6473657276696365406f70656e737573652e6f72673e8864041311020024021b03060b09080703020315020303160201021e01021780050253674e3b050921bf0084000a09103b3011b76b9d65234a5b00a095c38bcfaa29f80adefc0cf9ba2abf3a3e9b516b009e367296e1a96af211f8cded2493f7f6ac09de41", + "ttl": 300, + "type": "OPENPGPKEY" + } + ], + "registrar": "none" + } + ], + "registrars": [] +} diff --git a/pkg/normalize/validate.go b/pkg/normalize/validate.go index dd39ad1a1..d502489e6 100644 --- a/pkg/normalize/validate.go +++ b/pkg/normalize/validate.go @@ -70,6 +70,7 @@ func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []strin "MX": true, "NAPTR": true, "NS": true, + "OPENPGPKEY": true, "PTR": true, "SOA": true, "SRV": true, @@ -223,7 +224,7 @@ func checkTargets(rec *models.RecordConfig, domain string) (errs []error) { } case "SRV": check(checkTarget(target)) - case "CAA", "DHCID", "DNSKEY", "DS", "HTTPS", "IMPORT_TRANSFORM", "SSHFP", "SVCB", "TLSA", "TXT": + case "CAA", "DHCID", "DNSKEY", "DS", "HTTPS", "IMPORT_TRANSFORM", "OPENPGPKEY", "SSHFP", "SVCB", "TLSA", "TXT": default: if rec.Metadata["orig_custom_type"] != "" { // it is a valid custom type. We perform no validation on target @@ -724,6 +725,7 @@ var providerCapabilityChecks = []pairTypeCapability{ capabilityCheck("HTTPS", providers.CanUseHTTPS), capabilityCheck("LOC", providers.CanUseLOC), capabilityCheck("NAPTR", providers.CanUseNAPTR), + capabilityCheck("OPENPGPKEY", providers.CanUseOPENPGPKEY), capabilityCheck("PTR", providers.CanUsePTR), capabilityCheck("R53_ALIAS", providers.CanUseRoute53Alias), capabilityCheck("SOA", providers.CanUseSOA), diff --git a/pkg/prettyzone/prettyzone_test.go b/pkg/prettyzone/prettyzone_test.go index a344d13e0..f2f21c34d 100644 --- a/pkg/prettyzone/prettyzone_test.go +++ b/pkg/prettyzone/prettyzone_test.go @@ -358,6 +358,7 @@ func TestWriteZoneFileEach(t *testing.T) { d = append(d, mustNewRR(`dnssec.bosun.org. 300 IN DNSKEY 257 3 13 rNR701yiOPHfqDP53GnsHZdlsRqI7O1ksk60rnFILZVk7Z4eTBd1U49oSkTNVNox9tb7N15N2hboXoMEyFFzcw==`)) d = append(d, mustNewRR(`bosun.org. 300 IN HTTPS 1 . alpn="h3,h2"`)) d = append(d, mustNewRR(`bosun.org. 300 IN SVCB 1 . alpn="h3,h2"`)) + d = append(d, mustNewRR(`9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15._openpgpkey.bosun.org. 300 IN OPENPGPKEY 9901a204447450b7110400d9bef554b145128ccc90d9f52df14bb878626e3db32112d47fbc5ee9cc5ffcbbd06bee487a580481674d9d31e368a85ccf4d4ef3bfa3e23fdde238bc32d8c40d39204b912f8cb1c47a7f34ba64bf3598dafe0f080e17facb678b6e700b0163d677960471d265a197e5ee9d53d71e1911f47f518a0e303abaf3c01b188e37d7bf00a0b90d4f43af944202fc49356a35a367955633cd4503ff7dfa21fb70a201ffb4aa7a755fc560ffd5a4b1d7b7015e7b4bdc0a1e45c1c28fd2f628f4d21f07a091da0d29c98b070566e178c5974554e509a5153a16b271df835e8c8a97715cc4beb5383d05fdf7a0d9412a1fb9f572c195d8c0c696a5ec179bab29d3d8701446e7aca79565ecdd6ec3ceef4937cb248564a75ddb4115adc10400a8f820174b32c99c5ac6ee483c0184fed24fa44d2fd4c9dc00af9ed048b51cfdb95747ab1e35df933382b08f8223da934bfcba59cb356b0d2f4158d647ab76d09c444fadf5e92b95d65f4aae667f33835226170c6625db872a6b72cb13638cf4754941730f5117a4f7c262044bea453839f95b806a0bd98a668073ba2d0fce1ab4326f70656e53555345204275696c642053657276696365203c6275696c6473657276696365406f70656e737573652e6f72673e8864041311020024021b03060b09080703020315020303160201021e01021780050253674e3b050921bf0084000a09103b3011b76b9d65234a5b00a095c38bcfaa29f80adefc0cf9ba2abf3a3e9b516b009e367296e1a96af211f8cded2493f7f6ac09de41"`)) buf := &bytes.Buffer{} if err := writeZoneFileRR(buf, d, "bosun.org"); err != nil { t.Fatal(err) diff --git a/providers/bind/bindProvider.go b/providers/bind/bindProvider.go index 81cd9abb6..ed2a90884 100644 --- a/providers/bind/bindProvider.go +++ b/providers/bind/bindProvider.go @@ -44,6 +44,7 @@ var features = providers.DocumentationNotes{ providers.CanUseHTTPS: providers.Can(), providers.CanUseLOC: providers.Can(), providers.CanUseNAPTR: providers.Can(), + providers.CanUseOPENPGPKEY: providers.Can(), providers.CanUsePTR: providers.Can(), providers.CanUseSOA: providers.Can(), providers.CanUseSRV: providers.Can(), diff --git a/providers/capabilities.go b/providers/capabilities.go index 6d0638b8d..c54fa406f 100644 --- a/providers/capabilities.go +++ b/providers/capabilities.go @@ -97,6 +97,9 @@ const ( // CanUseDNSKEY indicates that the provider can handle DNSKEY records CanUseDNSKEY + // CanUseOPENPGPKEY indicates that the provider can handle OPENPGPKEY records + CanUseOPENPGPKEY + // DocCreateDomains means provider can add domains with the `dnscontrol create-domains` command DocCreateDomains diff --git a/providers/capability_string.go b/providers/capability_string.go index 9b51f7d19..4b05b7daf 100644 --- a/providers/capability_string.go +++ b/providers/capability_string.go @@ -31,14 +31,15 @@ func _() { _ = x[CanUseSVCB-20] _ = x[CanUseTLSA-21] _ = x[CanUseDNSKEY-22] - _ = x[DocCreateDomains-23] - _ = x[DocDualHost-24] - _ = x[DocOfficiallySupported-25] + _ = x[CanUseOPENPGPKEY-23] + _ = x[DocCreateDomains-24] + _ = x[DocDualHost-25] + _ = x[DocOfficiallySupported-26] } -const _Capability_name = "CanAutoDNSSECCanConcurCanGetZonesCanOnlyDiff1FeaturesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDHCIDCanUseDNAMECanUseDSCanUseDSForChildrenCanUseHTTPSCanUseLOCCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSOACanUseSRVCanUseSSHFPCanUseSVCBCanUseTLSACanUseDNSKEYDocCreateDomainsDocDualHostDocOfficiallySupported" +const _Capability_name = "CanAutoDNSSECCanConcurCanGetZonesCanOnlyDiff1FeaturesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDHCIDCanUseDNAMECanUseDSCanUseDSForChildrenCanUseHTTPSCanUseLOCCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSOACanUseSRVCanUseSSHFPCanUseSVCBCanUseTLSACanUseDNSKEYCanUseOPENPGPKEYDocCreateDomainsDocDualHostDocOfficiallySupported" -var _Capability_index = [...]uint16{0, 13, 22, 33, 53, 68, 79, 95, 104, 115, 126, 134, 153, 164, 173, 184, 193, 211, 220, 229, 240, 250, 260, 272, 288, 299, 321} +var _Capability_index = [...]uint16{0, 13, 22, 33, 53, 68, 79, 95, 104, 115, 126, 134, 153, 164, 173, 184, 193, 211, 220, 229, 240, 250, 260, 272, 288, 304, 315, 337} func (i Capability) String() string { if i >= Capability(len(_Capability_index)-1) { diff --git a/providers/powerdns/powerdnsProvider.go b/providers/powerdns/powerdnsProvider.go index c924dd7b0..726779a2c 100644 --- a/providers/powerdns/powerdnsProvider.go +++ b/providers/powerdns/powerdnsProvider.go @@ -22,6 +22,7 @@ var features = providers.DocumentationNotes{ providers.CanUseDHCID: providers.Can(), providers.CanUseLOC: providers.Unimplemented("Normalization within the PowerDNS API seems to be buggy, so disabled", "https://github.com/PowerDNS/pdns/issues/10558"), providers.CanUseNAPTR: providers.Can(), + providers.CanUseOPENPGPKEY: providers.Can(), providers.CanUsePTR: providers.Can(), providers.CanUseSOA: providers.Can(), providers.CanUseSRV: providers.Can(),