mirror of
				https://github.com/go-acme/lego.git
				synced 2025-10-31 16:37:41 +02:00 
			
		
		
		
	Add DNS provider for all-inkl (#1444)
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							2a194d6ab9
						
					
				
				
					commit
					43779d7533
				
			
							
								
								
									
										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/)                  | | ||||
| | [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/)                              | | ||||
| | [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/)                        | | ||||
| | [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/)                            | | ||||
| | [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/)               | | ||||
| | [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/)            | | ||||
| | [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/)                                  | | ||||
| | [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/)                    | | ||||
| | [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/)                         | | ||||
| | [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/)                     | | ||||
| | [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/)                    | | ||||
| | [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/)                              | | ||||
| | [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/)                     | | ||||
| | [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/)                         | | ||||
| | [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/)                        | | ||||
| | [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/)                            | | ||||
| | [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/)                                  | | ||||
| | [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/)                             | | ||||
| | [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/)                      | [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/)                 | | ||||
| | [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/)                              | | ||||
| | [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/)                            |                                                                                 | | ||||
| | [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/)               | | ||||
| | [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/)                          | | ||||
| | [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/)                  | | ||||
| | [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/)                        | | ||||
| | [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/) | | ||||
| | [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/)                            | | ||||
| | [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/)                         | | ||||
| | [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/)                        | | ||||
| | [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/)                            | | ||||
| | [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/)                     | | ||||
| | [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/)                        | | ||||
| | [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/)                                | | ||||
| | [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/)                       | | ||||
| | [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/)                            | | ||||
| | [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/)                      | | ||||
| | [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/)                        | | ||||
| | [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/)                 | | ||||
| | [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/)                      | | ||||
| | [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/)                 | | ||||
| | [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/)                      | [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/)                 | [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/)                              | [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 --> | ||||
|  | ||||
|   | ||||
| @@ -16,6 +16,7 @@ func allDNSCodes() string { | ||||
| 		"manual", | ||||
| 		"acme-dns", | ||||
| 		"alidns", | ||||
| 		"allinkl", | ||||
| 		"arvancloud", | ||||
| 		"auroradns", | ||||
| 		"autodns", | ||||
| @@ -150,6 +151,26 @@ func displayDNSHelp(name string) error { | ||||
| 		ew.writeln() | ||||
| 		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": | ||||
| 		// generated from: providers/dns/arvancloud/arvancloud.toml | ||||
| 		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/liquidweb/liquidweb-go v1.6.3 | ||||
| 	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/nrdcg/auroradns v1.0.1 | ||||
| 	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/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.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= | ||||
| 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-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | ||||
| 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/providers/dns/acmedns" | ||||
| 	"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/auroradns" | ||||
| 	"github.com/go-acme/lego/v4/providers/dns/autodns" | ||||
| @@ -104,6 +105,8 @@ func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) { | ||||
| 		return acmedns.NewDNSProvider() | ||||
| 	case "alidns": | ||||
| 		return alidns.NewDNSProvider() | ||||
| 	case "allinkl": | ||||
| 		return allinkl.NewDNSProvider() | ||||
| 	case "arvancloud": | ||||
| 		return arvancloud.NewDNSProvider() | ||||
| 	case "azure": | ||||
|   | ||||
		Reference in New Issue
	
	Block a user