forked from TrueCloudLab/lego
Add DNS provider for all-inkl (#1444)
This commit is contained in:
parent
2a194d6ab9
commit
43779d7533
22 changed files with 1608 additions and 24 deletions
46
README.md
46
README.md
|
@ -46,29 +46,29 @@ Detailed documentation is available [here](https://go-acme.github.io/lego/dns).
|
||||||
|
|
||||||
| | | | |
|
| | | | |
|
||||||
|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|
|
|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|
|
||||||
| [Akamai EdgeDNS](https://go-acme.github.io/lego/dns/edgedns/) | [Alibaba Cloud DNS](https://go-acme.github.io/lego/dns/alidns/) | [Amazon Lightsail](https://go-acme.github.io/lego/dns/lightsail/) | [Amazon Route 53](https://go-acme.github.io/lego/dns/route53/) |
|
| [Akamai EdgeDNS](https://go-acme.github.io/lego/dns/edgedns/) | [Alibaba Cloud DNS](https://go-acme.github.io/lego/dns/alidns/) | [all-inkl](https://go-acme.github.io/lego/dns/allinkl/) | [Amazon Lightsail](https://go-acme.github.io/lego/dns/lightsail/) |
|
||||||
| [ArvanCloud](https://go-acme.github.io/lego/dns/arvancloud/) | [Aurora DNS](https://go-acme.github.io/lego/dns/auroradns/) | [Autodns](https://go-acme.github.io/lego/dns/autodns/) | [Azure](https://go-acme.github.io/lego/dns/azure/) |
|
| [Amazon Route 53](https://go-acme.github.io/lego/dns/route53/) | [ArvanCloud](https://go-acme.github.io/lego/dns/arvancloud/) | [Aurora DNS](https://go-acme.github.io/lego/dns/auroradns/) | [Autodns](https://go-acme.github.io/lego/dns/autodns/) |
|
||||||
| [Bindman](https://go-acme.github.io/lego/dns/bindman/) | [Bluecat](https://go-acme.github.io/lego/dns/bluecat/) | [Checkdomain](https://go-acme.github.io/lego/dns/checkdomain/) | [CloudDNS](https://go-acme.github.io/lego/dns/clouddns/) |
|
| [Azure](https://go-acme.github.io/lego/dns/azure/) | [Bindman](https://go-acme.github.io/lego/dns/bindman/) | [Bluecat](https://go-acme.github.io/lego/dns/bluecat/) | [Checkdomain](https://go-acme.github.io/lego/dns/checkdomain/) |
|
||||||
| [Cloudflare](https://go-acme.github.io/lego/dns/cloudflare/) | [ClouDNS](https://go-acme.github.io/lego/dns/cloudns/) | [CloudXNS](https://go-acme.github.io/lego/dns/cloudxns/) | [ConoHa](https://go-acme.github.io/lego/dns/conoha/) |
|
| [CloudDNS](https://go-acme.github.io/lego/dns/clouddns/) | [Cloudflare](https://go-acme.github.io/lego/dns/cloudflare/) | [ClouDNS](https://go-acme.github.io/lego/dns/cloudns/) | [CloudXNS](https://go-acme.github.io/lego/dns/cloudxns/) |
|
||||||
| [Constellix](https://go-acme.github.io/lego/dns/constellix/) | [deSEC.io](https://go-acme.github.io/lego/dns/desec/) | [Designate DNSaaS for Openstack](https://go-acme.github.io/lego/dns/designate/) | [Digital Ocean](https://go-acme.github.io/lego/dns/digitalocean/) |
|
| [ConoHa](https://go-acme.github.io/lego/dns/conoha/) | [Constellix](https://go-acme.github.io/lego/dns/constellix/) | [deSEC.io](https://go-acme.github.io/lego/dns/desec/) | [Designate DNSaaS for Openstack](https://go-acme.github.io/lego/dns/designate/) |
|
||||||
| [DNS Made Easy](https://go-acme.github.io/lego/dns/dnsmadeeasy/) | [DNSimple](https://go-acme.github.io/lego/dns/dnsimple/) | [DNSPod](https://go-acme.github.io/lego/dns/dnspod/) | [Domain Offensive (do.de)](https://go-acme.github.io/lego/dns/dode/) |
|
| [Digital Ocean](https://go-acme.github.io/lego/dns/digitalocean/) | [DNS Made Easy](https://go-acme.github.io/lego/dns/dnsmadeeasy/) | [DNSimple](https://go-acme.github.io/lego/dns/dnsimple/) | [DNSPod](https://go-acme.github.io/lego/dns/dnspod/) |
|
||||||
| [Domeneshop](https://go-acme.github.io/lego/dns/domeneshop/) | [DreamHost](https://go-acme.github.io/lego/dns/dreamhost/) | [Duck DNS](https://go-acme.github.io/lego/dns/duckdns/) | [Dyn](https://go-acme.github.io/lego/dns/dyn/) |
|
| [Domain Offensive (do.de)](https://go-acme.github.io/lego/dns/dode/) | [Domeneshop](https://go-acme.github.io/lego/dns/domeneshop/) | [DreamHost](https://go-acme.github.io/lego/dns/dreamhost/) | [Duck DNS](https://go-acme.github.io/lego/dns/duckdns/) |
|
||||||
| [Dynu](https://go-acme.github.io/lego/dns/dynu/) | [EasyDNS](https://go-acme.github.io/lego/dns/easydns/) | [Exoscale](https://go-acme.github.io/lego/dns/exoscale/) | [External program](https://go-acme.github.io/lego/dns/exec/) |
|
| [Dyn](https://go-acme.github.io/lego/dns/dyn/) | [Dynu](https://go-acme.github.io/lego/dns/dynu/) | [EasyDNS](https://go-acme.github.io/lego/dns/easydns/) | [Exoscale](https://go-acme.github.io/lego/dns/exoscale/) |
|
||||||
| [Gandi Live DNS (v5)](https://go-acme.github.io/lego/dns/gandiv5/) | [Gandi](https://go-acme.github.io/lego/dns/gandi/) | [Glesys](https://go-acme.github.io/lego/dns/glesys/) | [Go Daddy](https://go-acme.github.io/lego/dns/godaddy/) |
|
| [External program](https://go-acme.github.io/lego/dns/exec/) | [Gandi Live DNS (v5)](https://go-acme.github.io/lego/dns/gandiv5/) | [Gandi](https://go-acme.github.io/lego/dns/gandi/) | [Glesys](https://go-acme.github.io/lego/dns/glesys/) |
|
||||||
| [Google Cloud](https://go-acme.github.io/lego/dns/gcloud/) | [Hetzner](https://go-acme.github.io/lego/dns/hetzner/) | [Hosting.de](https://go-acme.github.io/lego/dns/hostingde/) | [HTTP request](https://go-acme.github.io/lego/dns/httpreq/) |
|
| [Go Daddy](https://go-acme.github.io/lego/dns/godaddy/) | [Google Cloud](https://go-acme.github.io/lego/dns/gcloud/) | [Hetzner](https://go-acme.github.io/lego/dns/hetzner/) | [Hosting.de](https://go-acme.github.io/lego/dns/hostingde/) |
|
||||||
| [Hurricane Electric DNS](https://go-acme.github.io/lego/dns/hurricane/) | [HyperOne](https://go-acme.github.io/lego/dns/hyperone/) | [Infoblox](https://go-acme.github.io/lego/dns/infoblox/) | [Infomaniak](https://go-acme.github.io/lego/dns/infomaniak/) |
|
| [HTTP request](https://go-acme.github.io/lego/dns/httpreq/) | [Hurricane Electric DNS](https://go-acme.github.io/lego/dns/hurricane/) | [HyperOne](https://go-acme.github.io/lego/dns/hyperone/) | [Infoblox](https://go-acme.github.io/lego/dns/infoblox/) |
|
||||||
| [Internet Initiative Japan](https://go-acme.github.io/lego/dns/iij/) | [Internet.bs](https://go-acme.github.io/lego/dns/internetbs/) | [INWX](https://go-acme.github.io/lego/dns/inwx/) | [Ionos](https://go-acme.github.io/lego/dns/ionos/) |
|
| [Infomaniak](https://go-acme.github.io/lego/dns/infomaniak/) | [Internet Initiative Japan](https://go-acme.github.io/lego/dns/iij/) | [Internet.bs](https://go-acme.github.io/lego/dns/internetbs/) | [INWX](https://go-acme.github.io/lego/dns/inwx/) |
|
||||||
| [Joker](https://go-acme.github.io/lego/dns/joker/) | [Joohoi's ACME-DNS](https://go-acme.github.io/lego/dns/acme-dns/) | [Linode (v4)](https://go-acme.github.io/lego/dns/linode/) | [Liquid Web](https://go-acme.github.io/lego/dns/liquidweb/) |
|
| [Ionos](https://go-acme.github.io/lego/dns/ionos/) | [Joker](https://go-acme.github.io/lego/dns/joker/) | [Joohoi's ACME-DNS](https://go-acme.github.io/lego/dns/acme-dns/) | [Linode (v4)](https://go-acme.github.io/lego/dns/linode/) |
|
||||||
| [Loopia](https://go-acme.github.io/lego/dns/loopia/) | [LuaDNS](https://go-acme.github.io/lego/dns/luadns/) | [Manual](https://go-acme.github.io/lego/dns/manual/) | [MyDNS.jp](https://go-acme.github.io/lego/dns/mydnsjp/) |
|
| [Liquid Web](https://go-acme.github.io/lego/dns/liquidweb/) | [Loopia](https://go-acme.github.io/lego/dns/loopia/) | [LuaDNS](https://go-acme.github.io/lego/dns/luadns/) | [Manual](https://go-acme.github.io/lego/dns/manual/) |
|
||||||
| [MythicBeasts](https://go-acme.github.io/lego/dns/mythicbeasts/) | [Name.com](https://go-acme.github.io/lego/dns/namedotcom/) | [Namecheap](https://go-acme.github.io/lego/dns/namecheap/) | [Namesilo](https://go-acme.github.io/lego/dns/namesilo/) |
|
| [MyDNS.jp](https://go-acme.github.io/lego/dns/mydnsjp/) | [MythicBeasts](https://go-acme.github.io/lego/dns/mythicbeasts/) | [Name.com](https://go-acme.github.io/lego/dns/namedotcom/) | [Namecheap](https://go-acme.github.io/lego/dns/namecheap/) |
|
||||||
| [Netcup](https://go-acme.github.io/lego/dns/netcup/) | [Netlify](https://go-acme.github.io/lego/dns/netlify/) | [NIFCloud](https://go-acme.github.io/lego/dns/nifcloud/) | [Njalla](https://go-acme.github.io/lego/dns/njalla/) |
|
| [Namesilo](https://go-acme.github.io/lego/dns/namesilo/) | [Netcup](https://go-acme.github.io/lego/dns/netcup/) | [Netlify](https://go-acme.github.io/lego/dns/netlify/) | [NIFCloud](https://go-acme.github.io/lego/dns/nifcloud/) |
|
||||||
| [NS1](https://go-acme.github.io/lego/dns/ns1/) | [Open Telekom Cloud](https://go-acme.github.io/lego/dns/otc/) | [Oracle Cloud](https://go-acme.github.io/lego/dns/oraclecloud/) | [OVH](https://go-acme.github.io/lego/dns/ovh/) |
|
| [Njalla](https://go-acme.github.io/lego/dns/njalla/) | [NS1](https://go-acme.github.io/lego/dns/ns1/) | [Open Telekom Cloud](https://go-acme.github.io/lego/dns/otc/) | [Oracle Cloud](https://go-acme.github.io/lego/dns/oraclecloud/) |
|
||||||
| [Porkbun](https://go-acme.github.io/lego/dns/porkbun/) | [PowerDNS](https://go-acme.github.io/lego/dns/pdns/) | [Rackspace](https://go-acme.github.io/lego/dns/rackspace/) | [reg.ru](https://go-acme.github.io/lego/dns/regru/) |
|
| [OVH](https://go-acme.github.io/lego/dns/ovh/) | [Porkbun](https://go-acme.github.io/lego/dns/porkbun/) | [PowerDNS](https://go-acme.github.io/lego/dns/pdns/) | [Rackspace](https://go-acme.github.io/lego/dns/rackspace/) |
|
||||||
| [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/) |
|
| [reg.ru](https://go-acme.github.io/lego/dns/regru/) | [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/) |
|
||||||
| [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/) |
|
| [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/) |
|
||||||
| [Stackpath](https://go-acme.github.io/lego/dns/stackpath/) | [TransIP](https://go-acme.github.io/lego/dns/transip/) | [VegaDNS](https://go-acme.github.io/lego/dns/vegadns/) | [Versio.[nl/eu/uk]](https://go-acme.github.io/lego/dns/versio/) |
|
| [Sonic](https://go-acme.github.io/lego/dns/sonic/) | [Stackpath](https://go-acme.github.io/lego/dns/stackpath/) | [TransIP](https://go-acme.github.io/lego/dns/transip/) | [VegaDNS](https://go-acme.github.io/lego/dns/vegadns/) |
|
||||||
| [VinylDNS](https://go-acme.github.io/lego/dns/vinyldns/) | [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/) |
|
| [Versio.[nl/eu/uk]](https://go-acme.github.io/lego/dns/versio/) | [VinylDNS](https://go-acme.github.io/lego/dns/vinyldns/) | [Vscale](https://go-acme.github.io/lego/dns/vscale/) | [Vultr](https://go-acme.github.io/lego/dns/vultr/) |
|
||||||
| [Yandex](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/) | |
|
| [WEDOS](https://go-acme.github.io/lego/dns/wedos/) | [Yandex](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 -->
|
<!-- END DNS PROVIDERS LIST -->
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ func allDNSCodes() string {
|
||||||
"manual",
|
"manual",
|
||||||
"acme-dns",
|
"acme-dns",
|
||||||
"alidns",
|
"alidns",
|
||||||
|
"allinkl",
|
||||||
"arvancloud",
|
"arvancloud",
|
||||||
"auroradns",
|
"auroradns",
|
||||||
"autodns",
|
"autodns",
|
||||||
|
@ -150,6 +151,26 @@ func displayDNSHelp(name string) error {
|
||||||
ew.writeln()
|
ew.writeln()
|
||||||
ew.writeln(`More information: https://go-acme.github.io/lego/dns/alidns`)
|
ew.writeln(`More information: https://go-acme.github.io/lego/dns/alidns`)
|
||||||
|
|
||||||
|
case "allinkl":
|
||||||
|
// generated from: providers/dns/allinkl/allinkl.toml
|
||||||
|
ew.writeln(`Configuration for all-inkl.`)
|
||||||
|
ew.writeln(`Code: 'allinkl'`)
|
||||||
|
ew.writeln(`Since: 'v4.5.0'`)
|
||||||
|
ew.writeln()
|
||||||
|
|
||||||
|
ew.writeln(`Credentials:`)
|
||||||
|
ew.writeln(` - "ALL_INKL_API_KEY": API login`)
|
||||||
|
ew.writeln(` - "ALL_INKL_PASSWORD": API password`)
|
||||||
|
ew.writeln()
|
||||||
|
|
||||||
|
ew.writeln(`Additional Configuration:`)
|
||||||
|
ew.writeln(` - "ALL_INKL_HTTP_TIMEOUT": API request timeout`)
|
||||||
|
ew.writeln(` - "ALL_INKL_POLLING_INTERVAL": Time between DNS propagation check`)
|
||||||
|
ew.writeln(` - "ALL_INKL_PROPAGATION_TIMEOUT": Maximum waiting time for DNS propagation`)
|
||||||
|
|
||||||
|
ew.writeln()
|
||||||
|
ew.writeln(`More information: https://go-acme.github.io/lego/dns/allinkl`)
|
||||||
|
|
||||||
case "arvancloud":
|
case "arvancloud":
|
||||||
// generated from: providers/dns/arvancloud/arvancloud.toml
|
// generated from: providers/dns/arvancloud/arvancloud.toml
|
||||||
ew.writeln(`Configuration for ArvanCloud.`)
|
ew.writeln(`Configuration for ArvanCloud.`)
|
||||||
|
|
63
docs/content/dns/zz_gen_allinkl.md
Normal file
63
docs/content/dns/zz_gen_allinkl.md
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
---
|
||||||
|
title: "all-inkl"
|
||||||
|
date: 2019-03-03T16:39:46+01:00
|
||||||
|
draft: false
|
||||||
|
slug: allinkl
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
|
||||||
|
<!-- providers/dns/allinkl/allinkl.toml -->
|
||||||
|
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
|
||||||
|
|
||||||
|
Since: v4.5.0
|
||||||
|
|
||||||
|
Configuration for [all-inkl](https://all-inkl.com).
|
||||||
|
|
||||||
|
|
||||||
|
<!--more-->
|
||||||
|
|
||||||
|
- Code: `allinkl`
|
||||||
|
|
||||||
|
Here is an example bash command using the all-inkl provider:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ALL_INKL_LOGIN=xxxxxxxxxxxxxxxxxxxxxxxxxx \
|
||||||
|
ALL_INKL_PASSWORD=yyyyyyyyyyyyyyyyyyyyyyyyyy \
|
||||||
|
lego --email myemail@example.com --dns allinkl --domains my.example.org run
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Credentials
|
||||||
|
|
||||||
|
| Environment Variable Name | Description |
|
||||||
|
|-----------------------|-------------|
|
||||||
|
| `ALL_INKL_API_KEY` | API login |
|
||||||
|
| `ALL_INKL_PASSWORD` | API password |
|
||||||
|
|
||||||
|
The environment variable names can be suffixed by `_FILE` to reference a file instead of a value.
|
||||||
|
More information [here](/lego/dns/#configuration-and-credentials).
|
||||||
|
|
||||||
|
|
||||||
|
## Additional Configuration
|
||||||
|
|
||||||
|
| Environment Variable Name | Description |
|
||||||
|
|--------------------------------|-------------|
|
||||||
|
| `ALL_INKL_HTTP_TIMEOUT` | API request timeout |
|
||||||
|
| `ALL_INKL_POLLING_INTERVAL` | Time between DNS propagation check |
|
||||||
|
| `ALL_INKL_PROPAGATION_TIMEOUT` | Maximum waiting time for DNS propagation |
|
||||||
|
|
||||||
|
The environment variable names can be suffixed by `_FILE` to reference a file instead of a value.
|
||||||
|
More information [here](/lego/dns/#configuration-and-credentials).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## More information
|
||||||
|
|
||||||
|
- [API documentation](https://kasapi.kasserver.com/dokumentation/phpdoc/index.html)
|
||||||
|
|
||||||
|
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
|
||||||
|
<!-- providers/dns/allinkl/allinkl.toml -->
|
||||||
|
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
|
1
go.mod
1
go.mod
|
@ -31,6 +31,7 @@ require (
|
||||||
github.com/linode/linodego v0.25.3
|
github.com/linode/linodego v0.25.3
|
||||||
github.com/liquidweb/liquidweb-go v1.6.3
|
github.com/liquidweb/liquidweb-go v1.6.3
|
||||||
github.com/miekg/dns v1.1.40
|
github.com/miekg/dns v1.1.40
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1
|
||||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04
|
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04
|
||||||
github.com/nrdcg/auroradns v1.0.1
|
github.com/nrdcg/auroradns v1.0.1
|
||||||
github.com/nrdcg/desec v0.5.0
|
github.com/nrdcg/desec v0.5.0
|
||||||
|
|
3
go.sum
3
go.sum
|
@ -324,8 +324,9 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
|
||||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
|
|
||||||
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
|
161
providers/dns/allinkl/allinkl.go
Normal file
161
providers/dns/allinkl/allinkl.go
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
// Package allinkl implements a DNS provider for solving the DNS-01 challenge using all-inkl.
|
||||||
|
package allinkl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-acme/lego/v4/challenge/dns01"
|
||||||
|
"github.com/go-acme/lego/v4/platform/config/env"
|
||||||
|
"github.com/go-acme/lego/v4/providers/dns/allinkl/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Environment variables names.
|
||||||
|
const (
|
||||||
|
envNamespace = "ALL_INKL_"
|
||||||
|
|
||||||
|
EnvLogin = envNamespace + "LOGIN"
|
||||||
|
EnvPassword = envNamespace + "PASSWORD"
|
||||||
|
|
||||||
|
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
|
||||||
|
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
|
||||||
|
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config is used to configure the creation of the DNSProvider.
|
||||||
|
type Config struct {
|
||||||
|
Login string
|
||||||
|
Password string
|
||||||
|
PropagationTimeout time.Duration
|
||||||
|
PollingInterval time.Duration
|
||||||
|
TTL int
|
||||||
|
HTTPClient *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDefaultConfig returns a default configuration for the DNSProvider.
|
||||||
|
func NewDefaultConfig() *Config {
|
||||||
|
return &Config{
|
||||||
|
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, dns01.DefaultPropagationTimeout),
|
||||||
|
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
|
||||||
|
HTTPClient: &http.Client{
|
||||||
|
Timeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSProvider implements the challenge.Provider interface.
|
||||||
|
type DNSProvider struct {
|
||||||
|
config *Config
|
||||||
|
client *internal.Client
|
||||||
|
|
||||||
|
recordIDs map[string]string
|
||||||
|
recordIDsMu sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProvider returns a DNSProvider instance configured for all-inkl.
|
||||||
|
// Credentials must be passed in the environment variable: ALL_INKL_API_KEY, ALL_INKL_PASSWORD.
|
||||||
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
|
values, err := env.Get(EnvLogin, EnvPassword)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("allinkl: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config := NewDefaultConfig()
|
||||||
|
config.Login = values[EnvLogin]
|
||||||
|
config.Password = values[EnvPassword]
|
||||||
|
|
||||||
|
return NewDNSProviderConfig(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProviderConfig return a DNSProvider instance configured for all-inkl.
|
||||||
|
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
|
if config == nil {
|
||||||
|
return nil, errors.New("allinkl: the configuration of the DNS provider is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Login == "" || config.Password == "" {
|
||||||
|
return nil, errors.New("allinkl: missing credentials")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := internal.NewClient(config.Login, config.Password)
|
||||||
|
|
||||||
|
if config.HTTPClient != nil {
|
||||||
|
client.HTTPClient = config.HTTPClient
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DNSProvider{
|
||||||
|
config: config,
|
||||||
|
client: client,
|
||||||
|
recordIDs: make(map[string]string),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timeout returns the timeout and interval to use when checking for DNS propagation.
|
||||||
|
// Adjusting here to cope with spikes in propagation times.
|
||||||
|
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("allinkl: could not determine zone for domain %q: %w", domain, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
credential, err := d.client.Authentication(60, true)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("allinkl: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
subDomain := dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone))
|
||||||
|
|
||||||
|
record := internal.DNSRequest{
|
||||||
|
ZoneHost: authZone,
|
||||||
|
RecordType: "TXT",
|
||||||
|
RecordName: subDomain,
|
||||||
|
RecordData: value,
|
||||||
|
}
|
||||||
|
|
||||||
|
recordID, err := d.client.AddDNSSettings(credential, record)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("allinkl: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.recordIDsMu.Lock()
|
||||||
|
d.recordIDs[token] = recordID
|
||||||
|
d.recordIDsMu.Unlock()
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
credential, err := d.client.Authentication(60, true)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("allinkl: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// gets the record's unique ID from when we created it
|
||||||
|
d.recordIDsMu.Lock()
|
||||||
|
recordID, ok := d.recordIDs[token]
|
||||||
|
d.recordIDsMu.Unlock()
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("allinkl: unknown record ID for '%s' '%s'", fqdn, token)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = d.client.DeleteDNSSettings(credential, recordID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("allinkl: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
24
providers/dns/allinkl/allinkl.toml
Normal file
24
providers/dns/allinkl/allinkl.toml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
Name = "all-inkl"
|
||||||
|
Description = ''''''
|
||||||
|
URL = "https://all-inkl.com"
|
||||||
|
Code = "allinkl"
|
||||||
|
Since = "v4.5.0"
|
||||||
|
|
||||||
|
Example = '''
|
||||||
|
ALL_INKL_LOGIN=xxxxxxxxxxxxxxxxxxxxxxxxxx \
|
||||||
|
ALL_INKL_PASSWORD=yyyyyyyyyyyyyyyyyyyyyyyyyy \
|
||||||
|
lego --email myemail@example.com --dns allinkl --domains my.example.org run
|
||||||
|
'''
|
||||||
|
|
||||||
|
[Configuration]
|
||||||
|
[Configuration.Credentials]
|
||||||
|
ALL_INKL_API_KEY = "API login"
|
||||||
|
ALL_INKL_PASSWORD = "API password"
|
||||||
|
[Configuration.Additional]
|
||||||
|
ALL_INKL_POLLING_INTERVAL = "Time between DNS propagation check"
|
||||||
|
ALL_INKL_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation"
|
||||||
|
ALL_INKL_HTTP_TIMEOUT = "API request timeout"
|
||||||
|
|
||||||
|
[Links]
|
||||||
|
API = "https://kasapi.kasserver.com/dokumentation/phpdoc/index.html"
|
||||||
|
Guide = "https://kasapi.kasserver.com/dokumentation/"
|
142
providers/dns/allinkl/allinkl_test.go
Normal file
142
providers/dns/allinkl/allinkl_test.go
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
package allinkl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/go-acme/lego/v4/platform/tester"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
const envDomain = envNamespace + "DOMAIN"
|
||||||
|
|
||||||
|
var envTest = tester.NewEnvTest(EnvLogin, EnvPassword).WithDomain(envDomain)
|
||||||
|
|
||||||
|
func TestNewDNSProvider(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
envVars map[string]string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "success",
|
||||||
|
envVars: map[string]string{
|
||||||
|
EnvLogin: "user",
|
||||||
|
EnvPassword: "secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing credentials: account name",
|
||||||
|
envVars: map[string]string{
|
||||||
|
EnvLogin: "",
|
||||||
|
EnvPassword: "secret",
|
||||||
|
},
|
||||||
|
expected: "allinkl: some credentials information are missing: ALL_INKL_LOGIN",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing credentials: api key",
|
||||||
|
envVars: map[string]string{
|
||||||
|
EnvLogin: "user",
|
||||||
|
EnvPassword: "",
|
||||||
|
},
|
||||||
|
expected: "allinkl: some credentials information are missing: ALL_INKL_PASSWORD",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing credentials: all",
|
||||||
|
envVars: map[string]string{
|
||||||
|
EnvLogin: "",
|
||||||
|
EnvPassword: "",
|
||||||
|
},
|
||||||
|
expected: "allinkl: some credentials information are missing: ALL_INKL_LOGIN,ALL_INKL_PASSWORD",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
defer envTest.RestoreEnv()
|
||||||
|
envTest.ClearEnv()
|
||||||
|
|
||||||
|
envTest.Apply(test.envVars)
|
||||||
|
|
||||||
|
p, err := NewDNSProvider()
|
||||||
|
|
||||||
|
if test.expected == "" {
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, p)
|
||||||
|
require.NotNil(t, p.config)
|
||||||
|
require.NotNil(t, p.client)
|
||||||
|
} else {
|
||||||
|
require.EqualError(t, err, test.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewDNSProviderConfig(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
login string
|
||||||
|
password string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "success",
|
||||||
|
login: "user",
|
||||||
|
password: "secret",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing account name",
|
||||||
|
password: "secret",
|
||||||
|
expected: "allinkl: missing credentials",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing api key",
|
||||||
|
login: "user",
|
||||||
|
expected: "allinkl: missing credentials",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
config := NewDefaultConfig()
|
||||||
|
config.Login = test.login
|
||||||
|
config.Password = test.password
|
||||||
|
|
||||||
|
p, err := NewDNSProviderConfig(config)
|
||||||
|
|
||||||
|
if test.expected == "" {
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, p)
|
||||||
|
require.NotNil(t, p.config)
|
||||||
|
require.NotNil(t, p.client)
|
||||||
|
} 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)
|
||||||
|
}
|
286
providers/dns/allinkl/internal/client.go
Normal file
286
providers/dns/allinkl/internal/client.go
Normal file
|
@ -0,0 +1,286 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
authEndpoint = "https://kasapi.kasserver.com/soap/KasAuth.php"
|
||||||
|
apiEndpoint = "https://kasapi.kasserver.com/soap/KasApi.php"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Client a KAS server client.
|
||||||
|
type Client struct {
|
||||||
|
login string
|
||||||
|
password string
|
||||||
|
|
||||||
|
authEndpoint string
|
||||||
|
apiEndpoint string
|
||||||
|
HTTPClient *http.Client
|
||||||
|
floodTime time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient creates a new Client.
|
||||||
|
func NewClient(login string, password string) *Client {
|
||||||
|
return &Client{
|
||||||
|
login: login,
|
||||||
|
password: password,
|
||||||
|
authEndpoint: authEndpoint,
|
||||||
|
apiEndpoint: apiEndpoint,
|
||||||
|
HTTPClient: &http.Client{Timeout: 10 * time.Second},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authentication Creates a credential token.
|
||||||
|
// - sessionLifetime: Validity of the token in seconds.
|
||||||
|
// - sessionUpdateLifetime: with `true` the session is extended with every request.
|
||||||
|
func (c Client) Authentication(sessionLifetime int, sessionUpdateLifetime bool) (string, error) {
|
||||||
|
hash := sha1.New()
|
||||||
|
hash.Write([]byte(c.password))
|
||||||
|
|
||||||
|
sul := "N"
|
||||||
|
if sessionUpdateLifetime {
|
||||||
|
sul = "Y"
|
||||||
|
}
|
||||||
|
|
||||||
|
ar := AuthRequest{
|
||||||
|
Login: c.login,
|
||||||
|
AuthData: fmt.Sprintf("%x", hash.Sum(nil)),
|
||||||
|
AuthType: "sha1",
|
||||||
|
SessionLifetime: sessionLifetime,
|
||||||
|
SessionUpdateLifetime: sul,
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(ar)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("request marshal: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := []byte(strings.TrimSpace(fmt.Sprintf(kasAuthEnvelope, body)))
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, c.authEndpoint, bytes.NewReader(payload))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("request creation: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("request execution: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() { _ = resp.Body.Close() }()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
data, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
return "", fmt.Errorf("invalid status code: %d %s", resp.StatusCode, string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("response read: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var e KasAuthEnvelope
|
||||||
|
decoder := xml.NewTokenDecoder(Trimmer{decoder: xml.NewDecoder(bytes.NewReader(data))})
|
||||||
|
err = decoder.Decode(&e)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("response xml decode: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Body.Fault != nil {
|
||||||
|
return "", e.Body.Fault
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.Body.KasAuthResponse.Return.Text, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDNSSettings Reading out the DNS settings of a zone.
|
||||||
|
// - zone: host zone.
|
||||||
|
// - recordID: the ID of the resource record (optional).
|
||||||
|
func (c *Client) GetDNSSettings(credentialToken, zone, recordID string) ([]ReturnInfo, error) {
|
||||||
|
requestParams := map[string]string{"zone_host": zone}
|
||||||
|
|
||||||
|
if recordID != "" {
|
||||||
|
requestParams["record_id"] = recordID
|
||||||
|
}
|
||||||
|
|
||||||
|
item, err := c.do(credentialToken, "get_dns_settings", requestParams)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
raw := getValue(item)
|
||||||
|
|
||||||
|
var g GetDNSSettingsAPIResponse
|
||||||
|
err = mapstructure.Decode(raw, &g)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("response struct decode: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.updateFloodTime(g.Response.KasFloodDelay)
|
||||||
|
|
||||||
|
return g.Response.ReturnInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddDNSSettings Creation of a DNS resource record.
|
||||||
|
func (c *Client) AddDNSSettings(credentialToken string, record DNSRequest) (string, error) {
|
||||||
|
item, err := c.do(credentialToken, "add_dns_settings", record)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
raw := getValue(item)
|
||||||
|
|
||||||
|
var g AddDNSSettingsAPIResponse
|
||||||
|
err = mapstructure.Decode(raw, &g)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("response struct decode: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.updateFloodTime(g.Response.KasFloodDelay)
|
||||||
|
|
||||||
|
return g.Response.ReturnInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteDNSSettings Deleting a DNS Resource Record.
|
||||||
|
func (c *Client) DeleteDNSSettings(credentialToken, recordID string) (bool, error) {
|
||||||
|
requestParams := map[string]string{"record_id": recordID}
|
||||||
|
|
||||||
|
item, err := c.do(credentialToken, "delete_dns_settings", requestParams)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
raw := getValue(item)
|
||||||
|
|
||||||
|
var g DeleteDNSSettingsAPIResponse
|
||||||
|
err = mapstructure.Decode(raw, &g)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("response struct decode: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.updateFloodTime(g.Response.KasFloodDelay)
|
||||||
|
|
||||||
|
return g.Response.ReturnInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Client) do(credentialToken, action string, requestParams interface{}) (*Item, error) {
|
||||||
|
time.Sleep(time.Until(c.floodTime))
|
||||||
|
|
||||||
|
ar := KasRequest{
|
||||||
|
Login: c.login,
|
||||||
|
AuthType: "session",
|
||||||
|
AuthData: credentialToken,
|
||||||
|
Action: action,
|
||||||
|
RequestParams: requestParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(ar)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("request marshal: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := []byte(strings.TrimSpace(fmt.Sprintf(kasAPIEnvelope, body)))
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, c.apiEndpoint, bytes.NewReader(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("request creation: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("request execution: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() { _ = resp.Body.Close() }()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
data, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
return nil, fmt.Errorf("invalid status code: %d %s", resp.StatusCode, string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("response read: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var e KasAPIResponseEnvelope
|
||||||
|
decoder := xml.NewTokenDecoder(Trimmer{decoder: xml.NewDecoder(bytes.NewReader(data))})
|
||||||
|
err = decoder.Decode(&e)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("response xml decode: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Body.Fault != nil {
|
||||||
|
return nil, e.Body.Fault
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.Body.KasAPIResponse.Return, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) updateFloodTime(delay float64) {
|
||||||
|
c.floodTime = time.Now().Add(time.Duration(delay * float64(time.Second)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getValue(item *Item) interface{} {
|
||||||
|
switch {
|
||||||
|
case item.Raw != "":
|
||||||
|
v, _ := strconv.ParseBool(item.Raw)
|
||||||
|
return v
|
||||||
|
|
||||||
|
case item.Text != "":
|
||||||
|
switch item.Type {
|
||||||
|
case "xsd:string":
|
||||||
|
return item.Text
|
||||||
|
case "xsd:float":
|
||||||
|
v, _ := strconv.ParseFloat(item.Text, 64)
|
||||||
|
return v
|
||||||
|
case "xsd:int":
|
||||||
|
v, _ := strconv.ParseInt(item.Text, 10, 64)
|
||||||
|
return v
|
||||||
|
default:
|
||||||
|
return item.Text
|
||||||
|
}
|
||||||
|
|
||||||
|
case item.Value != nil:
|
||||||
|
return getValue(item.Value)
|
||||||
|
|
||||||
|
case len(item.Items) > 0 && item.Type == "SOAP-ENC:Array":
|
||||||
|
var v []interface{}
|
||||||
|
for _, i := range item.Items {
|
||||||
|
v = append(v, getValue(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
return v
|
||||||
|
|
||||||
|
case len(item.Items) > 0:
|
||||||
|
v := map[string]interface{}{}
|
||||||
|
for _, i := range item.Items {
|
||||||
|
v[getKey(i)] = getValue(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return v
|
||||||
|
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getKey(item *Item) string {
|
||||||
|
if item.Key == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return item.Key.Text
|
||||||
|
}
|
194
providers/dns/allinkl/internal/client_test.go
Normal file
194
providers/dns/allinkl/internal/client_test.go
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClient_Authentication(t *testing.T) {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
server := httptest.NewServer(mux)
|
||||||
|
t.Cleanup(server.Close)
|
||||||
|
|
||||||
|
mux.HandleFunc("/", testHandler("auth.xml"))
|
||||||
|
|
||||||
|
client := NewClient("user", "secret")
|
||||||
|
client.authEndpoint = server.URL
|
||||||
|
|
||||||
|
credentialToken, err := client.Authentication(60, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "593959ca04f0de9689b586c6a647d15d", credentialToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_Authentication_error(t *testing.T) {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
server := httptest.NewServer(mux)
|
||||||
|
t.Cleanup(server.Close)
|
||||||
|
|
||||||
|
mux.HandleFunc("/", testHandler("auth_fault.xml"))
|
||||||
|
|
||||||
|
client := NewClient("user", "secret")
|
||||||
|
client.authEndpoint = server.URL
|
||||||
|
|
||||||
|
_, err := client.Authentication(60, false)
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_GetDNSSettings(t *testing.T) {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
server := httptest.NewServer(mux)
|
||||||
|
t.Cleanup(server.Close)
|
||||||
|
|
||||||
|
mux.HandleFunc("/", testHandler("get_dns_settings.xml"))
|
||||||
|
|
||||||
|
client := NewClient("user", "secret")
|
||||||
|
client.apiEndpoint = server.URL
|
||||||
|
|
||||||
|
token := "sha1secret"
|
||||||
|
|
||||||
|
records, err := client.GetDNSSettings(token, "example.com", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expected := []ReturnInfo{
|
||||||
|
{
|
||||||
|
ID: "57297429",
|
||||||
|
Zone: "example.org",
|
||||||
|
Name: "",
|
||||||
|
Type: "A",
|
||||||
|
Data: "10.0.0.1",
|
||||||
|
Changeable: "Y",
|
||||||
|
Aux: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: int64(0),
|
||||||
|
Zone: "example.org",
|
||||||
|
Name: "",
|
||||||
|
Type: "NS",
|
||||||
|
Data: "ns5.kasserver.com.",
|
||||||
|
Changeable: "N",
|
||||||
|
Aux: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: int64(0),
|
||||||
|
Zone: "example.org",
|
||||||
|
Name: "",
|
||||||
|
Type: "NS",
|
||||||
|
Data: "ns6.kasserver.com.",
|
||||||
|
Changeable: "N",
|
||||||
|
Aux: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "57297479",
|
||||||
|
Zone: "example.org",
|
||||||
|
Name: "*",
|
||||||
|
Type: "A",
|
||||||
|
Data: "10.0.0.1",
|
||||||
|
Changeable: "Y",
|
||||||
|
Aux: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "57297481",
|
||||||
|
Zone: "example.org",
|
||||||
|
Name: "",
|
||||||
|
Type: "MX",
|
||||||
|
Data: "user.kasserver.com.",
|
||||||
|
Changeable: "Y",
|
||||||
|
Aux: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "57297483",
|
||||||
|
Zone: "example.org",
|
||||||
|
Name: "",
|
||||||
|
Type: "TXT",
|
||||||
|
Data: "v=spf1 mx a ?all",
|
||||||
|
Changeable: "Y",
|
||||||
|
Aux: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "57297485",
|
||||||
|
Zone: "example.org",
|
||||||
|
Name: "_dmarc",
|
||||||
|
Type: "TXT",
|
||||||
|
Data: "v=DMARC1; p=none;",
|
||||||
|
Changeable: "Y",
|
||||||
|
Aux: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, expected, records)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_AddDNSSettings(t *testing.T) {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
server := httptest.NewServer(mux)
|
||||||
|
t.Cleanup(server.Close)
|
||||||
|
|
||||||
|
mux.HandleFunc("/", testHandler("add_dns_settings.xml"))
|
||||||
|
|
||||||
|
client := NewClient("user", "secret")
|
||||||
|
client.apiEndpoint = server.URL
|
||||||
|
|
||||||
|
token := "sha1secret"
|
||||||
|
|
||||||
|
record := DNSRequest{
|
||||||
|
ZoneHost: "42cnc.de.",
|
||||||
|
RecordType: "TXT",
|
||||||
|
RecordName: "lego",
|
||||||
|
RecordData: "abcdefgh",
|
||||||
|
}
|
||||||
|
|
||||||
|
recordID, err := client.AddDNSSettings(token, record)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "57347444", recordID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_DeleteDNSSettings(t *testing.T) {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
server := httptest.NewServer(mux)
|
||||||
|
t.Cleanup(server.Close)
|
||||||
|
|
||||||
|
mux.HandleFunc("/", testHandler("delete_dns_settings.xml"))
|
||||||
|
|
||||||
|
client := NewClient("user", "secret")
|
||||||
|
client.apiEndpoint = server.URL
|
||||||
|
|
||||||
|
token := "sha1secret"
|
||||||
|
|
||||||
|
r, err := client.DeleteDNSSettings(token, "57347450")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.True(t, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testHandler(filename string) http.HandlerFunc {
|
||||||
|
return func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
if req.Method != http.MethodPost {
|
||||||
|
http.Error(rw, fmt.Sprintf("unsupported method: %s", req.Method), http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open(filepath.Join("fixtures", filename))
|
||||||
|
if err != nil {
|
||||||
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() { _ = file.Close() }()
|
||||||
|
|
||||||
|
_, err = io.Copy(rw, file)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"Request": {
|
||||||
|
"KasRequestParams": {
|
||||||
|
"record_aux": 0,
|
||||||
|
"record_data": "abcdefgh",
|
||||||
|
"record_name": "lego",
|
||||||
|
"record_type": "TXT",
|
||||||
|
"zone_host": "example.org."
|
||||||
|
},
|
||||||
|
"KasRequestTime": 1625014992,
|
||||||
|
"KasRequestType": true
|
||||||
|
},
|
||||||
|
"Response": {
|
||||||
|
"KasFloodDelay": 0.5,
|
||||||
|
"ReturnInfo": "57347444",
|
||||||
|
"ReturnString": "TRUE"
|
||||||
|
}
|
||||||
|
}
|
68
providers/dns/allinkl/internal/fixtures/add_dns_settings.xml
Normal file
68
providers/dns/allinkl/internal/fixtures/add_dns_settings.xml
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:ns1="https://kasapi.kasserver.com/soap/KasApi.php"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:ns2="http://xml.apache.org/xml-soap"
|
||||||
|
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
|
<SOAP-ENV:Body>
|
||||||
|
<ns1:KasApiResponse>
|
||||||
|
<return xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">Request</key>
|
||||||
|
<value xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasRequestTime</key>
|
||||||
|
<value xsi:type="xsd:int">1625014992</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasRequestType</key>
|
||||||
|
<value xsi:nil="true"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasRequestParams</key>
|
||||||
|
<value xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">zone_host</key>
|
||||||
|
<value xsi:type="xsd:string">example.org.</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_type</key>
|
||||||
|
<value xsi:type="xsd:string">TXT</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_name</key>
|
||||||
|
<value xsi:type="xsd:string">lego</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_data</key>
|
||||||
|
<value xsi:type="xsd:string">abcdefgh</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_aux</key>
|
||||||
|
<value xsi:type="xsd:int">0</value>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">Response</key>
|
||||||
|
<value xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasFloodDelay</key>
|
||||||
|
<value xsi:type="xsd:float">0.5</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">ReturnString</key>
|
||||||
|
<value xsi:type="xsd:string">TRUE</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">ReturnInfo</key>
|
||||||
|
<value xsi:type="xsd:string">57347444</value>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
</return>
|
||||||
|
</ns1:KasApiResponse>
|
||||||
|
</SOAP-ENV:Body>
|
||||||
|
</SOAP-ENV:Envelope>
|
11
providers/dns/allinkl/internal/fixtures/auth.xml
Normal file
11
providers/dns/allinkl/internal/fixtures/auth.xml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:ns1="https://kasapi.kasserver.com/soap/KasAuth.php"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
|
<SOAP-ENV:Body>
|
||||||
|
<ns1:KasAuthResponse>
|
||||||
|
<return xsi:type="xsd:string">593959ca04f0de9689b586c6a647d15d</return>
|
||||||
|
</ns1:KasAuthResponse>
|
||||||
|
</SOAP-ENV:Body>
|
||||||
|
</SOAP-ENV:Envelope>
|
10
providers/dns/allinkl/internal/fixtures/auth_fault.xml
Normal file
10
providers/dns/allinkl/internal/fixtures/auth_fault.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
<SOAP-ENV:Body>
|
||||||
|
<SOAP-ENV:Fault>
|
||||||
|
<faultcode>SOAP-ENV:Client</faultcode>
|
||||||
|
<faultstring>kas_login_syntax_incorrect</faultstring>
|
||||||
|
<faultactor>KasAuth</faultactor>
|
||||||
|
</SOAP-ENV:Fault>
|
||||||
|
</SOAP-ENV:Body>
|
||||||
|
</SOAP-ENV:Envelope>
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"Request": {
|
||||||
|
"KasRequestParams": {
|
||||||
|
"record_id": "57347444"
|
||||||
|
},
|
||||||
|
"KasRequestTime": 1625016066,
|
||||||
|
"KasRequestType": true
|
||||||
|
},
|
||||||
|
"Response": {
|
||||||
|
"KasFloodDelay": 0.5,
|
||||||
|
"ReturnInfo": true,
|
||||||
|
"ReturnString": "TRUE"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:ns1="https://kasapi.kasserver.com/soap/KasApi.php"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:ns2="http://xml.apache.org/xml-soap"
|
||||||
|
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
|
<SOAP-ENV:Body>
|
||||||
|
<ns1:KasApiResponse>
|
||||||
|
<return xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">Request</key>
|
||||||
|
<value xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasRequestTime</key>
|
||||||
|
<value xsi:type="xsd:int">1625016066</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasRequestType</key>
|
||||||
|
<value xsi:nil="true"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasRequestParams</key>
|
||||||
|
<value xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_id</key>
|
||||||
|
<value xsi:type="xsd:string">57347444</value>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">Response</key>
|
||||||
|
<value xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasFloodDelay</key>
|
||||||
|
<value xsi:type="xsd:float">0.5</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">ReturnString</key>
|
||||||
|
<value xsi:type="xsd:string">TRUE</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">ReturnInfo</key>
|
||||||
|
<value xsi:nil="true"/>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
</return>
|
||||||
|
</ns1:KasApiResponse>
|
||||||
|
</SOAP-ENV:Body>
|
||||||
|
</SOAP-ENV:Envelope>
|
|
@ -0,0 +1,78 @@
|
||||||
|
{
|
||||||
|
"Request": {
|
||||||
|
"KasRequestParams": {
|
||||||
|
"zone_host": "example.org"
|
||||||
|
},
|
||||||
|
"KasRequestTime": 1625012975,
|
||||||
|
"KasRequestType": true
|
||||||
|
},
|
||||||
|
"Response": {
|
||||||
|
"KasFloodDelay": 0.5,
|
||||||
|
"ReturnInfo": [
|
||||||
|
{
|
||||||
|
"record_aux": 0,
|
||||||
|
"record_changeable": "Y",
|
||||||
|
"record_data": "10.0.0.1",
|
||||||
|
"record_id": "57297429",
|
||||||
|
"record_name": "",
|
||||||
|
"record_type": "A",
|
||||||
|
"record_zone": "example.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"record_aux": 0,
|
||||||
|
"record_changeable": "N",
|
||||||
|
"record_data": "ns5.kasserver.com.",
|
||||||
|
"record_id": 0,
|
||||||
|
"record_name": "",
|
||||||
|
"record_type": "NS",
|
||||||
|
"record_zone": "example.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"record_aux": 0,
|
||||||
|
"record_changeable": "N",
|
||||||
|
"record_data": "ns6.kasserver.com.",
|
||||||
|
"record_id": 0,
|
||||||
|
"record_name": "",
|
||||||
|
"record_type": "NS",
|
||||||
|
"record_zone": "example.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"record_aux": 0,
|
||||||
|
"record_changeable": "Y",
|
||||||
|
"record_data": "10.0.0.1",
|
||||||
|
"record_id": "57297479",
|
||||||
|
"record_name": "*",
|
||||||
|
"record_type": "A",
|
||||||
|
"record_zone": "example.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"record_aux": 10,
|
||||||
|
"record_changeable": "Y",
|
||||||
|
"record_data": "user.kasserver.com.",
|
||||||
|
"record_id": "57297481",
|
||||||
|
"record_name": "",
|
||||||
|
"record_type": "MX",
|
||||||
|
"record_zone": "example.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"record_aux": 0,
|
||||||
|
"record_changeable": "Y",
|
||||||
|
"record_data": "v=spf1 mx a ?all",
|
||||||
|
"record_id": "57297483",
|
||||||
|
"record_name": "",
|
||||||
|
"record_type": "TXT",
|
||||||
|
"record_zone": "example.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"record_aux": 0,
|
||||||
|
"record_changeable": "Y",
|
||||||
|
"record_data": "v=DMARC1; p=none;",
|
||||||
|
"record_id": "57297485",
|
||||||
|
"record_name": "_dmarc",
|
||||||
|
"record_type": "TXT",
|
||||||
|
"record_zone": "example.org"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ReturnString": "TRUE"
|
||||||
|
}
|
||||||
|
}
|
263
providers/dns/allinkl/internal/fixtures/get_dns_settings.xml
Normal file
263
providers/dns/allinkl/internal/fixtures/get_dns_settings.xml
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:ns1="https://kasapi.kasserver.com/soap/KasApi.php"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
||||||
|
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
|
<SOAP-ENV:Body>
|
||||||
|
<ns1:KasApiResponse>
|
||||||
|
<return xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">Request</key>
|
||||||
|
<value xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasRequestTime</key>
|
||||||
|
<value xsi:type="xsd:int">1624993260</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasRequestType</key>
|
||||||
|
<value xsi:nil="true"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasRequestParams</key>
|
||||||
|
<value xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">zone_host</key>
|
||||||
|
<value xsi:type="xsd:string">example.org</value>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">Response</key>
|
||||||
|
<value xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">KasFloodDelay</key>
|
||||||
|
<value xsi:type="xsd:float">0.5</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">ReturnString</key>
|
||||||
|
<value xsi:type="xsd:string">TRUE</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">ReturnInfo</key>
|
||||||
|
<value SOAP-ENC:arrayType="ns2:Map[7]" xsi:type="SOAP-ENC:Array">
|
||||||
|
<item xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_zone</key>
|
||||||
|
<value xsi:type="xsd:string">example.org</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_name</key>
|
||||||
|
<value xsi:type="xsd:string"></value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_type</key>
|
||||||
|
<value xsi:type="xsd:string">A</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_data</key>
|
||||||
|
<value xsi:type="xsd:string">10.0.0.1</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_aux</key>
|
||||||
|
<value xsi:type="xsd:int">0</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_id</key>
|
||||||
|
<value xsi:type="xsd:string">57297429</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_changeable</key>
|
||||||
|
<value xsi:type="xsd:string">Y</value>
|
||||||
|
</item>
|
||||||
|
</item>
|
||||||
|
<item xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_zone</key>
|
||||||
|
<value xsi:type="xsd:string">example.org</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_name</key>
|
||||||
|
<value xsi:type="xsd:string"></value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_type</key>
|
||||||
|
<value xsi:type="xsd:string">NS</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_data</key>
|
||||||
|
<value xsi:type="xsd:string">ns5.kasserver.com.</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_aux</key>
|
||||||
|
<value xsi:type="xsd:int">0</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_id</key>
|
||||||
|
<value xsi:type="xsd:int">0</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_changeable</key>
|
||||||
|
<value xsi:type="xsd:string">N</value>
|
||||||
|
</item>
|
||||||
|
</item>
|
||||||
|
<item xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_zone</key>
|
||||||
|
<value xsi:type="xsd:string">example.org</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_name</key>
|
||||||
|
<value xsi:type="xsd:string"></value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_type</key>
|
||||||
|
<value xsi:type="xsd:string">NS</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_data</key>
|
||||||
|
<value xsi:type="xsd:string">ns6.kasserver.com.</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_aux</key>
|
||||||
|
<value xsi:type="xsd:int">0</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_id</key>
|
||||||
|
<value xsi:type="xsd:int">0</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_changeable</key>
|
||||||
|
<value xsi:type="xsd:string">N</value>
|
||||||
|
</item>
|
||||||
|
</item>
|
||||||
|
<item xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_zone</key>
|
||||||
|
<value xsi:type="xsd:string">example.org</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_name</key>
|
||||||
|
<value xsi:type="xsd:string">*</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_type</key>
|
||||||
|
<value xsi:type="xsd:string">A</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_data</key>
|
||||||
|
<value xsi:type="xsd:string">10.0.0.1</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_aux</key>
|
||||||
|
<value xsi:type="xsd:int">0</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_id</key>
|
||||||
|
<value xsi:type="xsd:string">57297479</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_changeable</key>
|
||||||
|
<value xsi:type="xsd:string">Y</value>
|
||||||
|
</item>
|
||||||
|
</item>
|
||||||
|
<item xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_zone</key>
|
||||||
|
<value xsi:type="xsd:string">example.org</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_name</key>
|
||||||
|
<value xsi:type="xsd:string"></value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_type</key>
|
||||||
|
<value xsi:type="xsd:string">MX</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_data</key>
|
||||||
|
<value xsi:type="xsd:string">user.kasserver.com.</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_aux</key>
|
||||||
|
<value xsi:type="xsd:int">10</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_id</key>
|
||||||
|
<value xsi:type="xsd:string">57297481</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_changeable</key>
|
||||||
|
<value xsi:type="xsd:string">Y</value>
|
||||||
|
</item>
|
||||||
|
</item>
|
||||||
|
<item xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_zone</key>
|
||||||
|
<value xsi:type="xsd:string">example.org</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_name</key>
|
||||||
|
<value xsi:type="xsd:string"></value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_type</key>
|
||||||
|
<value xsi:type="xsd:string">TXT</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_data</key>
|
||||||
|
<value xsi:type="xsd:string">v=spf1 mx a ?all</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_aux</key>
|
||||||
|
<value xsi:type="xsd:int">0</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_id</key>
|
||||||
|
<value xsi:type="xsd:string">57297483</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_changeable</key>
|
||||||
|
<value xsi:type="xsd:string">Y</value>
|
||||||
|
</item>
|
||||||
|
</item>
|
||||||
|
<item xsi:type="ns2:Map">
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_zone</key>
|
||||||
|
<value xsi:type="xsd:string">example.org</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_name</key>
|
||||||
|
<value xsi:type="xsd:string">_dmarc</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_type</key>
|
||||||
|
<value xsi:type="xsd:string">TXT</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_data</key>
|
||||||
|
<value xsi:type="xsd:string">v=DMARC1; p=none;</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_aux</key>
|
||||||
|
<value xsi:type="xsd:int">0</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_id</key>
|
||||||
|
<value xsi:type="xsd:string">57297485</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key xsi:type="xsd:string">record_changeable</key>
|
||||||
|
<value xsi:type="xsd:string">Y</value>
|
||||||
|
</item>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
</return>
|
||||||
|
</ns1:KasApiResponse>
|
||||||
|
</SOAP-ENV:Body>
|
||||||
|
</SOAP-ENV:Envelope>
|
46
providers/dns/allinkl/internal/types.go
Normal file
46
providers/dns/allinkl/internal/types.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Trimmer trim all XML fields.
|
||||||
|
type Trimmer struct {
|
||||||
|
decoder *xml.Decoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr Trimmer) Token() (xml.Token, error) {
|
||||||
|
t, err := tr.decoder.Token()
|
||||||
|
if cd, ok := t.(xml.CharData); ok {
|
||||||
|
t = xml.CharData(bytes.TrimSpace(cd))
|
||||||
|
}
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fault a SOAP fault.
|
||||||
|
type Fault struct {
|
||||||
|
Code string `xml:"faultcode"`
|
||||||
|
Message string `xml:"faultstring"`
|
||||||
|
Actor string `xml:"faultactor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Fault) Error() string {
|
||||||
|
return fmt.Sprintf("%s: %s: %s", f.Actor, f.Code, f.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// KasResponse a KAS SOAP response.
|
||||||
|
type KasResponse struct {
|
||||||
|
Return *Item `xml:"return"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Item an item of the KAS SOAP response.
|
||||||
|
type Item struct {
|
||||||
|
Text string `xml:",chardata" json:"text,omitempty"`
|
||||||
|
Type string `xml:"type,attr" json:"type,omitempty"`
|
||||||
|
Raw string `xml:"nil,attr" json:"raw,omitempty"`
|
||||||
|
Key *Item `xml:"key" json:"key,omitempty"`
|
||||||
|
Value *Item `xml:"value" json:"value,omitempty"`
|
||||||
|
Items []*Item `xml:"item" json:"item,omitempty"`
|
||||||
|
}
|
94
providers/dns/allinkl/internal/types_api.go
Normal file
94
providers/dns/allinkl/internal/types_api.go
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
// kasAPIEnvelope a KAS API request envelope.
|
||||||
|
const kasAPIEnvelope = `
|
||||||
|
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
<Body>
|
||||||
|
<KasApi xmlns="https://kasserver.com/">
|
||||||
|
<Params>%s</Params>
|
||||||
|
</KasApi>
|
||||||
|
</Body>
|
||||||
|
</Envelope>`
|
||||||
|
|
||||||
|
// KasAPIResponseEnvelope a KAS envelope of the API response.
|
||||||
|
type KasAPIResponseEnvelope struct {
|
||||||
|
XMLName xml.Name `xml:"Envelope"`
|
||||||
|
Body KasAPIBody `xml:"Body"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type KasAPIBody struct {
|
||||||
|
KasAPIResponse *KasResponse `xml:"KasApiResponse"`
|
||||||
|
Fault *Fault `xml:"Fault"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
type KasRequest struct {
|
||||||
|
// Login the relevant KAS login.
|
||||||
|
Login string `json:"kas_login,omitempty"`
|
||||||
|
// AuthType the authentication type.
|
||||||
|
AuthType string `json:"kas_auth_type,omitempty"`
|
||||||
|
// AuthData the authentication data.
|
||||||
|
AuthData string `json:"kas_auth_data,omitempty"`
|
||||||
|
// Action API function.
|
||||||
|
Action string `json:"kas_action,omitempty"`
|
||||||
|
// RequestParams Parameters to the API function.
|
||||||
|
RequestParams interface{} `json:"KasRequestParams,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DNSRequest struct {
|
||||||
|
// ZoneHost the zone in question (must be a FQDN).
|
||||||
|
ZoneHost string `json:"zone_host"`
|
||||||
|
// RecordType the TYPE of the resource record (MX, A, AAAA etc.).
|
||||||
|
RecordType string `json:"record_type"`
|
||||||
|
// RecordName the NAME of the resource record.
|
||||||
|
RecordName string `json:"record_name"`
|
||||||
|
// RecordData the DATA of the resource record.
|
||||||
|
RecordData string `json:"record_data"`
|
||||||
|
// RecordAux the AUX of the resource record.
|
||||||
|
RecordAux int `json:"record_aux"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
type GetDNSSettingsAPIResponse struct {
|
||||||
|
Response GetDNSSettingsResponse `json:"Response" mapstructure:"Response"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetDNSSettingsResponse struct {
|
||||||
|
KasFloodDelay float64 `json:"KasFloodDelay" mapstructure:"KasFloodDelay"`
|
||||||
|
ReturnInfo []ReturnInfo `json:"ReturnInfo" mapstructure:"ReturnInfo"`
|
||||||
|
ReturnString string `json:"ReturnString"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReturnInfo struct {
|
||||||
|
ID interface{} `json:"record_id,omitempty" mapstructure:"record_id"`
|
||||||
|
Zone string `json:"record_zone,omitempty" mapstructure:"record_zone"`
|
||||||
|
Name string `json:"record_name,omitempty" mapstructure:"record_name"`
|
||||||
|
Type string `json:"record_type,omitempty" mapstructure:"record_type"`
|
||||||
|
Data string `json:"record_data,omitempty" mapstructure:"record_data"`
|
||||||
|
Changeable string `json:"record_changeable,omitempty" mapstructure:"record_changeable"`
|
||||||
|
Aux int `json:"record_aux,omitempty" mapstructure:"record_aux"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddDNSSettingsAPIResponse struct {
|
||||||
|
Response AddDNSSettingsResponse `json:"Response" mapstructure:"Response"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddDNSSettingsResponse struct {
|
||||||
|
KasFloodDelay float64 `json:"KasFloodDelay" mapstructure:"KasFloodDelay"`
|
||||||
|
ReturnInfo string `json:"ReturnInfo" mapstructure:"ReturnInfo"`
|
||||||
|
ReturnString string `json:"ReturnString" mapstructure:"ReturnString"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteDNSSettingsAPIResponse struct {
|
||||||
|
Response DeleteDNSSettingsResponse `json:"Response"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteDNSSettingsResponse struct {
|
||||||
|
KasFloodDelay float64 `json:"KasFloodDelay"`
|
||||||
|
ReturnInfo bool `json:"ReturnInfo"`
|
||||||
|
ReturnString string `json:"ReturnString"`
|
||||||
|
}
|
34
providers/dns/allinkl/internal/types_auth.go
Normal file
34
providers/dns/allinkl/internal/types_auth.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
// kasAuthEnvelope a KAS authentication request envelope.
|
||||||
|
const kasAuthEnvelope = `
|
||||||
|
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
<Body>
|
||||||
|
<KasAuth xmlns="https://kasserver.com/">
|
||||||
|
<Params>%s</Params>
|
||||||
|
</KasAuth>
|
||||||
|
</Body>
|
||||||
|
</Envelope>`
|
||||||
|
|
||||||
|
// KasAuthEnvelope a KAS envelope of the authentication response.
|
||||||
|
type KasAuthEnvelope struct {
|
||||||
|
XMLName xml.Name `xml:"Envelope"`
|
||||||
|
Body KasAuthBody `xml:"Body"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type KasAuthBody struct {
|
||||||
|
KasAuthResponse *KasResponse `xml:"KasAuthResponse"`
|
||||||
|
Fault *Fault `xml:"Fault"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
type AuthRequest struct {
|
||||||
|
Login string `json:"kas_login,omitempty"`
|
||||||
|
AuthData string `json:"kas_auth_data,omitempty"`
|
||||||
|
AuthType string `json:"kas_auth_type,omitempty"`
|
||||||
|
SessionLifetime int `json:"session_lifetime,omitempty"`
|
||||||
|
SessionUpdateLifetime string `json:"session_update_lifetime,omitempty"`
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/go-acme/lego/v4/challenge/dns01"
|
"github.com/go-acme/lego/v4/challenge/dns01"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/acmedns"
|
"github.com/go-acme/lego/v4/providers/dns/acmedns"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/alidns"
|
"github.com/go-acme/lego/v4/providers/dns/alidns"
|
||||||
|
"github.com/go-acme/lego/v4/providers/dns/allinkl"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/arvancloud"
|
"github.com/go-acme/lego/v4/providers/dns/arvancloud"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/auroradns"
|
"github.com/go-acme/lego/v4/providers/dns/auroradns"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/autodns"
|
"github.com/go-acme/lego/v4/providers/dns/autodns"
|
||||||
|
@ -104,6 +105,8 @@ func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) {
|
||||||
return acmedns.NewDNSProvider()
|
return acmedns.NewDNSProvider()
|
||||||
case "alidns":
|
case "alidns":
|
||||||
return alidns.NewDNSProvider()
|
return alidns.NewDNSProvider()
|
||||||
|
case "allinkl":
|
||||||
|
return allinkl.NewDNSProvider()
|
||||||
case "arvancloud":
|
case "arvancloud":
|
||||||
return arvancloud.NewDNSProvider()
|
return arvancloud.NewDNSProvider()
|
||||||
case "azure":
|
case "azure":
|
||||||
|
|
Loading…
Reference in a new issue