Add DNS provider for UltraDNS (#1806)

Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
This commit is contained in:
AntonyRohithAkash 2023-01-11 19:27:25 +05:30 committed by GitHub
parent 7f8305e8d8
commit afcb2bc6d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 515 additions and 23 deletions

View file

@ -73,10 +73,10 @@ Detailed documentation is available [here](https://go-acme.github.io/lego/dns).
| [RFC2136](https://go-acme.github.io/lego/dns/rfc2136/) | [RimuHosting](https://go-acme.github.io/lego/dns/rimuhosting/) | [Sakura Cloud](https://go-acme.github.io/lego/dns/sakuracloud/) | [Scaleway](https://go-acme.github.io/lego/dns/scaleway/) |
| [Selectel](https://go-acme.github.io/lego/dns/selectel/) | [Servercow](https://go-acme.github.io/lego/dns/servercow/) | [Simply.com](https://go-acme.github.io/lego/dns/simply/) | [Sonic](https://go-acme.github.io/lego/dns/sonic/) |
| [Stackpath](https://go-acme.github.io/lego/dns/stackpath/) | [Tencent Cloud DNS](https://go-acme.github.io/lego/dns/tencentcloud/) | [TransIP](https://go-acme.github.io/lego/dns/transip/) | [UKFast SafeDNS](https://go-acme.github.io/lego/dns/safedns/) |
| [Variomedia](https://go-acme.github.io/lego/dns/variomedia/) | [VegaDNS](https://go-acme.github.io/lego/dns/vegadns/) | [Vercel](https://go-acme.github.io/lego/dns/vercel/) | [Versio.[nl/eu/uk]](https://go-acme.github.io/lego/dns/versio/) |
| [VinylDNS](https://go-acme.github.io/lego/dns/vinyldns/) | [VK Cloud](https://go-acme.github.io/lego/dns/vkcloud/) | [Vscale](https://go-acme.github.io/lego/dns/vscale/) | [Vultr](https://go-acme.github.io/lego/dns/vultr/) |
| [WEDOS](https://go-acme.github.io/lego/dns/wedos/) | [Yandex Cloud](https://go-acme.github.io/lego/dns/yandexcloud/) | [Yandex PDD](https://go-acme.github.io/lego/dns/yandex/) | [Zone.ee](https://go-acme.github.io/lego/dns/zoneee/) |
| [Zonomi](https://go-acme.github.io/lego/dns/zonomi/) | | | |
| [Ultradns](https://go-acme.github.io/lego/dns/ultradns/) | [Variomedia](https://go-acme.github.io/lego/dns/variomedia/) | [VegaDNS](https://go-acme.github.io/lego/dns/vegadns/) | [Vercel](https://go-acme.github.io/lego/dns/vercel/) |
| [Versio.[nl/eu/uk]](https://go-acme.github.io/lego/dns/versio/) | [VinylDNS](https://go-acme.github.io/lego/dns/vinyldns/) | [VK Cloud](https://go-acme.github.io/lego/dns/vkcloud/) | [Vscale](https://go-acme.github.io/lego/dns/vscale/) |
| [Vultr](https://go-acme.github.io/lego/dns/vultr/) | [WEDOS](https://go-acme.github.io/lego/dns/wedos/) | [Yandex Cloud](https://go-acme.github.io/lego/dns/yandexcloud/) | [Yandex PDD](https://go-acme.github.io/lego/dns/yandex/) |
| [Zone.ee](https://go-acme.github.io/lego/dns/zoneee/) | [Zonomi](https://go-acme.github.io/lego/dns/zonomi/) | | |
<!-- END DNS PROVIDERS LIST -->

View file

@ -109,6 +109,7 @@ func allDNSCodes() string {
"stackpath",
"tencentcloud",
"transip",
"ultradns",
"variomedia",
"vegadns",
"vercel",
@ -2158,6 +2159,27 @@ func displayDNSHelp(w io.Writer, name string) error {
ew.writeln()
ew.writeln(`More information: https://go-acme.github.io/lego/dns/transip`)
case "ultradns":
// generated from: providers/dns/ultradns/ultradns.toml
ew.writeln(`Configuration for Ultradns.`)
ew.writeln(`Code: 'ultradns'`)
ew.writeln(`Since: 'v4.10.0'`)
ew.writeln()
ew.writeln(`Credentials:`)
ew.writeln(` - "ULTRADNS_PASSWORD": API Password`)
ew.writeln(` - "ULTRADNS_USERNAME": API Username`)
ew.writeln()
ew.writeln(`Additional Configuration:`)
ew.writeln(` - "ULTRADNS_ENDPOINT": API endpoint URL, defaults to https://api.ultradns.com/`)
ew.writeln(` - "ULTRADNS_POLLING_INTERVAL": Time between DNS propagation check`)
ew.writeln(` - "ULTRADNS_PROPAGATION_TIMEOUT": Maximum waiting time for DNS propagation`)
ew.writeln(` - "ULTRADNS_TTL": The TTL of the TXT record used for the DNS challenge`)
ew.writeln()
ew.writeln(`More information: https://go-acme.github.io/lego/dns/ultradns`)
case "variomedia":
// generated from: providers/dns/variomedia/variomedia.toml
ew.writeln(`Configuration for Variomedia.`)

View file

@ -0,0 +1,70 @@
---
title: "Ultradns"
date: 2019-03-03T16:39:46+01:00
draft: false
slug: ultradns
dnsprovider:
since: "v4.10.0"
code: "ultradns"
url: "https://neustarsecurityservices.com/dns-services"
---
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
<!-- providers/dns/ultradns/ultradns.toml -->
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
Configuration for [Ultradns](https://neustarsecurityservices.com/dns-services).
<!--more-->
- Code: `ultradns`
- Since: v4.10.0
Here is an example bash command using the Ultradns provider:
```bash
ULTRADNS_USERNAME=username \
ULTRADNS_PASSWORD=password \
lego --email you@example.com --dns ultradns --domains my.example.org run
```
## Credentials
| Environment Variable Name | Description |
|-----------------------|-------------|
| `ULTRADNS_PASSWORD` | API Password |
| `ULTRADNS_USERNAME` | API Username |
The environment variable names can be suffixed by `_FILE` to reference a file instead of a value.
More information [here]({{< ref "dns#configuration-and-credentials" >}}).
## Additional Configuration
| Environment Variable Name | Description |
|--------------------------------|-------------|
| `ULTRADNS_ENDPOINT` | API endpoint URL, defaults to https://api.ultradns.com/ |
| `ULTRADNS_POLLING_INTERVAL` | Time between DNS propagation check |
| `ULTRADNS_PROPAGATION_TIMEOUT` | Maximum waiting time for DNS propagation |
| `ULTRADNS_TTL` | The TTL of the TXT record used for the DNS challenge |
The environment variable names can be suffixed by `_FILE` to reference a file instead of a value.
More information [here]({{< ref "dns#configuration-and-credentials" >}}).
## More information
- [API documentation](https://ultra-portalstatic.ultradns.com/static/docs/REST-API_User_Guide.pdf)
- [Go client](https://github.com/ultradns/ultradns-go-sdk)
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
<!-- providers/dns/ultradns/ultradns.toml -->
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->

View file

@ -125,7 +125,7 @@ To display the documentation for a specific DNS provider, run:
$ lego dnshelp -c code
Supported DNS providers:
acme-dns, alidns, allinkl, arvancloud, auroradns, autodns, azure, bindman, bluecat, checkdomain, civo, clouddns, cloudflare, cloudns, cloudxns, conoha, constellix, desec, designate, digitalocean, dnsimple, dnsmadeeasy, dnspod, dode, domeneshop, dreamhost, duckdns, dyn, dynu, easydns, edgedns, epik, exec, exoscale, freemyip, gandi, gandiv5, gcloud, gcore, glesys, godaddy, hetzner, hostingde, hosttech, httpreq, hurricane, hyperone, ibmcloud, iij, iijdpf, infoblox, infomaniak, internetbs, inwx, ionos, iwantmyname, joker, liara, lightsail, linode, liquidweb, loopia, luadns, manual, mydnsjp, mythicbeasts, namecheap, namedotcom, namesilo, nearlyfreespeech, netcup, netlify, nicmanager, nifcloud, njalla, ns1, oraclecloud, otc, ovh, pdns, porkbun, rackspace, regru, rfc2136, rimuhosting, route53, safedns, sakuracloud, scaleway, selectel, servercow, simply, sonic, stackpath, tencentcloud, transip, variomedia, vegadns, vercel, versio, vinyldns, vkcloud, vscale, vultr, wedos, yandex, yandexcloud, zoneee, zonomi
acme-dns, alidns, allinkl, arvancloud, auroradns, autodns, azure, bindman, bluecat, checkdomain, civo, clouddns, cloudflare, cloudns, cloudxns, conoha, constellix, desec, designate, digitalocean, dnsimple, dnsmadeeasy, dnspod, dode, domeneshop, dreamhost, duckdns, dyn, dynu, easydns, edgedns, epik, exec, exoscale, freemyip, gandi, gandiv5, gcloud, gcore, glesys, godaddy, hetzner, hostingde, hosttech, httpreq, hurricane, hyperone, ibmcloud, iij, iijdpf, infoblox, infomaniak, internetbs, inwx, ionos, iwantmyname, joker, liara, lightsail, linode, liquidweb, loopia, luadns, manual, mydnsjp, mythicbeasts, namecheap, namedotcom, namesilo, nearlyfreespeech, netcup, netlify, nicmanager, nifcloud, njalla, ns1, oraclecloud, otc, ovh, pdns, porkbun, rackspace, regru, rfc2136, rimuhosting, route53, safedns, sakuracloud, scaleway, selectel, servercow, simply, sonic, stackpath, tencentcloud, transip, ultradns, variomedia, vegadns, vercel, versio, vinyldns, vkcloud, vscale, vultr, wedos, yandex, yandexcloud, zoneee, zonomi
More information: https://go-acme.github.io/lego/dns
"""

14
go.mod
View file

@ -55,14 +55,15 @@ require (
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490
github.com/transip/gotransip/v6 v6.17.0
github.com/ultradns/ultradns-go-sdk v1.4.0-20221107152238-f3f1d1d
github.com/urfave/cli/v2 v2.14.0
github.com/vinyldns/go-vinyldns v0.9.16
github.com/vultr/govultr/v2 v2.17.2
github.com/yandex-cloud/go-genproto v0.0.0-20220805142335-27b56ddae16f
github.com/yandex-cloud/go-sdk v0.0.0-20220805164847-cf028e604997
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1
golang.org/x/net v0.1.0
golang.org/x/oauth2 v0.1.0
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65
google.golang.org/api v0.20.0
gopkg.in/ns1/ns1-go.v2 v2.6.5
@ -121,11 +122,10 @@ require (
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.opencensus.io v0.22.3 // indirect
go.uber.org/ratelimit v0.2.0 // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/text v0.4.0 // indirect
golang.org/x/tools v0.1.12 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c // indirect
google.golang.org/grpc v1.41.0 // indirect

27
go.sum
View file

@ -549,6 +549,8 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
github.com/ultradns/ultradns-go-sdk v1.4.0-20221107152238-f3f1d1d h1:pLMpEtrkiaeA2NY6CzA2+K75YnY6c5ka02SbxQ9YgSo=
github.com/ultradns/ultradns-go-sdk v1.4.0-20221107152238-f3f1d1d/go.mod h1:IgdoVzrGYzq4H4IGI0DAVnM3CbcuQDSxEP4s/j6cztI=
github.com/urfave/cli/v2 v2.14.0 h1:sFRL29Dm9JhXSMYb96raDeo/Q/JRyPXPs8u+4CkMlI8=
github.com/urfave/cli/v2 v2.14.0/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
@ -634,8 +636,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -671,15 +674,15 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA=
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y=
golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -688,8 +691,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -741,12 +744,13 @@ golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -755,8 +759,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -801,12 +806,12 @@ golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=

View file

@ -100,6 +100,7 @@ import (
"github.com/go-acme/lego/v4/providers/dns/stackpath"
"github.com/go-acme/lego/v4/providers/dns/tencentcloud"
"github.com/go-acme/lego/v4/providers/dns/transip"
"github.com/go-acme/lego/v4/providers/dns/ultradns"
"github.com/go-acme/lego/v4/providers/dns/variomedia"
"github.com/go-acme/lego/v4/providers/dns/vegadns"
"github.com/go-acme/lego/v4/providers/dns/vercel"
@ -310,6 +311,8 @@ func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) {
return tencentcloud.NewDNSProvider()
case "transip":
return transip.NewDNSProvider()
case "ultradns":
return ultradns.NewDNSProvider()
case "variomedia":
return variomedia.NewDNSProvider()
case "vegadns":

View file

@ -0,0 +1,169 @@
// Package ultradns implements a DNS provider for solving the DNS-01 challenge using ultradns.
package ultradns
import (
"errors"
"fmt"
"time"
"github.com/go-acme/lego/v4/challenge/dns01"
"github.com/go-acme/lego/v4/platform/config/env"
"github.com/ultradns/ultradns-go-sdk/pkg/client"
"github.com/ultradns/ultradns-go-sdk/pkg/record"
"github.com/ultradns/ultradns-go-sdk/pkg/rrset"
)
// Environment variables names.
const (
envNamespace = "ULTRADNS_"
EnvUsername = envNamespace + "USERNAME"
EnvPassword = envNamespace + "PASSWORD"
EnvEndpoint = envNamespace + "ENDPOINT"
EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
// Default variables names.
defaultEndpoint = "https://api.ultradns.com/"
defaultUserAgent = "lego-provider-ultradns"
)
// DNSProvider implements the challenge.Provider interface.
type DNSProvider struct {
config *Config
client *client.Client
}
// Config is used to configure the creation of the DNSProvider.
type Config struct {
Username string
Password string
Endpoint string
TTL int
PropagationTimeout time.Duration
PollingInterval time.Duration
}
// NewDefaultConfig returns a default configuration for the DNSProvider.
func NewDefaultConfig() *Config {
return &Config{
Endpoint: env.GetOrDefaultString(EnvEndpoint, defaultEndpoint),
TTL: env.GetOrDefaultInt(EnvTTL, 120),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, 4*time.Second),
}
}
// NewDNSProvider returns a DNSProvider instance configured for ultradns.
// Credentials must be passed in the environment variables:
// ULTRADNS_USERNAME and ULTRADNS_PASSWORD.
func NewDNSProvider() (*DNSProvider, error) {
values, err := env.Get(EnvUsername, EnvPassword)
if err != nil {
return nil, fmt.Errorf("ultradns: %w", err)
}
config := NewDefaultConfig()
config.Username = values[EnvUsername]
config.Password = values[EnvPassword]
return NewDNSProviderConfig(config)
}
// NewDNSProviderConfig return a DNSProvider instance configured for ultradns.
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
if config == nil {
return nil, errors.New("ultradns: the configuration of the DNS provider is nil")
}
ultraConfig := client.Config{
Username: config.Username,
Password: config.Password,
HostURL: config.Endpoint,
UserAgent: defaultUserAgent,
}
uClient, err := client.NewClient(ultraConfig)
if err != nil {
return nil, fmt.Errorf("ultradns: %w", err)
}
return &DNSProvider{config: config, client: uClient}, nil
}
// Timeout returns the timeout and interval to use when checking for DNS propagation.
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval
}
// Present creates a TXT record using the specified parameters.
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth)
authZone, err := dns01.FindZoneByFqdn(fqdn)
if err != nil {
return fmt.Errorf("ultradns: %w", err)
}
recordService, err := record.Get(d.client)
if err != nil {
return fmt.Errorf("ultradns: %w", err)
}
rrSetKeyData := &rrset.RRSetKey{
Owner: fqdn,
Zone: authZone,
RecordType: "TXT",
}
res, _, _ := recordService.Read(rrSetKeyData)
rrSetData := &rrset.RRSet{
OwnerName: fqdn,
TTL: d.config.TTL,
RRType: "TXT",
RData: []string{value},
}
if res != nil && res.StatusCode == 200 {
_, err = recordService.Update(rrSetKeyData, rrSetData)
} else {
_, err = recordService.Create(rrSetKeyData, rrSetData)
}
if err != nil {
return fmt.Errorf("ultradns: %w", err)
}
return nil
}
// CleanUp removes the TXT record matching the specified parameters.
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
fqdn, _ := dns01.GetRecord(domain, keyAuth)
authZone, err := dns01.FindZoneByFqdn(fqdn)
if err != nil {
return fmt.Errorf("ultradns: %w", err)
}
recordService, err := record.Get(d.client)
if err != nil {
return fmt.Errorf("ultradns: %w", err)
}
rrSetKeyData := &rrset.RRSetKey{
Owner: fqdn,
Zone: authZone,
RecordType: "TXT",
}
_, err = recordService.Delete(rrSetKeyData)
if err != nil {
return fmt.Errorf("ultradns: %w", err)
}
return nil
}

View file

@ -0,0 +1,25 @@
Name = "Ultradns"
Description = ''''''
URL = "https://neustarsecurityservices.com/dns-services"
Code = "ultradns"
Since = "v4.10.0"
Example = '''
ULTRADNS_USERNAME=username \
ULTRADNS_PASSWORD=password \
lego --email you@example.com --dns ultradns --domains my.example.org run
'''
[Configuration]
[Configuration.Credentials]
ULTRADNS_USERNAME = "API Username"
ULTRADNS_PASSWORD = "API Password"
[Configuration.Additional]
ULTRADNS_ENDPOINT = "API endpoint URL, defaults to https://api.ultradns.com/"
ULTRADNS_TTL = "The TTL of the TXT record used for the DNS challenge"
ULTRADNS_POLLING_INTERVAL = "Time between DNS propagation check"
ULTRADNS_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation"
[Links]
API = "https://ultra-portalstatic.ultradns.com/static/docs/REST-API_User_Guide.pdf"
GoClient = "https://github.com/ultradns/ultradns-go-sdk"

View file

@ -0,0 +1,198 @@
package ultradns
import (
"testing"
"time"
"github.com/go-acme/lego/v4/platform/tester"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const envDomain = envNamespace + "DOMAIN"
var envTest = tester.NewEnvTest(
EnvUsername,
EnvPassword,
EnvEndpoint,
EnvTTL,
EnvPropagationTimeout,
EnvPollingInterval).
WithDomain(envDomain)
func TestNewDefaultConfig(t *testing.T) {
defer envTest.RestoreEnv()
testCases := []struct {
desc string
envVars map[string]string
expected *Config
}{
{
desc: "default configuration",
expected: &Config{
Endpoint: "https://api.ultradns.com/",
TTL: 120,
PropagationTimeout: 2 * time.Minute,
PollingInterval: 4 * time.Second,
},
},
{
desc: "input configuration",
envVars: map[string]string{
EnvEndpoint: "https://example.com/",
EnvTTL: "99",
EnvPropagationTimeout: "60",
EnvPollingInterval: "60",
},
expected: &Config{
Endpoint: "https://example.com/",
TTL: 99,
PropagationTimeout: 60 * time.Second,
PollingInterval: 60 * time.Second,
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
envTest.ClearEnv()
envTest.Apply(test.envVars)
config := NewDefaultConfig()
assert.Equal(t, test.expected, config)
})
}
}
func TestNewDNSProvider(t *testing.T) {
defer envTest.RestoreEnv()
testCases := []struct {
desc string
envVars map[string]string
expected string
}{
{
desc: "missing username and password",
expected: "ultradns: some credentials information are missing: ULTRADNS_USERNAME,ULTRADNS_PASSWORD",
},
{
desc: "missing username",
envVars: map[string]string{
EnvPassword: "password",
},
expected: "ultradns: some credentials information are missing: ULTRADNS_USERNAME",
},
{
desc: "missing password",
envVars: map[string]string{
EnvUsername: "username",
},
expected: "ultradns: some credentials information are missing: ULTRADNS_PASSWORD",
},
{
desc: "success",
envVars: map[string]string{
EnvUsername: "username",
EnvPassword: "password",
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
envTest.ClearEnv()
envTest.Apply(test.envVars)
p, err := NewDNSProvider()
if test.expected == "" {
require.NoError(t, err)
require.NotNil(t, p)
assert.NotNil(t, p.config)
assert.NotNil(t, p.client)
} else {
require.EqualError(t, err, test.expected)
}
})
}
}
func TestNewDNSProviderConfig(t *testing.T) {
testCases := []struct {
desc string
username string
password string
expected string
}{
{
desc: "success",
username: "api_username",
password: "api_password",
},
{
desc: "missing credentials",
expected: "ultradns: config validation failure: username is missing",
},
{
desc: "missing username",
username: "",
password: "api_password",
expected: "ultradns: config validation failure: username is missing",
},
{
desc: "missing password",
username: "api_username",
password: "",
expected: "ultradns: config validation failure: password is missing",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
config := NewDefaultConfig()
config.Username = test.username
config.Password = test.password
p, err := NewDNSProviderConfig(config)
if test.expected == "" {
require.NoError(t, err)
require.NotNil(t, p)
require.NotNil(t, p.config)
} else {
require.EqualError(t, err, test.expected)
}
})
}
}
func TestLivePresent(t *testing.T) {
if !envTest.IsLiveTest() {
t.Skip("skipping live test")
}
envTest.RestoreEnv()
provider, err := NewDNSProvider()
require.NoError(t, err)
err = provider.Present(envTest.GetDomain(), "", "123d==")
require.NoError(t, err)
}
func TestLiveCleanUp(t *testing.T) {
if !envTest.IsLiveTest() {
t.Skip("skipping live test")
}
envTest.RestoreEnv()
provider, err := NewDNSProvider()
require.NoError(t, err)
err = provider.CleanUp(envTest.GetDomain(), "", "123d==")
require.NoError(t, err)
}