update_nics: Move legacy protocol support to an adapter function
This commit is contained in:
parent
a178d40633
commit
5256a1d02c
2 changed files with 68 additions and 64 deletions
128
ddclient.in
128
ddclient.in
|
@ -709,9 +709,55 @@ our %variables = (
|
||||||
'wildcard' => setv(T_BOOL, 0, 1, 0, undef),
|
'wildcard' => setv(T_BOOL, 0, 1, 0, undef),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# Converts a legacy protocol update method to behave like a modern implementation by moving
|
||||||
|
# `$config{$h}{status}` and `$config{$h}{ip}` to the version-specific modern equivalents.
|
||||||
|
sub adapt_legacy_update {
|
||||||
|
my ($update) = @_;
|
||||||
|
return sub {
|
||||||
|
my (@hosts) = @_;
|
||||||
|
my %ipv;
|
||||||
|
for my $h (@hosts) {
|
||||||
|
$ipv{$h} = defined($config{$h}{'wantipv4'}) ? '4' : '6';
|
||||||
|
$config{$h}{'wantip'} = delete($config{$h}{"wantipv$ipv{$h}"});
|
||||||
|
delete($config{$h}{$_}) for qw(ip status);
|
||||||
|
}
|
||||||
|
$update->(@hosts);
|
||||||
|
for my $h (@hosts) {
|
||||||
|
local $_l = pushlogctx($h);
|
||||||
|
delete($config{$h}{'wantip'});
|
||||||
|
debug(
|
||||||
|
"legacy protocol; moving 'status' to 'status-ipv$ipv{$h}', 'ip' to 'ipv$ipv{$h}'");
|
||||||
|
$config{$h}{"status-ipv$ipv{$h}"} = delete($config{$h}{'status'});
|
||||||
|
# TODO: Currently $config{$h}{'ip'} is used for two distinct purposes: it holds the
|
||||||
|
# value of the --ip option, and it is updated by legacy protocols to hold the new IP
|
||||||
|
# address after an update. Fortunately, the --ip option is not used very often, and if
|
||||||
|
# it is, the values for the two use cases are usually (but not always) the same. This
|
||||||
|
# boolean is an imperfect attempt to identify whether 'ip' is being used for the --ip
|
||||||
|
# option, to avoid breaking some user's configuration. Protocols should be updated to
|
||||||
|
# not set $config{$h}{'ip'} because %config is for configuration, not update status
|
||||||
|
# (same goes for 'status', 'mtime', etc.).
|
||||||
|
my $ip_option = opt('use', $h) eq 'ip' || opt('usev6', $h) eq 'ip';
|
||||||
|
my $ip = $config{$h}{'ip'};
|
||||||
|
delete($config{$h}{'ip'}) if !$ip_option;
|
||||||
|
# TODO: See above comment for $ip_option. This is the same situation, but for 'ipv4'
|
||||||
|
# and 'ipv6'.
|
||||||
|
my $vip_option = opt("usev$ipv{$h}", $h) eq "ipv$ipv{$h}";
|
||||||
|
if ($vip_option && defined(my $vip = $config{$h}{"ipv$ipv{$h}"})) {
|
||||||
|
if (!defined($ip) || $ip ne $vip) {
|
||||||
|
my $fip = defined($ip) ? "'$ip'" : '<undefined>';
|
||||||
|
debug("unable to set 'ipv$ipv{$h}' to $fip; already set to '$vip'");
|
||||||
|
}
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
$config{$h}{"ipv$ipv{$h}"} = $ip;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
our %protocols = (
|
our %protocols = (
|
||||||
'1984' => {
|
'1984' => {
|
||||||
'update' => \&nic_1984_update,
|
'update' => adapt_legacy_update(\&nic_1984_update),
|
||||||
'examples' => \&nic_1984_examples,
|
'examples' => \&nic_1984_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -720,7 +766,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'changeip' => {
|
'changeip' => {
|
||||||
'update' => \&nic_changeip_update,
|
'update' => adapt_legacy_update(\&nic_changeip_update),
|
||||||
'examples' => \&nic_changeip_examples,
|
'examples' => \&nic_changeip_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -739,7 +785,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'cloudns' => {
|
'cloudns' => {
|
||||||
'update' => \&nic_cloudns_update,
|
'update' => adapt_legacy_update(\&nic_cloudns_update),
|
||||||
'examples' => \&nic_cloudns_examples,
|
'examples' => \&nic_cloudns_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -768,7 +814,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'dinahosting' => {
|
'dinahosting' => {
|
||||||
'update' => \&nic_dinahosting_update,
|
'update' => adapt_legacy_update(\&nic_dinahosting_update),
|
||||||
'examples' => \&nic_dinahosting_examples,
|
'examples' => \&nic_dinahosting_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -789,7 +835,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'dnsmadeeasy' => {
|
'dnsmadeeasy' => {
|
||||||
'update' => \&nic_dnsmadeeasy_update,
|
'update' => adapt_legacy_update(\&nic_dnsmadeeasy_update),
|
||||||
'examples' => \&nic_dnsmadeeasy_examples,
|
'examples' => \&nic_dnsmadeeasy_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -798,7 +844,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'dondominio' => {
|
'dondominio' => {
|
||||||
'update' => \&nic_dondominio_update,
|
'update' => adapt_legacy_update(\&nic_dondominio_update),
|
||||||
'examples' => \&nic_dondominio_examples,
|
'examples' => \&nic_dondominio_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -806,7 +852,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'dslreports1' => {
|
'dslreports1' => {
|
||||||
'update' => \&nic_dslreports1_update,
|
'update' => adapt_legacy_update(\&nic_dslreports1_update),
|
||||||
'examples' => \&nic_dslreports1_examples,
|
'examples' => \&nic_dslreports1_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -831,7 +877,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'dyndns1' => {
|
'dyndns1' => {
|
||||||
'update' => \&nic_dyndns1_update,
|
'update' => adapt_legacy_update(\&nic_dyndns1_update),
|
||||||
'examples' => \&nic_dyndns1_examples,
|
'examples' => \&nic_dyndns1_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -873,7 +919,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'freemyip' => {
|
'freemyip' => {
|
||||||
'update' => \&nic_freemyip_update,
|
'update' => adapt_legacy_update(\&nic_freemyip_update),
|
||||||
'examples' => \&nic_freemyip_examples,
|
'examples' => \&nic_freemyip_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -947,7 +993,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'namecheap' => {
|
'namecheap' => {
|
||||||
'update' => \&nic_namecheap_update,
|
'update' => adapt_legacy_update(\&nic_namecheap_update),
|
||||||
'examples' => \&nic_namecheap_examples,
|
'examples' => \&nic_namecheap_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -956,7 +1002,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'nfsn' => {
|
'nfsn' => {
|
||||||
'update' => \&nic_nfsn_update,
|
'update' => adapt_legacy_update(\&nic_nfsn_update),
|
||||||
'examples' => \&nic_nfsn_examples,
|
'examples' => \&nic_nfsn_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -996,7 +1042,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'ovh' => {
|
'ovh' => {
|
||||||
'update' => \&nic_ovh_update,
|
'update' => adapt_legacy_update(\&nic_ovh_update),
|
||||||
'examples' => \&nic_ovh_examples,
|
'examples' => \&nic_ovh_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -1018,7 +1064,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'sitelutions' => {
|
'sitelutions' => {
|
||||||
'update' => \&nic_sitelutions_update,
|
'update' => adapt_legacy_update(\&nic_sitelutions_update),
|
||||||
'examples' => \&nic_sitelutions_examples,
|
'examples' => \&nic_sitelutions_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -1027,7 +1073,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'yandex' => {
|
'yandex' => {
|
||||||
'update' => \&nic_yandex_update,
|
'update' => adapt_legacy_update(\&nic_yandex_update),
|
||||||
'examples' => \&nic_yandex_examples,
|
'examples' => \&nic_yandex_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -1036,7 +1082,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'zoneedit1' => {
|
'zoneedit1' => {
|
||||||
'update' => \&nic_zoneedit1_update,
|
'update' => adapt_legacy_update(\&nic_zoneedit1_update),
|
||||||
'examples' => \&nic_zoneedit1_examples,
|
'examples' => \&nic_zoneedit1_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -1046,7 +1092,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'keysystems' => {
|
'keysystems' => {
|
||||||
'update' => \&nic_keysystems_update,
|
'update' => adapt_legacy_update(\&nic_keysystems_update),
|
||||||
'examples' => \&nic_keysystems_examples,
|
'examples' => \&nic_keysystems_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -1077,7 +1123,7 @@ our %protocols = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'enom' => {
|
'enom' => {
|
||||||
'update' => \&nic_enom_update,
|
'update' => adapt_legacy_update(\&nic_enom_update),
|
||||||
'examples' => \&nic_enom_examples,
|
'examples' => \&nic_enom_examples,
|
||||||
'variables' => {
|
'variables' => {
|
||||||
%{$variables{'protocol-common-defaults'}},
|
%{$variables{'protocol-common-defaults'}},
|
||||||
|
@ -1454,49 +1500,9 @@ sub update_nics {
|
||||||
if (@hosts) {
|
if (@hosts) {
|
||||||
$0 = sprintf("%s - updating %s", $program, join(',', @hosts));
|
$0 = sprintf("%s - updating %s", $program, join(',', @hosts));
|
||||||
local $_l = pushlogctx($p);
|
local $_l = pushlogctx($p);
|
||||||
for my $h (@hosts) {
|
|
||||||
# TODO: Remove this once all legacy protocol implementations have been upgraded to
|
|
||||||
# read `wantipv4` and `wantipv6` directly.
|
|
||||||
$config{$h}{'wantip'} = $config{$h}{'wantipv4'} // $config{$h}{'wantipv6'};
|
|
||||||
}
|
|
||||||
&$update(@hosts);
|
&$update(@hosts);
|
||||||
for my $h (@hosts) {
|
for my $h (@hosts) {
|
||||||
local $_l = pushlogctx($h);
|
delete($config{$h}{$_}) for qw(wantipv4 wantipv6);
|
||||||
delete($config{$h}{$_}) for qw(wantip wantipv4 wantipv6);
|
|
||||||
# Backwards compatibility: Legacy protocol implementations read `wantip` and set
|
|
||||||
# `ip` and `status`. Modern protocol implementations read `wantipv4` and
|
|
||||||
# `wantipv6` and set `ipv4`, `ipv6`, `status-ipv4`, and `status-ipv6`. Make legacy
|
|
||||||
# implementations look like modern implementations by moving `ip` and `status` to
|
|
||||||
# the modern version-specific equivalents.
|
|
||||||
my $status = delete($config{$h}{'status'}) or next;
|
|
||||||
my $ip = $config{$h}{'ip'};
|
|
||||||
my $ipv = is_ipv4($ip) ? '4' : is_ipv6($ip) ? '6' : undef;
|
|
||||||
# TODO: Currently $config{$h}{'ip'} is used for two distinct purposes: it holds the
|
|
||||||
# value of the --ip option, and it is updated by legacy protocols to hold the new
|
|
||||||
# IP address after an update. Fortunately, the --ip option is not used very often,
|
|
||||||
# and if it is, the values for the two use cases are usually (but not always) the
|
|
||||||
# same. This boolean is an imperfect attempt to identify whether 'ip' is being
|
|
||||||
# used for the --ip option, to avoid breaking some user's configuration. Protocols
|
|
||||||
# should be updated to not set $config{$h}{'ip'} because %config is for
|
|
||||||
# configuration, not update status (same goes for 'status', 'mtime', etc.).
|
|
||||||
my $ip_option = opt('use', $h) eq 'ip' || opt('usev6', $h) eq 'ip';
|
|
||||||
delete($config{$h}{'ip'}) if !$ip_option;
|
|
||||||
debug("legacy protocol; moving 'status' to 'status-ipv$ipv', 'ip' to 'ipv$ipv'");
|
|
||||||
$config{$h}{"status-ipv$ipv"} = $status;
|
|
||||||
# TODO: See above comment for $ip_option. This is the same situation, but for
|
|
||||||
# 'ipv4' and 'ipv6'.
|
|
||||||
my $vip_option = opt("usev$ipv", $h) eq "ipv$ipv";
|
|
||||||
if (defined(my $vip = $config{$h}{"ipv$ipv"}) && $vip_option) {
|
|
||||||
debug("unable to update 'ipv$ipv' to '$ip' " .
|
|
||||||
"because it is already set to '$vip'") if $vip_option;
|
|
||||||
} else {
|
|
||||||
# A previous update would have moved `$config{$h}{'ip'}` to
|
|
||||||
# `$config{$h}{"ipv$ipv"}`, so it is OK to overwrite `$config{$h}{"ipv$ipv"}`
|
|
||||||
# if it is already set.
|
|
||||||
debug("updating 'ipv$ipv' from '$vip' to '$ip'")
|
|
||||||
if defined($vip) && $vip ne $ip;
|
|
||||||
$config{$h}{"ipv$ipv"} = $ip;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
runpostscript(join ' ', keys %ipsv4, keys %ipsv6);
|
runpostscript(join ' ', keys %ipsv4, keys %ipsv6);
|
||||||
|
@ -3600,9 +3606,7 @@ sub nic_updateable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO: `status` is set by legacy protocol implementations. Remove it from this list once all
|
delete($config{$host}{$_}) for qw(status-ipv4 status-ipv6 update);
|
||||||
# legacy protocol implementations have been upgraded.
|
|
||||||
delete($config{$host}{$_}) for qw(status status-ipv4 status-ipv6 update);
|
|
||||||
if ($update) {
|
if ($update) {
|
||||||
$config{$host}{'update'} = 1;
|
$config{$host}{'update'} = 1;
|
||||||
$config{$host}{'atime'} = $now;
|
$config{$host}{'atime'} = $now;
|
||||||
|
@ -3611,7 +3615,7 @@ sub nic_updateable {
|
||||||
for (qw(status-ipv4 status-ipv6)) {
|
for (qw(status-ipv4 status-ipv6)) {
|
||||||
$config{$host}{$_} = $recap{$host}{$_} if defined($recap{$host}{$_});
|
$config{$host}{$_} = $recap{$host}{$_} if defined($recap{$host}{$_});
|
||||||
}
|
}
|
||||||
delete($config{$host}{$_}) for qw(wantip wantipv4 wantipv6);
|
delete($config{$host}{$_}) for qw(wantipv4 wantipv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $update;
|
return $update;
|
||||||
|
|
|
@ -48,7 +48,7 @@ local %ddclient::protocols = (
|
||||||
# properties. (Modern protocol implementations read `wantipv4` and `wantipv6` and set `ipv4`,
|
# properties. (Modern protocol implementations read `wantipv4` and `wantipv6` and set `ipv4`,
|
||||||
# `ipv6`, `status-ipv4`, and `status-ipv6`.) It always succeeds.
|
# `ipv6`, `status-ipv4`, and `status-ipv6`.) It always succeeds.
|
||||||
legacy => {
|
legacy => {
|
||||||
update => sub {
|
update => ddclient::adapt_legacy_update(sub {
|
||||||
ddclient::debug('in update');
|
ddclient::debug('in update');
|
||||||
for my $h (@_) {
|
for my $h (@_) {
|
||||||
local $ddclient::_l = ddclient::pushlogctx($h);
|
local $ddclient::_l = ddclient::pushlogctx($h);
|
||||||
|
@ -59,7 +59,7 @@ local %ddclient::protocols = (
|
||||||
$ddclient::config{$h}{mtime} = $ddclient::now;
|
$ddclient::config{$h}{mtime} = $ddclient::now;
|
||||||
}
|
}
|
||||||
ddclient::debug('returning from update');
|
ddclient::debug('returning from update');
|
||||||
},
|
}),
|
||||||
variables => {
|
variables => {
|
||||||
%{$ddclient::variables{'protocol-common-defaults'}},
|
%{$ddclient::variables{'protocol-common-defaults'}},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue