diff --git a/ChangeLog.md b/ChangeLog.md index 3c0e540d..07ea2809 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 d9baa981..ecf4d230 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 22db4993..2b8a7761 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 0beb3f88..9d4b9d3c 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();