From 60e3cfeb4c38d610afa5247f34b0e0c2ce65f192 Mon Sep 17 00:00:00 2001 From: Nelson Araujo Date: Sun, 8 Sep 2024 20:00:10 -0700 Subject: [PATCH 1/5] Add support for ionos.com --- ChangeLog.md | 2 ++ Makefile.am | 1 + README.md | 1 + ddclient.in | 72 +++++++++++++++++++++++++++++++++++++++++++++ t/protocol_ionos.pl | 69 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 145 insertions(+) create mode 100644 t/protocol_ionos.pl diff --git a/ChangeLog.md b/ChangeLog.md index 3c0e540..07ea280 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -99,6 +99,8 @@ repository history](https://github.com/ddclient/ddclient/commits/master). [#726](https://github.com/ddclient/ddclient/pull/726) * `porkbun`: The update URL hostname is now configurable via the `server` option. [#752](https://github.com/ddclient/ddclient/pull/752) + * `ionos`: Added support for updating Ionos records. + [#743](https://github.com/ddclient/ddclient/pull/743) ### Bug fixes diff --git a/Makefile.am b/Makefile.am index d9baa98..ecf4d23 100644 --- a/Makefile.am +++ b/Makefile.am @@ -73,6 +73,7 @@ handwritten_tests = \ t/protocol_directnic.pl \ t/protocol_dnsexit2.pl \ t/protocol_dyndns2.pl \ + t/protocol_ionos.pl \ t/read_recap.pl \ t/skip.pl \ t/ssl-validate.pl \ diff --git a/README.md b/README.md index 22db499..2b8a776 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Dynamic DNS services currently supported include: * [Hurricane Electric](https://dns.he.net) * [Infomaniak](https://faq.infomaniak.com/2376) * [INWX](https://www.inwx.com/) + * [Ionos](https://ionos.com) * [Loopia](https://www.loopia.se) * [Mythic Beasts](https://www.mythic-beasts.com/support/api/dnsv2/dynamic-dns) * [NameCheap](https://www.namecheap.com) diff --git a/ddclient.in b/ddclient.in index 0beb3f8..9d4b9d3 100755 --- a/ddclient.in +++ b/ddclient.in @@ -1295,6 +1295,15 @@ our %protocols = ( 'max-interval' => setv(T_DELAY, 0, 'inf', 0), }, ), + 'ionos' => ddclient::Protocol->new( + 'update' => \&nic_ionos_update, + 'examples' => \&nic_ionos_examples, + 'cfgvars' => { + %{$cfgvars{'protocol-common-defaults'}}, + 'server' => setv(T_FQDNP, 0, 'ipv4.api.hosting.ionos.com', undef), + 'login' => undef, + }, + ), ); $cfgvars{'merged'} = { map({ %{$protocols{$_}{'cfgvars'}} } keys(%protocols)), @@ -7644,6 +7653,69 @@ Example ${program}.conf file entries: EoEXAMPLE } +###################################################################### +## nic_ionos_examples +###################################################################### +sub nic_ionos_examples { + my $self = shift; + return < $@); + ddclient::t::HTTPD->import(); + plan tests => 2; +} + +{ + package Logger; + use parent qw(-norequire ddclient::Logger); + sub new { + my ($class, $parent) = @_; + my $self = $class->SUPER::new(undef, $parent); + $self->{logs} = []; + return $self; + } + sub _log { + my ($self, $args) = @_; + push(@{$self->{logs}}, $args) + if ($args->{label} // '') =~ qr/^(?:WARNING|FATAL|SUCCESS|FAILED)$/; + return $self->SUPER::_log($args); + } +} + +# Subtest for the protocol_ionos +subtest 'Testing protocol_ionos' => sub { + # Mock HTTP server + httpd()->run(sub { + my ($req) = @_; + diag('=============================================================================='); + diag("Test server received request:\n" . $req->as_string()); + + return undef if $req->uri()->path() eq '/control'; + return [400, $textplain, ['invalid method: ' . $req->method()]] if $req->method() ne 'GET'; + return undef + }); + + local $ddclient::globals{debug} = 1; + local $ddclient::globals{verbose} = 1; + my $l = Logger->new($ddclient::_l); + + local %ddclient::config = ( + 'host.my.example.com' => { + 'protocol' => 'ionos', + 'password' => 'mytestingpassword', + 'server' => httpd()->endpoint(), + 'wantipv4' => '1.2.3.4', + }, + ); + + httpd()->reset([200, $textplain, []]); + + { + local $ddclient::_l = $l; + + ddclient::nic_ionos_update(undef, 'host.my.example.com'); + } + + my @requests = httpd()->reset(); + is(scalar(@requests), 1, "Single update request"); + + my $req = shift(@requests); + is($req->uri()->path(), '/dns/v1/dyndns', "Correct request path"); + is($req->uri()->query(), 'q=mytestingpassword', "Correct request query"); +}; + +done_testing(); From 3784633b70a7734af53b4bb1bef46fc553f111ca Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Thu, 19 Dec 2024 05:14:36 -0500 Subject: [PATCH 2/5] fixup! Add support for ionos.com --- ddclient.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ddclient.in b/ddclient.in index 9d4b9d3..467c140 100755 --- a/ddclient.in +++ b/ddclient.in @@ -1296,9 +1296,9 @@ our %protocols = ( }, ), 'ionos' => ddclient::Protocol->new( - 'update' => \&nic_ionos_update, - 'examples' => \&nic_ionos_examples, - 'cfgvars' => { + 'update' => \&nic_ionos_update, + 'examples' => \&nic_ionos_examples, + 'cfgvars' => { %{$cfgvars{'protocol-common-defaults'}}, 'server' => setv(T_FQDNP, 0, 'ipv4.api.hosting.ionos.com', undef), 'login' => undef, From 8d29a6ea99428f91baa414d0806080a3cd79ce33 Mon Sep 17 00:00:00 2001 From: Nelson Araujo Date: Fri, 20 Dec 2024 00:27:53 -0800 Subject: [PATCH 3/5] Update ddclient.in Co-authored-by: Indrajit Raychaudhuri --- ddclient.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddclient.in b/ddclient.in index 467c140..77bc1eb 100755 --- a/ddclient.in +++ b/ddclient.in @@ -7678,7 +7678,7 @@ Getting the DynDNS key (only available via Ionos API): 1. Create an API key 2. Enable DynDNS for your host using the /dns/v1/dyndns API - (documentation @ https://developer.hosting.ionos.es/docs/dns) + (documentation @ https://developer.hosting.ionos.com/docs/dns) 3. In the API response, get the key value. The key is a long string from the "q=" parameter. The URL looks like this: https://ipv4.api.hosting.ionos.com/dns/v1/dyndns?q=XXXXXXXXXXXXXXX From bf8687279aea4aeea2d6b016ce67d873ef581e1b Mon Sep 17 00:00:00 2001 From: Nelson Araujo Date: Fri, 20 Dec 2024 00:34:28 -0800 Subject: [PATCH 4/5] Update ddclient.in Co-authored-by: Richard Hansen --- ddclient.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddclient.in b/ddclient.in index 77bc1eb..1db870d 100755 --- a/ddclient.in +++ b/ddclient.in @@ -7681,7 +7681,7 @@ Getting the DynDNS key (only available via Ionos API): (documentation @ https://developer.hosting.ionos.com/docs/dns) 3. In the API response, get the key value. The key is a long string from the "q=" parameter. The URL looks like this: - https://ipv4.api.hosting.ionos.com/dns/v1/dyndns?q=XXXXXXXXXXXXXXX + https://api.hosting.ionos.com/dns/v1/dyndns?q=XXXXXXXXXXXXXXX (in the example above the key is "XXXXXXXXXXXXXXX"). Note: Because the key is individual for each host, you cannot update From e8578547fe3bb073a10a829fe2b3d142fb9990d8 Mon Sep 17 00:00:00 2001 From: Nelson Araujo Date: Fri, 20 Dec 2024 00:34:35 -0800 Subject: [PATCH 5/5] Update ddclient.in Co-authored-by: Richard Hansen --- ddclient.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddclient.in b/ddclient.in index 1db870d..5b8bea0 100755 --- a/ddclient.in +++ b/ddclient.in @@ -1300,7 +1300,7 @@ our %protocols = ( 'examples' => \&nic_ionos_examples, 'cfgvars' => { %{$cfgvars{'protocol-common-defaults'}}, - 'server' => setv(T_FQDNP, 0, 'ipv4.api.hosting.ionos.com', undef), + 'server' => setv(T_FQDNP, 0, 'api.hosting.ionos.com', undef), 'login' => undef, }, ),