Write update status to %recap
, not %config
Status is not configuration so it doesn't belong in `%config`. `wantip`, `wantipv4`, and `wantipv6` are still passed along in `%config` because `group_hosts_by` needs access to them like other settings.
This commit is contained in:
parent
0348ded46b
commit
268369a05e
6 changed files with 254 additions and 451 deletions
|
@ -100,6 +100,8 @@ repository history](https://github.com/ddclient/ddclient/commits/master).
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
|
||||||
|
* Fixed numerous bugs in cache file (recap) handling.
|
||||||
|
[#740](https://github.com/ddclient/ddclient/pull/740)
|
||||||
* Fixed numerous bugs in command-line option and configuration file
|
* Fixed numerous bugs in command-line option and configuration file
|
||||||
processing. [#733](https://github.com/ddclient/ddclient/pull/733)
|
processing. [#733](https://github.com/ddclient/ddclient/pull/733)
|
||||||
* `noip`: Fixed failure to honor IP discovery settings in some circumstances.
|
* `noip`: Fixed failure to honor IP discovery settings in some circumstances.
|
||||||
|
|
466
ddclient.in
466
ddclient.in
|
@ -145,15 +145,10 @@ our %config;
|
||||||
# host's "recap variables" -- the host's protocol's variables with a truthy `recap` property -- are
|
# host's "recap variables" -- the host's protocol's variables with a truthy `recap` property -- are
|
||||||
# included.
|
# included.
|
||||||
#
|
#
|
||||||
# `%config` is the source of truth for recap variable values. The recap variable values in
|
# `%recap` is independent of `%config`, although they both share the same set of variable
|
||||||
# `%config` are initialized with values from the cache file (via `%recap`). After initialization,
|
# declarations. There are two classes of recap variables:
|
||||||
# any change to a recap variable's value is made to `%config` and later copied to `%recap` before
|
|
||||||
# being written to the cache file. Changes made directly to `%recap` are erroneous because they
|
|
||||||
# will be overwritten by the value in `%config`.
|
|
||||||
#
|
|
||||||
# There are two classes of recap variables:
|
|
||||||
# * "Status" variables: These track update success/failure, the IP address of the last successful
|
# * "Status" variables: These track update success/failure, the IP address of the last successful
|
||||||
# update, etc. These do not hold configuration data. These should always be kept in sync with
|
# update, etc. These do not hold configuration data; they are unrelated to any entries in
|
||||||
# `%config`.
|
# `%config`.
|
||||||
# * "Configuration change detection" variables: These are used to force an update if the value in
|
# * "Configuration change detection" variables: These are used to force an update if the value in
|
||||||
# the same-named entry in `%config` has changed since the previous update attempt. The value
|
# the same-named entry in `%config` has changed since the previous update attempt. The value
|
||||||
|
@ -654,20 +649,13 @@ our %variables = (
|
||||||
'min-error-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0),
|
'min-error-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0),
|
||||||
|
|
||||||
# The desired IP address (IPv4 or IPv6, but almost always IPv4) that should be saved at the
|
# The desired IP address (IPv4 or IPv6, but almost always IPv4) that should be saved at the
|
||||||
# DDNS service.
|
# DDNS service (when `use=ip`).
|
||||||
# TODO: Legacy protocol implementations write the IP address most recently saved at the
|
|
||||||
# DDNS service to this variable so that it can be saved in the recap (as `ipv4` or `ipv6`).
|
|
||||||
# Update the legacy implementations to use `ipv4` or `ipv6` instead, though see the TODO
|
|
||||||
# for those variables.
|
|
||||||
'ip' => setv(T_IP, 0, 0, undef, undef),
|
'ip' => setv(T_IP, 0, 0, undef, undef),
|
||||||
# As a recap value, this is the IPv4 address most recently saved at the DDNS service. As a
|
# As a recap value, this is the IPv4 address most recently saved at the DDNS service. As a
|
||||||
# setting, this is the desired IPv4 address that should be saved at the DDNS service.
|
# setting, this is the desired IPv4 address that should be saved at the DDNS service.
|
||||||
# TODO: The use of `ipv4` as a recap status variable is supposed to be independent of the
|
# TODO: The use of `ipv4` as a recap status variable is independent of the use of `ipv4` as
|
||||||
# use of `ipv4` as a configuration setting. Unfortunately, because the `%config` value is
|
# a configuration setting. Rename the `%recap` status variable to something like
|
||||||
# synced to `%recap`, the two uses conflict which causes the bug "skipped: IP address was
|
# `saved-ipv4` to avoid confusion with the `%config` setting variable.
|
||||||
# already set to a.b.c.d" when the IP was never set to a.b.c.d. Rename the `%recap` status
|
|
||||||
# variable to something like `saved-ipv4` to avoid the collision (and confusion) with the
|
|
||||||
# `%config` setting variable.
|
|
||||||
'ipv4' => setv(T_IPV4, 0, 1, undef, undef),
|
'ipv4' => setv(T_IPV4, 0, 1, undef, undef),
|
||||||
# As `ipv4`, but for an IPv6 address.
|
# As `ipv4`, but for an IPv6 address.
|
||||||
'ipv6' => setv(T_IPV6, 0, 1, undef, undef),
|
'ipv6' => setv(T_IPV6, 0, 1, undef, undef),
|
||||||
|
@ -711,7 +699,7 @@ our %variables = (
|
||||||
);
|
);
|
||||||
|
|
||||||
# Converts a legacy protocol update method to behave like a modern implementation by moving
|
# 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.
|
# `$recap{$h}{status}` and `$recap{$h}{ip}` to the version-specific modern equivalents.
|
||||||
sub adapt_legacy_update {
|
sub adapt_legacy_update {
|
||||||
my ($update) = @_;
|
my ($update) = @_;
|
||||||
return sub {
|
return sub {
|
||||||
|
@ -720,7 +708,7 @@ sub adapt_legacy_update {
|
||||||
for my $h (@hosts) {
|
for my $h (@hosts) {
|
||||||
$ipv{$h} = defined($config{$h}{'wantipv4'}) ? '4' : '6';
|
$ipv{$h} = defined($config{$h}{'wantipv4'}) ? '4' : '6';
|
||||||
$config{$h}{'wantip'} = delete($config{$h}{"wantipv$ipv{$h}"});
|
$config{$h}{'wantip'} = delete($config{$h}{"wantipv$ipv{$h}"});
|
||||||
delete($config{$h}{$_}) for qw(ip status);
|
delete($recap{$h}{$_}) for qw(ip status);
|
||||||
}
|
}
|
||||||
$update->(@hosts);
|
$update->(@hosts);
|
||||||
for my $h (@hosts) {
|
for my $h (@hosts) {
|
||||||
|
@ -728,29 +716,8 @@ sub adapt_legacy_update {
|
||||||
delete($config{$h}{'wantip'});
|
delete($config{$h}{'wantip'});
|
||||||
debug(
|
debug(
|
||||||
"legacy protocol; moving 'status' to 'status-ipv$ipv{$h}', 'ip' to 'ipv$ipv{$h}'");
|
"legacy protocol; moving 'status' to 'status-ipv$ipv{$h}', 'ip' to 'ipv$ipv{$h}'");
|
||||||
$config{$h}{"status-ipv$ipv{$h}"} = delete($config{$h}{'status'});
|
$recap{$h}{"status-ipv$ipv{$h}"} = delete($recap{$h}{'status'});
|
||||||
# TODO: Currently $config{$h}{'ip'} is used for two distinct purposes: it holds the
|
$recap{$h}{"ipv$ipv{$h}"} = delete($recap{$h}{'ip'});
|
||||||
# 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;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1502,29 +1469,39 @@ sub update_nics {
|
||||||
$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) {
|
for my $h (@hosts) {
|
||||||
$config{$h}{'atime'} = $now;
|
$recap{$h}{'atime'} = $now;
|
||||||
delete($config{$h}{$_}) for qw(status-ipv4 status-ipv6 wtime
|
delete($recap{$h}{$_}) for qw(status-ipv4 status-ipv6 wtime
|
||||||
warned-min-interval warned-min-error-interval);
|
warned-min-interval warned-min-error-interval);
|
||||||
|
# Update configuration change detection variables in `%recap` with the latest
|
||||||
|
# values in `%config`. Notes about why this is done here:
|
||||||
|
# * The vars must not be updated if the host is not being updated because change
|
||||||
|
# detection is defined relative to the previous update attempt. In particular,
|
||||||
|
# these can't be updated when the protocol's `force_update` method is called
|
||||||
|
# because that method is not always called before an update is attempted.
|
||||||
|
# * The vars must be updated after the `force_update` method would be called so
|
||||||
|
# that `force_update` can check whether any settings have changed since the
|
||||||
|
# last time an update was attempted.
|
||||||
|
# * The vars are updated before the protocol's `update` method is called so that
|
||||||
|
# `update` sees consistent values between `%recap` and `%config`. This reduces
|
||||||
|
# the impact of Hyrum's Law; if a protocol needs a variable to be updated after
|
||||||
|
# the `update` method is called then that behavior should be made explicit.
|
||||||
|
my $vars = $protocols{opt('protocol', $h)}{variables};
|
||||||
|
for my $v (qw(static wildcard mx backupmx)) {
|
||||||
|
next if !$vars->{$v} || !$vars->{$v}{recap};
|
||||||
|
if (defined(my $val = opt($v, $h))) {
|
||||||
|
$recap{$h}{$v} = $val;
|
||||||
|
} else {
|
||||||
|
# Entries in `%recap` with `undef` values are deleted to avoid needing to
|
||||||
|
# figure out how to represent `undef` in the cache file and to simplify
|
||||||
|
# testing.
|
||||||
|
delete($recap{$h}{$v});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&$update(@hosts);
|
&$update(@hosts);
|
||||||
for my $h (@hosts) {
|
for my $h (@hosts) {
|
||||||
delete($config{$h}{$_}) for qw(wantipv4 wantipv6);
|
delete($config{$h}{$_}) for qw(wantipv4 wantipv6);
|
||||||
}
|
}
|
||||||
for my $h (@hosts) {
|
|
||||||
# Update `%recap` with the latest values in `%config`. This is done after the
|
|
||||||
# protocol's update method returns in case that method mutates any of the `%config`
|
|
||||||
# values or needs access to the previous iteration's `%recap` values. Entries in
|
|
||||||
# `%recap` with `undef` values are deleted to avoid needing to figure out how to
|
|
||||||
# represent `undef` in the cache file and to simplify testing. Also, entries for
|
|
||||||
# non-recap variables (which can happen after changing a host's protocol or after
|
|
||||||
# switching to a different version of ddclient) are deleted.
|
|
||||||
my $vars = $protocols{$p}{variables};
|
|
||||||
$recap{$h} = {};
|
|
||||||
for my $v (keys(%$vars)) {
|
|
||||||
next if !$vars->{$v}{recap} || !defined(opt($v, $h));
|
|
||||||
$recap{$h}{$v} = opt($v, $h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
runpostscript(join ' ', keys %ipsv4, keys %ipsv6);
|
runpostscript(join ' ', keys %ipsv4, keys %ipsv6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1614,7 +1591,6 @@ sub read_recap {
|
||||||
%opt = ();
|
%opt = ();
|
||||||
$saved_recap = _read_config(\%recap, $globals, "##\\s*$program-$version\\s*", $file);
|
$saved_recap = _read_config(\%recap, $globals, "##\\s*$program-$version\\s*", $file);
|
||||||
%opt = %saved;
|
%opt = %saved;
|
||||||
$recap{$_} //= {} for keys(%config);
|
|
||||||
for my $h (keys(%recap)) {
|
for my $h (keys(%recap)) {
|
||||||
if (!exists($config{$h})) {
|
if (!exists($config{$h})) {
|
||||||
delete($recap{$h});
|
delete($recap{$h});
|
||||||
|
@ -1624,26 +1600,6 @@ sub read_recap {
|
||||||
for my $v (keys(%{$recap{$h}})) {
|
for my $v (keys(%{$recap{$h}})) {
|
||||||
delete($recap{$h}{$v}) if !$vars->{$v} || !$vars->{$v}{recap};
|
delete($recap{$h}{$v}) if !$vars->{$v} || !$vars->{$v}{recap};
|
||||||
}
|
}
|
||||||
# Only status variables are copied from `%recap` into `%config` because the recap should
|
|
||||||
# not change the configuration. See the documenting comments for `%recap`.
|
|
||||||
# TODO: Hard-coding this list impairs readability and maintainability. In particular,
|
|
||||||
# different pieces of code need to know the list of status variables, and keeping them all
|
|
||||||
# in sync is error-prone (DRY). Also, different protocols might need different status
|
|
||||||
# variables.
|
|
||||||
# TODO: None of the recap variables should be copied into `%config` because `%config` is
|
|
||||||
# not the semantically appropriate place to record update status. Code that currently
|
|
||||||
# reads/sets `$config{$h}{'status-ipv4'}` (and friends) should instead access
|
|
||||||
# `$recap{$h}{'status-ipv4'}` directly.
|
|
||||||
for my $v (qw(atime mtime wtime ipv4 ipv6 status-ipv4 status-ipv6
|
|
||||||
warned-min-interval warned-min-error-interval)) {
|
|
||||||
next if !$vars->{$v} || !$vars->{$v}{recap};
|
|
||||||
if (defined($recap{$h}{$v})) {
|
|
||||||
$config{$h}{$v} = $recap{$h}{$v};
|
|
||||||
} else {
|
|
||||||
delete($config{$h}{$v});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete($recap{$h}) if !%{$recap{$h}};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
######################################################################
|
######################################################################
|
||||||
|
@ -3519,15 +3475,14 @@ sub nic_updateable {
|
||||||
if (($recap{$host}{'status-ipv4'} // '') eq 'good' &&
|
if (($recap{$host}{'status-ipv4'} // '') eq 'good' &&
|
||||||
!interval_expired($host, 'mtime', 'min-interval')) {
|
!interval_expired($host, 'mtime', 'min-interval')) {
|
||||||
warning("skipped update from $previpv4 to $ipv4 because it has been less than $prettyi{'min-interval'} since the previous update (on $prettyt{'mtime'})")
|
warning("skipped update from $previpv4 to $ipv4 because it has been less than $prettyi{'min-interval'} since the previous update (on $prettyt{'mtime'})")
|
||||||
if opt('verbose') || !($config{$host}{'warned-min-interval'} // 0);
|
if opt('verbose') || !($recap{$host}{'warned-min-interval'} // 0);
|
||||||
|
|
||||||
$config{$host}{'warned-min-interval'} = $now;
|
|
||||||
$recap{$host}{'warned-min-interval'} = $now;
|
$recap{$host}{'warned-min-interval'} = $now;
|
||||||
|
|
||||||
} elsif (($recap{$host}{'status-ipv4'} // '') ne 'good' &&
|
} elsif (($recap{$host}{'status-ipv4'} // '') ne 'good' &&
|
||||||
!interval_expired($host, 'atime', 'min-error-interval')) {
|
!interval_expired($host, 'atime', 'min-error-interval')) {
|
||||||
|
|
||||||
if (opt('verbose') || (!$config{$host}{'warned-min-error-interval'} &&
|
if (opt('verbose') || (!$recap{$host}{'warned-min-error-interval'} &&
|
||||||
($warned_ipv4{$host} // 0) < $inv_ip_warn_count)) {
|
($warned_ipv4{$host} // 0) < $inv_ip_warn_count)) {
|
||||||
warning("skipped update from $previpv4 to $ipv4 because it has been less than $prettyi{'min-error-interval'} since the previous update attempt (on $prettyt{'atime'}), which failed");
|
warning("skipped update from $previpv4 to $ipv4 because it has been less than $prettyi{'min-error-interval'} since the previous update attempt (on $prettyt{'atime'}), which failed");
|
||||||
if (!$ipv4 && !opt('verbose')) {
|
if (!$ipv4 && !opt('verbose')) {
|
||||||
|
@ -3537,7 +3492,6 @@ sub nic_updateable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$config{$host}{'warned-min-error-interval'} = $now;
|
|
||||||
$recap{$host}{'warned-min-error-interval'} = $now;
|
$recap{$host}{'warned-min-error-interval'} = $now;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -3548,15 +3502,14 @@ sub nic_updateable {
|
||||||
if (($recap{$host}{'status-ipv6'} // '') eq 'good' &&
|
if (($recap{$host}{'status-ipv6'} // '') eq 'good' &&
|
||||||
!interval_expired($host, 'mtime', 'min-interval')) {
|
!interval_expired($host, 'mtime', 'min-interval')) {
|
||||||
warning("skipped update from $previpv6 to $ipv6 because it has been less than $prettyi{'min-interval'} since the previous update (on $prettyt{'mtime'})")
|
warning("skipped update from $previpv6 to $ipv6 because it has been less than $prettyi{'min-interval'} since the previous update (on $prettyt{'mtime'})")
|
||||||
if opt('verbose') || !($config{$host}{'warned-min-interval'} // 0);
|
if opt('verbose') || !($recap{$host}{'warned-min-interval'} // 0);
|
||||||
|
|
||||||
$config{$host}{'warned-min-interval'} = $now;
|
|
||||||
$recap{$host}{'warned-min-interval'} = $now;
|
$recap{$host}{'warned-min-interval'} = $now;
|
||||||
|
|
||||||
} elsif (($recap{$host}{'status-ipv6'} // '') ne 'good' &&
|
} elsif (($recap{$host}{'status-ipv6'} // '') ne 'good' &&
|
||||||
!interval_expired($host, 'atime', 'min-error-interval')) {
|
!interval_expired($host, 'atime', 'min-error-interval')) {
|
||||||
|
|
||||||
if (opt('verbose') || (!$config{$host}{'warned-min-error-interval'} &&
|
if (opt('verbose') || (!$recap{$host}{'warned-min-error-interval'} &&
|
||||||
($warned_ipv6{$host} // 0) < $inv_ip_warn_count)) {
|
($warned_ipv6{$host} // 0) < $inv_ip_warn_count)) {
|
||||||
warning("skipped update from $previpv6 to $ipv6 because it has been less than $prettyi{'min-error-interval'} since the previous update attempt (on $prettyt{'atime'}, which failed");
|
warning("skipped update from $previpv6 to $ipv6 because it has been less than $prettyi{'min-error-interval'} since the previous update attempt (on $prettyt{'atime'}, which failed");
|
||||||
if (!$ipv6 && !opt('verbose')) {
|
if (!$ipv6 && !opt('verbose')) {
|
||||||
|
@ -3566,7 +3519,6 @@ sub nic_updateable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$config{$host}{'warned-min-error-interval'} = $now;
|
|
||||||
$recap{$host}{'warned-min-error-interval'} = $now;
|
$recap{$host}{'warned-min-error-interval'} = $now;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -3712,16 +3664,16 @@ sub nic_dyndns1_update {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($return_code ne 'NOERROR' || $error_code ne 'NOERROR' || !$title) {
|
if ($return_code ne 'NOERROR' || $error_code ne 'NOERROR' || !$title) {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
$title = 'incomplete response from ' . opt('server', $h) unless $title;
|
$title = 'incomplete response from ' . opt('server', $h) unless $title;
|
||||||
warning("SENT: %s", $url) unless opt('verbose');
|
warning("SENT: %s", $url) unless opt('verbose');
|
||||||
warning("REPLIED: %s", $reply);
|
warning("REPLIED: %s", $reply);
|
||||||
failed($title);
|
failed($title);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("$return_code: IP address set to $ip ($title)");
|
success("$return_code: IP address set to $ip ($title)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3868,8 +3820,8 @@ sub nic_dyndns2_update {
|
||||||
warning("$status: $errors{$status}");
|
warning("$status: $errors{$status}");
|
||||||
$status = 'good';
|
$status = 'good';
|
||||||
}
|
}
|
||||||
$config{$h}{'status-ipv4'} = $status if $ipv4;
|
$recap{$h}{'status-ipv4'} = $status if $ipv4;
|
||||||
$config{$h}{'status-ipv6'} = $status if $ipv6;
|
$recap{$h}{'status-ipv6'} = $status if $ipv6;
|
||||||
if ($status ne 'good') {
|
if ($status ne 'good') {
|
||||||
if (exists($errors{$status})) {
|
if (exists($errors{$status})) {
|
||||||
failed("$status: $errors{$status}");
|
failed("$status: $errors{$status}");
|
||||||
|
@ -3887,9 +3839,9 @@ sub nic_dyndns2_update {
|
||||||
# some services do not return the IP; and (2) comparison is brittle (e.g.,
|
# some services do not return the IP; and (2) comparison is brittle (e.g.,
|
||||||
# 192.000.002.001 vs. 192.0.2.1) and false errors could cause high load on the service
|
# 192.000.002.001 vs. 192.0.2.1) and false errors could cause high load on the service
|
||||||
# (an update attempt every min-error-interval instead of every max-interval).
|
# (an update attempt every min-error-interval instead of every max-interval).
|
||||||
$config{$h}{'ipv4'} = $ipv4 if $ipv4;
|
$recap{$h}{'ipv4'} = $ipv4 if $ipv4;
|
||||||
$config{$h}{'ipv6'} = $ipv6 if $ipv6;
|
$recap{$h}{'ipv6'} = $ipv6 if $ipv6;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
success("IPv4 address set to $ipv4") if $ipv4;
|
success("IPv4 address set to $ipv4") if $ipv4;
|
||||||
success("IPv6 address set to $ipv6") if $ipv6;
|
success("IPv6 address set to $ipv6") if $ipv6;
|
||||||
}
|
}
|
||||||
|
@ -3970,7 +3922,7 @@ sub dnsexit2_update_host {
|
||||||
my $ip = delete($config{$h}{"wantipv$ipv"}) or next;
|
my $ip = delete($config{$h}{"wantipv$ipv"}) or next;
|
||||||
$ips{$ipv} = $ip;
|
$ips{$ipv} = $ip;
|
||||||
info("updating IPv$ipv address to $ip");
|
info("updating IPv$ipv address to $ip");
|
||||||
$config{$h}{"status-ipv$ipv"} = 'failed';
|
$recap{$h}{"status-ipv$ipv"} = 'failed';
|
||||||
push(@updates, {
|
push(@updates, {
|
||||||
name => $name,
|
name => $name,
|
||||||
type => ($ipv eq '6') ? 'AAAA' : 'A',
|
type => ($ipv eq '6') ? 'AAAA' : 'A',
|
||||||
|
@ -4036,11 +3988,11 @@ sub dnsexit2_update_host {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
success($message);
|
success($message);
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
keys(%ips); # Reset internal iterator.
|
keys(%ips); # Reset internal iterator.
|
||||||
while (my ($ipv, $ip) = each(%ips)) {
|
while (my ($ipv, $ip) = each(%ips)) {
|
||||||
$config{$h}{"ipv$ipv"} = $ip;
|
$recap{$h}{"ipv$ipv"} = $ip;
|
||||||
$config{$h}{"status-ipv$ipv"} = 'good';
|
$recap{$h}{"status-ipv$ipv"} = 'good';
|
||||||
success("updated IPv$ipv address to $ip");
|
success("updated IPv$ipv address to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4100,27 +4052,27 @@ sub nic_noip_update {
|
||||||
for my $ip (split_by_comma($returnedips)) {
|
for my $ip (split_by_comma($returnedips)) {
|
||||||
next if (!$ip);
|
next if (!$ip);
|
||||||
my $ipv = ($ip eq ($ipv6 // '')) ? '6' : '4';
|
my $ipv = ($ip eq ($ipv6 // '')) ? '6' : '4';
|
||||||
$config{$h}{"status-ipv$ipv"} = $status;
|
$recap{$h}{"status-ipv$ipv"} = $status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($status eq 'good') {
|
if ($status eq 'good') {
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
for my $ip (split_by_comma($returnedips)) {
|
for my $ip (split_by_comma($returnedips)) {
|
||||||
next if (!$ip);
|
next if (!$ip);
|
||||||
my $ipv = ($ip eq ($ipv6 // '')) ? '6' : '4';
|
my $ipv = ($ip eq ($ipv6 // '')) ? '6' : '4';
|
||||||
$config{$h}{"ipv$ipv"} = $ip;
|
$recap{$h}{"ipv$ipv"} = $ip;
|
||||||
success("$status: IPv$ipv address set to $ip");
|
success("$status: IPv$ipv address set to $ip");
|
||||||
}
|
}
|
||||||
|
|
||||||
} elsif (exists $errors{$status}) {
|
} elsif (exists $errors{$status}) {
|
||||||
if ($status eq 'nochg') {
|
if ($status eq 'nochg') {
|
||||||
warning("$status: $errors{$status}");
|
warning("$status: $errors{$status}");
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
for my $ip (split_by_comma($returnedips)) {
|
for my $ip (split_by_comma($returnedips)) {
|
||||||
next if (!$ip);
|
next if (!$ip);
|
||||||
my $ipv = ($ip eq ($ipv6 // '')) ? '6' : '4';
|
my $ipv = ($ip eq ($ipv6 // '')) ? '6' : '4';
|
||||||
$config{$h}{"ipv$ipv"} = $ip;
|
$recap{$h}{"ipv$ipv"} = $ip;
|
||||||
$config{$h}{"status-ipv$ipv"} = 'good';
|
$recap{$h}{"status-ipv$ipv"} = 'good';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
failed("$status: $errors{$status}");
|
failed("$status: $errors{$status}");
|
||||||
|
@ -4135,7 +4087,7 @@ sub nic_noip_update {
|
||||||
($scale, $units) = (60*60, 'hours') if $units eq 'h';
|
($scale, $units) = (60*60, 'hours') if $units eq 'h';
|
||||||
|
|
||||||
$sec = $wait * $scale;
|
$sec = $wait * $scale;
|
||||||
$config{$h}{'wtime'} = $now + $sec;
|
$recap{$h}{'wtime'} = $now + $sec;
|
||||||
warning("$status: wait $wait $units before further updates");
|
warning("$status: wait $wait $units before further updates");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -4236,13 +4188,13 @@ sub nic_dslreports1_update {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($return_code !~ /NOERROR/) {
|
if ($return_code !~ /NOERROR/) {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
failed($reply);
|
failed($reply);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("$return_code: IP address set to $ip");
|
success("$return_code: IP address set to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4291,9 +4243,9 @@ sub nic_domeneshop_update {
|
||||||
password => opt('password', $h),
|
password => opt('password', $h),
|
||||||
);
|
);
|
||||||
next if !header_ok($reply);
|
next if !header_ok($reply);
|
||||||
$config{$h}{"ipv$ipv"} = $ip;
|
$recap{$h}{"ipv$ipv"} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{"status-ipv$ipv"} = 'good';
|
$recap{$h}{"status-ipv$ipv"} = 'good';
|
||||||
success("IPv$ipv address set to $ip");
|
success("IPv$ipv address set to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4381,14 +4333,14 @@ sub nic_zoneedit1_update {
|
||||||
$status_ip = $var{'IP'} if exists $var{'IP'};
|
$status_ip = $var{'IP'} if exists $var{'IP'};
|
||||||
|
|
||||||
if ($status eq 'SUCCESS' || ($status eq 'ERROR' && $var{'CODE'} eq '707')) {
|
if ($status eq 'SUCCESS' || ($status eq 'ERROR' && $var{'CODE'} eq '707')) {
|
||||||
$config{$h}{'ip'} = $status_ip;
|
$recap{$h}{'ip'} = $status_ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
|
|
||||||
success("IP address set to $ip ($status_code: $status_text)");
|
success("IP address set to $ip ($status_code: $status_text)");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
failed("$status_code: $status_text");
|
failed("$status_code: $status_text");
|
||||||
}
|
}
|
||||||
shift @hosts;
|
shift @hosts;
|
||||||
|
@ -4491,7 +4443,7 @@ sub nic_easydns_update {
|
||||||
# values are considered to be failures and will result in frequent retries (every
|
# values are considered to be failures and will result in frequent retries (every
|
||||||
# min-error-interval, which defaults to 5m).
|
# min-error-interval, which defaults to 5m).
|
||||||
$status = 'good' if ($status // '') =~ qr/^NOERROR|OK$/;
|
$status = 'good' if ($status // '') =~ qr/^NOERROR|OK$/;
|
||||||
$config{$h}{"status-ipv$ipv"} = $status;
|
$recap{$h}{"status-ipv$ipv"} = $status;
|
||||||
if ($status ne 'good') {
|
if ($status ne 'good') {
|
||||||
if (exists $errors{$status}) {
|
if (exists $errors{$status}) {
|
||||||
failed("$status: $errors{$status}");
|
failed("$status: $errors{$status}");
|
||||||
|
@ -4500,8 +4452,8 @@ sub nic_easydns_update {
|
||||||
}
|
}
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$config{$h}{"ipv$ipv"} = $ip;
|
$recap{$h}{"ipv$ipv"} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
success("IPv$ipv address set to $ip");
|
success("IPv$ipv address set to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4568,12 +4520,12 @@ sub nic_namecheap_update {
|
||||||
|
|
||||||
my @reply = split /\n/, $reply;
|
my @reply = split /\n/, $reply;
|
||||||
if (grep /<ErrCount>0/i, @reply) {
|
if (grep /<ErrCount>0/i, @reply) {
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
} else {
|
} else {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
failed("invalid reply: $reply");
|
failed("invalid reply: $reply");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4739,7 +4691,7 @@ sub nic_nfsn_update {
|
||||||
if ($h eq $zone) {
|
if ($h eq $zone) {
|
||||||
$name = '';
|
$name = '';
|
||||||
} elsif ($h !~ /$zone$/) {
|
} elsif ($h !~ /$zone$/) {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
failed("$h is outside zone $zone");
|
failed("$h is outside zone $zone");
|
||||||
next;
|
next;
|
||||||
} else {
|
} else {
|
||||||
|
@ -4754,7 +4706,7 @@ sub nic_nfsn_update {
|
||||||
my $list_body = encode_www_form_urlencoded({name => $name, type => 'A'});
|
my $list_body = encode_www_form_urlencoded({name => $name, type => 'A'});
|
||||||
my $list_resp = nic_nfsn_make_request($h, $list_path, 'POST', $list_body);
|
my $list_resp = nic_nfsn_make_request($h, $list_path, 'POST', $list_body);
|
||||||
if (!header_ok($list_resp)) {
|
if (!header_ok($list_resp)) {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
nic_nfsn_handle_error($list_resp, $h);
|
nic_nfsn_handle_error($list_resp, $h);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
@ -4762,7 +4714,7 @@ sub nic_nfsn_update {
|
||||||
$list_resp =~ s/^.*?\n\n//s; # Strip header
|
$list_resp =~ s/^.*?\n\n//s; # Strip header
|
||||||
my $list = eval { decode_json($list_resp) };
|
my $list = eval { decode_json($list_resp) };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
failed("JSON decoding failure");
|
failed("JSON decoding failure");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
@ -4779,7 +4731,7 @@ sub nic_nfsn_update {
|
||||||
my $rm_resp = nic_nfsn_make_request($h, $rm_path,
|
my $rm_resp = nic_nfsn_make_request($h, $rm_path,
|
||||||
'POST', $rm_body);
|
'POST', $rm_body);
|
||||||
if (!header_ok($rm_resp)) {
|
if (!header_ok($rm_resp)) {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
nic_nfsn_handle_error($rm_resp, $h);
|
nic_nfsn_handle_error($rm_resp, $h);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
@ -4794,12 +4746,12 @@ sub nic_nfsn_update {
|
||||||
my $add_resp = nic_nfsn_make_request($h, $add_path, 'POST',
|
my $add_resp = nic_nfsn_make_request($h, $add_path, 'POST',
|
||||||
$add_body);
|
$add_body);
|
||||||
if (header_ok($add_resp)) {
|
if (header_ok($add_resp)) {
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
} else {
|
} else {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
nic_nfsn_handle_error($add_resp, $h);
|
nic_nfsn_handle_error($add_resp, $h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4903,11 +4855,11 @@ sub nic_njalla_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($status eq 'good') {
|
if ($status eq 'good') {
|
||||||
$config{$h}{'ipv4'} = $ipv4 if $ipv4;
|
$recap{$h}{'ipv4'} = $ipv4 if $ipv4;
|
||||||
$config{$h}{'ipv6'} = $ipv6 if $ipv6;
|
$recap{$h}{'ipv6'} = $ipv6 if $ipv6;
|
||||||
}
|
}
|
||||||
$config{$h}{'status-ipv4'} = $status if $ipv4;
|
$recap{$h}{'status-ipv4'} = $status if $ipv4;
|
||||||
$config{$h}{'status-ipv6'} = $status if $ipv6;
|
$recap{$h}{'status-ipv6'} = $status if $ipv6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4968,12 +4920,12 @@ sub nic_sitelutions_update {
|
||||||
|
|
||||||
my @reply = split /\n/, $reply;
|
my @reply = split /\n/, $reply;
|
||||||
if (grep /success/i, @reply) {
|
if (grep /success/i, @reply) {
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
} else {
|
} else {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
warning("SENT: %s", $url) unless opt('verbose');
|
warning("SENT: %s", $url) unless opt('verbose');
|
||||||
warning("REPLIED: %s", $reply);
|
warning("REPLIED: %s", $reply);
|
||||||
failed("invalid reply");
|
failed("invalid reply");
|
||||||
|
@ -5075,8 +5027,8 @@ sub nic_freedns_update {
|
||||||
my $ipv6 = delete $config{$h}{'wantipv6'};
|
my $ipv6 = delete $config{$h}{'wantipv6'};
|
||||||
|
|
||||||
if ($record_list_error ne '') {
|
if ($record_list_error ne '') {
|
||||||
$config{$h}{'status-ipv4'} = 'failed' if ($ipv4);
|
$recap{$h}{'status-ipv4'} = 'failed' if ($ipv4);
|
||||||
$config{$h}{'status-ipv6'} = 'failed' if ($ipv6);
|
$recap{$h}{'status-ipv6'} = 'failed' if ($ipv6);
|
||||||
failed($record_list_error);
|
failed($record_list_error);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
@ -5094,12 +5046,12 @@ sub nic_freedns_update {
|
||||||
}
|
}
|
||||||
|
|
||||||
info("setting IP address to $ip");
|
info("setting IP address to $ip");
|
||||||
$config{$h}{"status-ipv$ipv"} = 'failed';
|
$recap{$h}{"status-ipv$ipv"} = 'failed';
|
||||||
|
|
||||||
if ($ip eq $rec->[1]) {
|
if ($ip eq $rec->[1]) {
|
||||||
$config{$h}{"ipv$ipv"} = $ip;
|
$recap{$h}{"ipv$ipv"} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{"status-ipv$ipv"} = 'good';
|
$recap{$h}{"status-ipv$ipv"} = 'good';
|
||||||
success("update not necessary, '$type' record already set to $ip")
|
success("update not necessary, '$type' record already set to $ip")
|
||||||
if (!$daemon || opt('verbose'));
|
if (!$daemon || opt('verbose'));
|
||||||
} else {
|
} else {
|
||||||
|
@ -5113,9 +5065,9 @@ sub nic_freedns_update {
|
||||||
if (header_ok($reply)) {
|
if (header_ok($reply)) {
|
||||||
$reply =~ s/^.*?\n\n//s; # Strip the headers.
|
$reply =~ s/^.*?\n\n//s; # Strip the headers.
|
||||||
if ($reply =~ /Updated.*$h.*to.*$ip/) {
|
if ($reply =~ /Updated.*$h.*to.*$ip/) {
|
||||||
$config{$h}{"ipv$ipv"} = $ip;
|
$recap{$h}{"ipv$ipv"} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{"status-ipv$ipv"} = 'good';
|
$recap{$h}{"status-ipv$ipv"} = 'good';
|
||||||
success("IPv$ipv address set to $ip");
|
success("IPv$ipv address set to $ip");
|
||||||
} else {
|
} else {
|
||||||
warning("SENT: %s", $url_tmpl) unless opt('verbose');
|
warning("SENT: %s", $url_tmpl) unless opt('verbose');
|
||||||
|
@ -5191,8 +5143,8 @@ sub nic_1984_update {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
$config{$host}{'status'} = 'good';
|
$recap{$host}{'status'} = 'good';
|
||||||
$config{$host}{'ip'} = $ip;
|
$recap{$host}{'ip'} = $ip;
|
||||||
if ($response->{msg} =~ /unaltered/) {
|
if ($response->{msg} =~ /unaltered/) {
|
||||||
success("skipped: IP was already set to $response->{ip}");
|
success("skipped: IP was already set to $response->{ip}");
|
||||||
} else {
|
} else {
|
||||||
|
@ -5259,12 +5211,12 @@ sub nic_changeip_update {
|
||||||
|
|
||||||
my @reply = split /\n/, $reply;
|
my @reply = split /\n/, $reply;
|
||||||
if (grep /success/i, @reply) {
|
if (grep /success/i, @reply) {
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
} else {
|
} else {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
warning("SENT: %s", $url) unless opt('verbose');
|
warning("SENT: %s", $url) unless opt('verbose');
|
||||||
warning("REPLIED: %s", $reply);
|
warning("REPLIED: %s", $reply);
|
||||||
failed("invalid reply");
|
failed("invalid reply");
|
||||||
|
@ -5380,9 +5332,9 @@ sub nic_godaddy_update {
|
||||||
failed($msg);
|
failed($msg);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$config{$h}{"ipv$ipv"} = $ip;
|
$recap{$h}{"ipv$ipv"} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{"status-ipv$ipv"} = 'good';
|
$recap{$h}{"status-ipv$ipv"} = 'good';
|
||||||
success("updated successfully to $ip (status: $code)");
|
success("updated successfully to $ip (status: $code)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5444,7 +5396,7 @@ sub nic_henet_update {
|
||||||
my ($line) = split(/\n/, $body, 2);
|
my ($line) = split(/\n/, $body, 2);
|
||||||
my ($status, $returnedip) = split(/ /, lc($line));
|
my ($status, $returnedip) = split(/ /, lc($line));
|
||||||
$status = 'good' if $status eq 'nochg';
|
$status = 'good' if $status eq 'nochg';
|
||||||
$config{$h}{"status-ipv$ipv"} = $status;
|
$recap{$h}{"status-ipv$ipv"} = $status;
|
||||||
if ($status ne 'good') {
|
if ($status ne 'good') {
|
||||||
if (exists($errors{$status})) {
|
if (exists($errors{$status})) {
|
||||||
failed("$status: $errors{$status}");
|
failed("$status: $errors{$status}");
|
||||||
|
@ -5454,8 +5406,8 @@ sub nic_henet_update {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
success("$status: IPv$ipv address set to $returnedip");
|
success("$status: IPv$ipv address set to $returnedip");
|
||||||
$config{$h}{"ipv$ipv"} = $returnedip;
|
$recap{$h}{"ipv$ipv"} = $returnedip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5524,8 +5476,8 @@ sub nic_mythicdyn_update {
|
||||||
);
|
);
|
||||||
my $ok = header_ok($reply);
|
my $ok = header_ok($reply);
|
||||||
if ($ok) {
|
if ($ok) {
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{"status-ipv$mythver"} = "good";
|
$recap{$h}{"status-ipv$mythver"} = "good";
|
||||||
|
|
||||||
success("IPv$mythver updated successfully");
|
success("IPv$mythver updated successfully");
|
||||||
}
|
}
|
||||||
|
@ -5634,12 +5586,12 @@ EoINSTR4
|
||||||
my $status = pipecmd($command, $instructions);
|
my $status = pipecmd($command, $instructions);
|
||||||
if ($status eq 1) {
|
if ($status eq 1) {
|
||||||
for (@hosts) {
|
for (@hosts) {
|
||||||
$config{$_}{'mtime'} = $now;
|
$recap{$_}{'mtime'} = $now;
|
||||||
for my $ip ($ipv4, $ipv6) {
|
for my $ip ($ipv4, $ipv6) {
|
||||||
next if (!$ip);
|
next if (!$ip);
|
||||||
my $ipv = ($ip eq ($ipv6 // '')) ? '6' : '4';
|
my $ipv = ($ip eq ($ipv6 // '')) ? '6' : '4';
|
||||||
$config{$_}{"ipv$ipv"} = $ip;
|
$recap{$_}{"ipv$ipv"} = $ip;
|
||||||
$config{$_}{"status-ipv$ipv"} = 'good';
|
$recap{$_}{"status-ipv$ipv"} = 'good';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
success("IPv4 address set to $ipv4") if $ipv4;
|
success("IPv4 address set to $ipv4") if $ipv4;
|
||||||
|
@ -5751,7 +5703,7 @@ sub nic_cloudflare_update {
|
||||||
my $type = ($ip eq ($ipv6 // '')) ? 'AAAA' : 'A';
|
my $type = ($ip eq ($ipv6 // '')) ? 'AAAA' : 'A';
|
||||||
|
|
||||||
info("setting IPv$ipv address to $ip");
|
info("setting IPv$ipv address to $ip");
|
||||||
$config{$domain}{"status-ipv$ipv"} = 'failed';
|
$recap{$domain}{"status-ipv$ipv"} = 'failed';
|
||||||
|
|
||||||
# Get DNS 'A' or 'AAAA' record ID
|
# Get DNS 'A' or 'AAAA' record ID
|
||||||
$url = "https://" . opt('server', $domain) . "/zones/$zone_id/dns_records?";
|
$url = "https://" . opt('server', $domain) . "/zones/$zone_id/dns_records?";
|
||||||
|
@ -5790,9 +5742,9 @@ sub nic_cloudflare_update {
|
||||||
$response = eval {decode_json(${^MATCH})};
|
$response = eval {decode_json(${^MATCH})};
|
||||||
if ($response && $response->{result}) {
|
if ($response && $response->{result}) {
|
||||||
success("IPv$ipv address set to $ip");
|
success("IPv$ipv address set to $ip");
|
||||||
$config{$domain}{"ipv$ipv"} = $ip;
|
$recap{$domain}{"ipv$ipv"} = $ip;
|
||||||
$config{$domain}{'mtime'} = $now;
|
$recap{$domain}{'mtime'} = $now;
|
||||||
$config{$domain}{"status-ipv$ipv"} = 'good';
|
$recap{$domain}{"status-ipv$ipv"} = 'good';
|
||||||
} else {
|
} else {
|
||||||
failed("invalid json or result");
|
failed("invalid json or result");
|
||||||
}
|
}
|
||||||
|
@ -5874,7 +5826,7 @@ sub nic_hetzner_update {
|
||||||
my $type = ($ip eq ($ipv6 // '')) ? 'AAAA' : 'A';
|
my $type = ($ip eq ($ipv6 // '')) ? 'AAAA' : 'A';
|
||||||
|
|
||||||
info("setting IPv$ipv address to $ip");
|
info("setting IPv$ipv address to $ip");
|
||||||
$config{$domain}{"status-ipv$ipv"} = 'failed';
|
$recap{$domain}{"status-ipv$ipv"} = 'failed';
|
||||||
|
|
||||||
# Get DNS 'A' or 'AAAA' record ID
|
# Get DNS 'A' or 'AAAA' record ID
|
||||||
$url = "https://" . opt('server', $domain) . "/records?zone_id=$zone_id";
|
$url = "https://" . opt('server', $domain) . "/records?zone_id=$zone_id";
|
||||||
|
@ -5919,9 +5871,9 @@ sub nic_hetzner_update {
|
||||||
$response = eval {decode_json(${^MATCH})};
|
$response = eval {decode_json(${^MATCH})};
|
||||||
if ($response && $response->{record}) {
|
if ($response && $response->{record}) {
|
||||||
success("IPv$ipv address set to $ip");
|
success("IPv$ipv address set to $ip");
|
||||||
$config{$domain}{"ipv$ipv"} = $ip;
|
$recap{$domain}{"ipv$ipv"} = $ip;
|
||||||
$config{$domain}{'mtime'} = $now;
|
$recap{$domain}{'mtime'} = $now;
|
||||||
$config{$domain}{"status-ipv$ipv"} = 'good';
|
$recap{$domain}{"status-ipv$ipv"} = 'good';
|
||||||
} else {
|
} else {
|
||||||
failed("invalid json or result");
|
failed("invalid json or result");
|
||||||
}
|
}
|
||||||
|
@ -6067,8 +6019,8 @@ sub nic_inwx_update {
|
||||||
$status = 'good';
|
$status = 'good';
|
||||||
}
|
}
|
||||||
for my $h (@hosts) {
|
for my $h (@hosts) {
|
||||||
$config{$h}{'status-ipv4'} = $status if $ipv4;
|
$recap{$h}{'status-ipv4'} = $status if $ipv4;
|
||||||
$config{$h}{'status-ipv6'} = $status if $ipv6;
|
$recap{$h}{'status-ipv6'} = $status if $ipv6;
|
||||||
}
|
}
|
||||||
if ($status ne 'good') {
|
if ($status ne 'good') {
|
||||||
if (exists($errors{$status})) {
|
if (exists($errors{$status})) {
|
||||||
|
@ -6079,9 +6031,9 @@ sub nic_inwx_update {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
for my $h (@hosts) {
|
for my $h (@hosts) {
|
||||||
$config{$h}{'ipv4'} = $ipv4 if $ipv4;
|
$recap{$h}{'ipv4'} = $ipv4 if $ipv4;
|
||||||
$config{$h}{'ipv6'} = $ipv6 if $ipv6;
|
$recap{$h}{'ipv6'} = $ipv6 if $ipv6;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
}
|
}
|
||||||
success("IPv4 address set to $ipv4") if $ipv4;
|
success("IPv4 address set to $ipv4") if $ipv4;
|
||||||
success("IPv6 address set to $ipv6") if $ipv6;
|
success("IPv6 address set to $ipv6") if $ipv6;
|
||||||
|
@ -6181,9 +6133,9 @@ sub nic_yandex_update {
|
||||||
failed("%s", $response->{error});
|
failed("%s", $response->{error});
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$config{$host}{'ip'} = $ip;
|
$recap{$host}{'ip'} = $ip;
|
||||||
$config{$host}{'mtime'} = $now;
|
$recap{$host}{'mtime'} = $now;
|
||||||
$config{$host}{'status'} = 'good';
|
$recap{$host}{'status'} = 'good';
|
||||||
success("updated successfully to $ip");
|
success("updated successfully to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6247,11 +6199,11 @@ sub nic_duckdns_update {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
for my $h (@hosts) {
|
for my $h (@hosts) {
|
||||||
$config{$h}{'ipv4'} = $ipv4 if $ipv4;
|
$recap{$h}{'ipv4'} = $ipv4 if $ipv4;
|
||||||
$config{$h}{'ipv6'} = $ipv6 if $ipv6;
|
$recap{$h}{'ipv6'} = $ipv6 if $ipv6;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status-ipv4'} = 'good' if $ipv4;
|
$recap{$h}{'status-ipv4'} = 'good' if $ipv4;
|
||||||
$config{$h}{'status-ipv6'} = 'good' if $ipv6;
|
$recap{$h}{'status-ipv6'} = 'good' if $ipv6;
|
||||||
}
|
}
|
||||||
success("IPv4 address set to $ipv4") if $ipv4;
|
success("IPv4 address set to $ipv4") if $ipv4;
|
||||||
success("IPv6 address set to $ipv6") if $ipv6;
|
success("IPv6 address set to $ipv6") if $ipv6;
|
||||||
|
@ -6302,9 +6254,9 @@ sub nic_freemyip_update {
|
||||||
failed("server said: $body");
|
failed("server said: $body");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6352,9 +6304,9 @@ sub nic_ddnsfm_update {
|
||||||
url => opt('server', $h) . "/update?key=" . opt('password', $h) . "&domain=$h&myip=$ip",
|
url => opt('server', $h) . "/update?key=" . opt('password', $h) . "&domain=$h&myip=$ip",
|
||||||
);
|
);
|
||||||
next if !header_ok($reply);
|
next if !header_ok($reply);
|
||||||
$config{$h}{"ipv$ipv"} = $ip;
|
$recap{$h}{"ipv$ipv"} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{"status-ipv$ipv"} = 'good';
|
$recap{$h}{"status-ipv$ipv"} = 'good';
|
||||||
success("IPv$ipv address set to $ip");
|
success("IPv$ipv address set to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6401,9 +6353,9 @@ sub nic_dondominio_update {
|
||||||
failed("server said: $returned");
|
failed("server said: $returned");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6465,9 +6417,9 @@ sub nic_dnsmadeeasy_update {
|
||||||
failed("server said: $err");
|
failed("server said: $err");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6533,16 +6485,16 @@ sub nic_ovh_update {
|
||||||
my @reply = split /\n/, $reply;
|
my @reply = split /\n/, $reply;
|
||||||
my $returned = List::Util::first { $_ =~ /good/ || $_ =~ /nochg/ } @reply;
|
my $returned = List::Util::first { $_ =~ /good/ || $_ =~ /nochg/ } @reply;
|
||||||
if ($returned) {
|
if ($returned) {
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
if ($returned =~ /good/) {
|
if ($returned =~ /good/) {
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
} else {
|
} else {
|
||||||
success("skipped: IP address was already set to $ip");
|
success("skipped: IP address was already set to $ip");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
failed("server said: $reply");
|
failed("server said: $reply");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6678,7 +6630,7 @@ sub nic_porkbun_update {
|
||||||
warning("There are multiple applicable records. Only first record is used. Overwrite all with the same content.")
|
warning("There are multiple applicable records. Only first record is used. Overwrite all with the same content.")
|
||||||
if @$records > 1;
|
if @$records > 1;
|
||||||
if ($records->[0]{'content'} eq $ip) {
|
if ($records->[0]{'content'} eq $ip) {
|
||||||
$config{$h}{"status-ipv$ipv"} = "good";
|
$recap{$h}{"status-ipv$ipv"} = "good";
|
||||||
success("skipped: IPv$ipv address was already set to $ip");
|
success("skipped: IPv$ipv address was already set to $ip");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
@ -6700,7 +6652,7 @@ sub nic_porkbun_update {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
next if !header_ok($reply);
|
next if !header_ok($reply);
|
||||||
$config{$h}{"status-ipv$ipv"} = "good";
|
$recap{$h}{"status-ipv$ipv"} = "good";
|
||||||
success("IPv$ipv address set to $ip");
|
success("IPv$ipv address set to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6755,14 +6707,14 @@ sub nic_cloudns_update {
|
||||||
$reply =~ s/^.*?\n\n//s; # Strip the headers.
|
$reply =~ s/^.*?\n\n//s; # Strip the headers.
|
||||||
chomp($reply);
|
chomp($reply);
|
||||||
if ($reply eq "The record's key is wrong!" || $reply eq "Invalid request.") {
|
if ($reply eq "The record's key is wrong!" || $reply eq "Invalid request.") {
|
||||||
$config{$_}{'status'} = 'failed' for @hosts;
|
$recap{$_}{'status'} = 'failed' for @hosts;
|
||||||
failed($reply);
|
failed($reply);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
# There's no documentation explaining possible return values, so we assume success.
|
# There's no documentation explaining possible return values, so we assume success.
|
||||||
$config{$_}{'ip'} = $ip for @hosts;
|
$recap{$_}{'ip'} = $ip for @hosts;
|
||||||
$config{$_}{'mtime'} = $now for @hosts;
|
$recap{$_}{'mtime'} = $now for @hosts;
|
||||||
$config{$_}{'status'} = 'good' for @hosts;
|
$recap{$_}{'status'} = 'good' for @hosts;
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6811,7 +6763,7 @@ sub nic_dinahosting_update {
|
||||||
password => opt('password', $h),
|
password => opt('password', $h),
|
||||||
url => $url,
|
url => $url,
|
||||||
);
|
);
|
||||||
$config{$h}{'status'} = 'failed'; # assume failure until otherwise determined
|
$recap{$h}{'status'} = 'failed'; # assume failure until otherwise determined
|
||||||
next if !header_ok($reply);
|
next if !header_ok($reply);
|
||||||
$reply =~ s/^.*?\n\n//s; # Strip the headers.
|
$reply =~ s/^.*?\n\n//s; # Strip the headers.
|
||||||
if ($reply !~ /Success/i) {
|
if ($reply !~ /Success/i) {
|
||||||
|
@ -6822,9 +6774,9 @@ sub nic_dinahosting_update {
|
||||||
failed("error $code: $message");
|
failed("error $code: $message");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6876,20 +6828,20 @@ sub nic_directnic_update {
|
||||||
(my $body = $reply) =~ s/^.*?\n\n//s;
|
(my $body = $reply) =~ s/^.*?\n\n//s;
|
||||||
my $response = eval {decode_json($body)};
|
my $response = eval {decode_json($body)};
|
||||||
if (ref($response) ne 'HASH') {
|
if (ref($response) ne 'HASH') {
|
||||||
$config{$h}{"status-ipv$ipv"} = 'bad';
|
$recap{$h}{"status-ipv$ipv"} = 'bad';
|
||||||
failed("response is not a JSON object:\n$body");
|
failed("response is not a JSON object:\n$body");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($response->{'result'} ne 'success') {
|
if ($response->{'result'} ne 'success') {
|
||||||
$config{$h}{"status-ipv$ipv"} = 'failed';
|
$recap{$h}{"status-ipv$ipv"} = 'failed';
|
||||||
failed("server said:\n$body");
|
failed("server said:\n$body");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
$config{$h}{"ipv$ipv"} = $ip;
|
$recap{$h}{"ipv$ipv"} = $ip;
|
||||||
$config{$h}{"status-ipv$ipv"} = 'good';
|
$recap{$h}{"status-ipv$ipv"} = 'good';
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
success("IPv$ipv address set to $ip");
|
success("IPv$ipv address set to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6972,15 +6924,15 @@ sub nic_gandi_update {
|
||||||
$reply =~ s/^.*?\n\n//s;
|
$reply =~ s/^.*?\n\n//s;
|
||||||
my $response = eval { decode_json($reply) };
|
my $response = eval { decode_json($reply) };
|
||||||
if (ref($response) ne 'HASH') {
|
if (ref($response) ne 'HASH') {
|
||||||
$config{$h}{"status-$ipv"} = "bad";
|
$recap{$h}{"status-$ipv"} = "bad";
|
||||||
failed("response is not a JSON object: $reply");
|
failed("response is not a JSON object: $reply");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
if ($response->{'rrset_values'}->[0] eq $ip && (!defined(opt('ttl', $h)) ||
|
if ($response->{'rrset_values'}->[0] eq $ip && (!defined(opt('ttl', $h)) ||
|
||||||
$response->{'rrset_ttl'} eq opt('ttl', $h))) {
|
$response->{'rrset_ttl'} eq opt('ttl', $h))) {
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{"status-$ipv"} = "good";
|
$recap{$h}{"status-$ipv"} = "good";
|
||||||
success("skipped: address was already set to $ip");
|
success("skipped: address was already set to $ip");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
@ -6995,7 +6947,7 @@ sub nic_gandi_update {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
if (!header_ok($reply)) {
|
if (!header_ok($reply)) {
|
||||||
$config{$h}{"status-$ipv"} = "bad";
|
$recap{$h}{"status-$ipv"} = "bad";
|
||||||
$reply =~ s/^.*?\n\n//s;
|
$reply =~ s/^.*?\n\n//s;
|
||||||
my $response = eval { decode_json($reply) };
|
my $response = eval { decode_json($reply) };
|
||||||
if (ref($response) eq 'HASH' && ($response->{message} // '') ne '') {
|
if (ref($response) eq 'HASH' && ($response->{message} // '') ne '') {
|
||||||
|
@ -7005,9 +6957,9 @@ sub nic_gandi_update {
|
||||||
}
|
}
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{"status-$ipv"} = "good";
|
$recap{$h}{"status-$ipv"} = "good";
|
||||||
success("updated successfully to $ip");
|
success("updated successfully to $ip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7055,12 +7007,12 @@ sub nic_keysystems_update {
|
||||||
last if !header_ok($reply);
|
last if !header_ok($reply);
|
||||||
|
|
||||||
if ($reply =~ /code = 200/) {
|
if ($reply =~ /code = 200/) {
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
} else {
|
} else {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
failed("server said: $reply");
|
failed("server said: $reply");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7109,11 +7061,11 @@ sub nic_regfishde_update {
|
||||||
failed("server said: $reply");
|
failed("server said: $reply");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$config{$h}{'ipv4'} = $ipv4 if $ipv4;
|
$recap{$h}{'ipv4'} = $ipv4 if $ipv4;
|
||||||
$config{$h}{'ipv6'} = $ipv6 if $ipv6;
|
$recap{$h}{'ipv6'} = $ipv6 if $ipv6;
|
||||||
$config{$h}{'status-ipv4'} = 'good' if $ipv4;
|
$recap{$h}{'status-ipv4'} = 'good' if $ipv4;
|
||||||
$config{$h}{'status-ipv6'} = 'good' if $ipv6;
|
$recap{$h}{'status-ipv6'} = 'good' if $ipv6;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
success("IPv4 address set to $ipv4") if $ipv4;
|
success("IPv4 address set to $ipv4") if $ipv4;
|
||||||
success("IPv6 address set to $ipv6") if $ipv6;
|
success("IPv6 address set to $ipv6") if $ipv6;
|
||||||
}
|
}
|
||||||
|
@ -7183,12 +7135,12 @@ sub nic_enom_update {
|
||||||
my @reply = split /\n/, $reply;
|
my @reply = split /\n/, $reply;
|
||||||
|
|
||||||
if (grep /Done=true/i, @reply) {
|
if (grep /Done=true/i, @reply) {
|
||||||
$config{$h}{'ip'} = $ip;
|
$recap{$h}{'ip'} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{'status'} = 'good';
|
$recap{$h}{'status'} = 'good';
|
||||||
success("IP address set to $ip");
|
success("IP address set to $ip");
|
||||||
} else {
|
} else {
|
||||||
$config{$h}{'status'} = 'failed';
|
$recap{$h}{'status'} = 'failed';
|
||||||
warning("SENT: %s", $url) unless opt('verbose');
|
warning("SENT: %s", $url) unless opt('verbose');
|
||||||
warning("REPLIED: %s", $reply);
|
warning("REPLIED: %s", $reply);
|
||||||
failed("invalid reply");
|
failed("invalid reply");
|
||||||
|
@ -7252,7 +7204,7 @@ sub nic_digitalocean_update_one {
|
||||||
|
|
||||||
my $list = eval { decode_json($list_resp) };
|
my $list = eval { decode_json($list_resp) };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
$config{$h}{"status-$ipv"} = 'failed';
|
$recap{$h}{"status-$ipv"} = 'failed';
|
||||||
failed("listing $ipv: JSON decoding failure");
|
failed("listing $ipv: JSON decoding failure");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -7261,7 +7213,7 @@ sub nic_digitalocean_update_one {
|
||||||
unless ((ref($elem) eq 'HASH') &&
|
unless ((ref($elem) eq 'HASH') &&
|
||||||
(ref ($elem = $elem->{'domain_records'}) eq 'ARRAY') &&
|
(ref ($elem = $elem->{'domain_records'}) eq 'ARRAY') &&
|
||||||
(@$elem == 1 && ref ($elem = $elem->[0]) eq 'HASH')) {
|
(@$elem == 1 && ref ($elem = $elem->[0]) eq 'HASH')) {
|
||||||
$config{$h}{"status-$ipv"} = 'failed';
|
$recap{$h}{"status-$ipv"} = 'failed';
|
||||||
failed("listing $ipv: no record, multiple records, or malformed JSON");
|
failed("listing $ipv: no record, multiple records, or malformed JSON");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -7283,9 +7235,9 @@ sub nic_digitalocean_update_one {
|
||||||
return if !header_ok($update_resp);
|
return if !header_ok($update_resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
$config{$h}{"status-$ipv"} = 'good';
|
$recap{$h}{"status-$ipv"} = 'good';
|
||||||
$config{$h}{"ip-$ipv"} = $ip;
|
$recap{$h}{"ip-$ipv"} = $ip;
|
||||||
$config{$h}{"mtime"} = $now;
|
$recap{$h}{"mtime"} = $now;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub nic_digitalocean_update {
|
sub nic_digitalocean_update {
|
||||||
|
@ -7393,9 +7345,9 @@ sub nic_infomaniak_update {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
success($msg);
|
success($msg);
|
||||||
$config{$h}{"ipv$v"} = $ip;
|
$recap{$h}{"ipv$v"} = $ip;
|
||||||
$config{$h}{'mtime'} = $now;
|
$recap{$h}{'mtime'} = $now;
|
||||||
$config{$h}{"status-ipv$v"} = 'good';
|
$recap{$h}{"status-ipv$v"} = 'good';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7417,11 +7369,11 @@ sub nic_emailonly_update {
|
||||||
logmsg(email => 1, raw => 1, join("\n", 'Host IP addresses:', map({
|
logmsg(email => 1, raw => 1, join("\n", 'Host IP addresses:', map({
|
||||||
my $ipv4 = delete($config{$_}{'wantipv4'});
|
my $ipv4 = delete($config{$_}{'wantipv4'});
|
||||||
my $ipv6 = delete($config{$_}{'wantipv6'});
|
my $ipv6 = delete($config{$_}{'wantipv6'});
|
||||||
$config{$_}{'status-ipv4'} = 'good' if $ipv4;
|
$recap{$_}{'status-ipv4'} = 'good' if $ipv4;
|
||||||
$config{$_}{'status-ipv6'} = 'good' if $ipv6;
|
$recap{$_}{'status-ipv6'} = 'good' if $ipv6;
|
||||||
$config{$_}{'ipv4'} = $ipv4 if $ipv4;
|
$recap{$_}{'ipv4'} = $ipv4 if $ipv4;
|
||||||
$config{$_}{'ipv6'} = $ipv6 if $ipv6;
|
$recap{$_}{'ipv6'} = $ipv6 if $ipv6;
|
||||||
$config{$_}{'mtime'} = $now;
|
$recap{$_}{'mtime'} = $now;
|
||||||
sprintf('%30s %s', $_, join(' ', grep(defined($_), $ipv4, $ipv6)));
|
sprintf('%30s %s', $_, join(' ', grep(defined($_), $ipv4, $ipv6)));
|
||||||
} @_)));
|
} @_)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ my @test_cases = (
|
||||||
{
|
{
|
||||||
desc => 'IPv4, good',
|
desc => 'IPv4, good',
|
||||||
cfg => {h1 => {urlv4 => "$hostname/dns/gateway/abc/", wantipv4 => '192.0.2.1'}},
|
cfg => {h1 => {urlv4 => "$hostname/dns/gateway/abc/", wantipv4 => '192.0.2.1'}},
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
},
|
},
|
||||||
wantlogs => [
|
wantlogs => [
|
||||||
|
@ -62,7 +62,7 @@ my @test_cases = (
|
||||||
{
|
{
|
||||||
desc => 'IPv4, failed',
|
desc => 'IPv4, failed',
|
||||||
cfg => {h1 => {urlv4 => "$hostname/dns/gateway/bad_token/", wantipv4 => '192.0.2.1'}},
|
cfg => {h1 => {urlv4 => "$hostname/dns/gateway/bad_token/", wantipv4 => '192.0.2.1'}},
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'failed'},
|
h1 => {'status-ipv4' => 'failed'},
|
||||||
},
|
},
|
||||||
wantlogs => [
|
wantlogs => [
|
||||||
|
@ -72,7 +72,7 @@ my @test_cases = (
|
||||||
{
|
{
|
||||||
desc => 'IPv4, bad',
|
desc => 'IPv4, bad',
|
||||||
cfg => {h1 => {urlv4 => "$hostname/bad/path/", wantipv4 => '192.0.2.1'}},
|
cfg => {h1 => {urlv4 => "$hostname/bad/path/", wantipv4 => '192.0.2.1'}},
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'bad'},
|
h1 => {'status-ipv4' => 'bad'},
|
||||||
},
|
},
|
||||||
wantlogs => [
|
wantlogs => [
|
||||||
|
@ -82,7 +82,7 @@ my @test_cases = (
|
||||||
{
|
{
|
||||||
desc => 'IPv4, unexpected response',
|
desc => 'IPv4, unexpected response',
|
||||||
cfg => {h1 => {urlv4 => "$hostname/unexpected/path/", wantipv4 => '192.0.2.1'}},
|
cfg => {h1 => {urlv4 => "$hostname/unexpected/path/", wantipv4 => '192.0.2.1'}},
|
||||||
wantstatus => {h1 => {}},
|
wantrecap => {},
|
||||||
wantlogs => [
|
wantlogs => [
|
||||||
{label => 'FAILED', ctx => ['h1'], msg => qr/400 Bad Request/},
|
{label => 'FAILED', ctx => ['h1'], msg => qr/400 Bad Request/},
|
||||||
],
|
],
|
||||||
|
@ -90,7 +90,7 @@ my @test_cases = (
|
||||||
{
|
{
|
||||||
desc => 'IPv4, no urlv4',
|
desc => 'IPv4, no urlv4',
|
||||||
cfg => {h1 => {wantipv4 => '192.0.2.1'}},
|
cfg => {h1 => {wantipv4 => '192.0.2.1'}},
|
||||||
wantstatus => {h1 => {}},
|
wantrecap => {},
|
||||||
wantlogs => [
|
wantlogs => [
|
||||||
{label => 'FAILED', ctx => ['h1'], msg => qr/missing urlv4 option/},
|
{label => 'FAILED', ctx => ['h1'], msg => qr/missing urlv4 option/},
|
||||||
],
|
],
|
||||||
|
@ -98,7 +98,7 @@ my @test_cases = (
|
||||||
{
|
{
|
||||||
desc => 'IPv6, good',
|
desc => 'IPv6, good',
|
||||||
cfg => {h1 => {urlv6 => "$hostname/dns/gateway/abc/", wantipv6 => '2001:db8::1'}},
|
cfg => {h1 => {urlv6 => "$hostname/dns/gateway/abc/", wantipv6 => '2001:db8::1'}},
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv6' => 'good', 'ipv6' => '2001:db8::1', 'mtime' => $ddclient::now},
|
h1 => {'status-ipv6' => 'good', 'ipv6' => '2001:db8::1', 'mtime' => $ddclient::now},
|
||||||
},
|
},
|
||||||
wantlogs => [
|
wantlogs => [
|
||||||
|
@ -113,7 +113,7 @@ my @test_cases = (
|
||||||
wantipv4 => '192.0.2.1',
|
wantipv4 => '192.0.2.1',
|
||||||
wantipv6 => '2001:db8::1',
|
wantipv6 => '2001:db8::1',
|
||||||
}},
|
}},
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1',
|
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1',
|
||||||
'status-ipv6' => 'good', 'ipv6' => '2001:db8::1',
|
'status-ipv6' => 'good', 'ipv6' => '2001:db8::1',
|
||||||
'mtime' => $ddclient::now},
|
'mtime' => $ddclient::now},
|
||||||
|
@ -132,7 +132,7 @@ my @test_cases = (
|
||||||
wantipv6 => '2001:db8::1',
|
wantipv6 => '2001:db8::1',
|
||||||
}},
|
}},
|
||||||
wantips => {h1 => {wantipv4 => '192.0.2.1', wantipv6 => '2001:db8::1'}},
|
wantips => {h1 => {wantipv4 => '192.0.2.1', wantipv6 => '2001:db8::1'}},
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'failed',
|
h1 => {'status-ipv4' => 'failed',
|
||||||
'status-ipv6' => 'good', 'ipv6' => '2001:db8::1',
|
'status-ipv6' => 'good', 'ipv6' => '2001:db8::1',
|
||||||
'mtime' => $ddclient::now},
|
'mtime' => $ddclient::now},
|
||||||
|
@ -152,20 +152,14 @@ for my $tc (@test_cases) {
|
||||||
local $ddclient::globals{verbose} = 1;
|
local $ddclient::globals{verbose} = 1;
|
||||||
my $l = Logger->new($ddclient::_l);
|
my $l = Logger->new($ddclient::_l);
|
||||||
local %ddclient::config = %{$tc->{cfg}};
|
local %ddclient::config = %{$tc->{cfg}};
|
||||||
|
local %ddclient::recap;
|
||||||
{
|
{
|
||||||
local $ddclient::_l = $l;
|
local $ddclient::_l = $l;
|
||||||
ddclient::nic_directnic_update(sort(keys(%{$tc->{cfg}})));
|
ddclient::nic_directnic_update(sort(keys(%{$tc->{cfg}})));
|
||||||
}
|
}
|
||||||
# These are the properties in %ddclient::config to check against $tc->{wantstatus}.
|
is_deeply(\%ddclient::recap, $tc->{wantrecap}, "$tc->{desc}: recap")
|
||||||
my %statuskeys = map(($_ => undef), qw(atime ip ipv4 ipv6 mtime status status-ipv4 status-ipv6
|
or diag(ddclient::repr(Values => [\%ddclient::recap, $tc->{wantrecap}],
|
||||||
wantip wantipv4 wantipv6 wtime));
|
Names => ['*got', '*want']));
|
||||||
my %gotstatus;
|
|
||||||
for my $h (keys(%ddclient::config)) {
|
|
||||||
$gotstatus{$h} = {map(($_ => $ddclient::config{$h}{$_}),
|
|
||||||
grep(exists($statuskeys{$_}), keys(%{$ddclient::config{$h}})))};
|
|
||||||
}
|
|
||||||
is_deeply(\%gotstatus, $tc->{wantstatus}, "$tc->{desc}: status")
|
|
||||||
or diag(ddclient::repr(\%ddclient::config, Names => ['*ddclient::config']));
|
|
||||||
$tc->{wantlogs} //= [];
|
$tc->{wantlogs} //= [];
|
||||||
subtest("$tc->{desc}: logs" => sub {
|
subtest("$tc->{desc}: logs" => sub {
|
||||||
my @got = @{$l->{logs}};
|
my @got = @{$l->{logs}};
|
||||||
|
|
|
@ -45,7 +45,7 @@ my @test_cases = (
|
||||||
cfg => {h1 => {wantipv4 => '192.0.2.1'}},
|
cfg => {h1 => {wantipv4 => '192.0.2.1'}},
|
||||||
resp => ['good'],
|
resp => ['good'],
|
||||||
wantquery => 'hostname=h1&myip=192.0.2.1',
|
wantquery => 'hostname=h1&myip=192.0.2.1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
},
|
},
|
||||||
wantlogs => [
|
wantlogs => [
|
||||||
|
@ -57,7 +57,7 @@ my @test_cases = (
|
||||||
cfg => {h1 => {wantipv4 => '192.0.2.1'}},
|
cfg => {h1 => {wantipv4 => '192.0.2.1'}},
|
||||||
resp => ['nochg'],
|
resp => ['nochg'],
|
||||||
wantquery => 'hostname=h1&myip=192.0.2.1',
|
wantquery => 'hostname=h1&myip=192.0.2.1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
},
|
},
|
||||||
wantlogs => [
|
wantlogs => [
|
||||||
|
@ -70,7 +70,7 @@ my @test_cases = (
|
||||||
cfg => {h1 => {wantipv4 => '192.0.2.1'}},
|
cfg => {h1 => {wantipv4 => '192.0.2.1'}},
|
||||||
resp => ['nohost'],
|
resp => ['nohost'],
|
||||||
wantquery => 'hostname=h1&myip=192.0.2.1',
|
wantquery => 'hostname=h1&myip=192.0.2.1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'nohost'},
|
h1 => {'status-ipv4' => 'nohost'},
|
||||||
},
|
},
|
||||||
wantlogs => [
|
wantlogs => [
|
||||||
|
@ -82,7 +82,7 @@ my @test_cases = (
|
||||||
cfg => {h1 => {wantipv4 => '192.0.2.1'}},
|
cfg => {h1 => {wantipv4 => '192.0.2.1'}},
|
||||||
resp => ['WAT'],
|
resp => ['WAT'],
|
||||||
wantquery => 'hostname=h1&myip=192.0.2.1',
|
wantquery => 'hostname=h1&myip=192.0.2.1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'WAT'},
|
h1 => {'status-ipv4' => 'WAT'},
|
||||||
},
|
},
|
||||||
wantlogs => [
|
wantlogs => [
|
||||||
|
@ -100,7 +100,7 @@ my @test_cases = (
|
||||||
'good',
|
'good',
|
||||||
],
|
],
|
||||||
wantquery => 'hostname=h1,h2&myip=192.0.2.1',
|
wantquery => 'hostname=h1,h2&myip=192.0.2.1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
h2 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h2 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
},
|
},
|
||||||
|
@ -122,7 +122,7 @@ my @test_cases = (
|
||||||
'dnserr',
|
'dnserr',
|
||||||
],
|
],
|
||||||
wantquery => 'hostname=h1,h2,h3&myip=192.0.2.1',
|
wantquery => 'hostname=h1,h2,h3&myip=192.0.2.1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
h2 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h2 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
h3 => {'status-ipv4' => 'dnserr'},
|
h3 => {'status-ipv4' => 'dnserr'},
|
||||||
|
@ -139,7 +139,7 @@ my @test_cases = (
|
||||||
cfg => {h1 => {wantipv6 => '2001:db8::1'}},
|
cfg => {h1 => {wantipv6 => '2001:db8::1'}},
|
||||||
resp => ['good'],
|
resp => ['good'],
|
||||||
wantquery => 'hostname=h1&myip=2001:db8::1',
|
wantquery => 'hostname=h1&myip=2001:db8::1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv6' => 'good', 'ipv6' => '2001:db8::1', 'mtime' => $ddclient::now},
|
h1 => {'status-ipv6' => 'good', 'ipv6' => '2001:db8::1', 'mtime' => $ddclient::now},
|
||||||
},
|
},
|
||||||
wantlogs => [
|
wantlogs => [
|
||||||
|
@ -151,7 +151,7 @@ my @test_cases = (
|
||||||
cfg => {h1 => {wantipv4 => '192.0.2.1', wantipv6 => '2001:db8::1'}},
|
cfg => {h1 => {wantipv4 => '192.0.2.1', wantipv6 => '2001:db8::1'}},
|
||||||
resp => ['good'],
|
resp => ['good'],
|
||||||
wantquery => 'hostname=h1&myip=192.0.2.1,2001:db8::1',
|
wantquery => 'hostname=h1&myip=192.0.2.1,2001:db8::1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1',
|
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1',
|
||||||
'status-ipv6' => 'good', 'ipv6' => '2001:db8::1',
|
'status-ipv6' => 'good', 'ipv6' => '2001:db8::1',
|
||||||
'mtime' => $ddclient::now},
|
'mtime' => $ddclient::now},
|
||||||
|
@ -173,7 +173,7 @@ my @test_cases = (
|
||||||
'WAT',
|
'WAT',
|
||||||
],
|
],
|
||||||
wantquery => 'hostname=h1,h2&myip=192.0.2.1',
|
wantquery => 'hostname=h1,h2&myip=192.0.2.1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
h2 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h2 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
},
|
},
|
||||||
|
@ -191,7 +191,7 @@ my @test_cases = (
|
||||||
},
|
},
|
||||||
resp => ['abuse'],
|
resp => ['abuse'],
|
||||||
wantquery => 'hostname=h1,h2&myip=192.0.2.1',
|
wantquery => 'hostname=h1,h2&myip=192.0.2.1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'abuse'},
|
h1 => {'status-ipv4' => 'abuse'},
|
||||||
h2 => {'status-ipv4' => 'abuse'},
|
h2 => {'status-ipv4' => 'abuse'},
|
||||||
},
|
},
|
||||||
|
@ -208,7 +208,7 @@ my @test_cases = (
|
||||||
},
|
},
|
||||||
resp => ['good'],
|
resp => ['good'],
|
||||||
wantquery => 'hostname=h1,h2&myip=192.0.2.1',
|
wantquery => 'hostname=h1,h2&myip=192.0.2.1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
h2 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h2 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
},
|
},
|
||||||
|
@ -230,7 +230,7 @@ my @test_cases = (
|
||||||
'nochg',
|
'nochg',
|
||||||
],
|
],
|
||||||
wantquery => 'hostname=h1,h2,h3&myip=192.0.2.1',
|
wantquery => 'hostname=h1,h2,h3&myip=192.0.2.1',
|
||||||
wantstatus => {
|
wantrecap => {
|
||||||
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h1 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
h2 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
h2 => {'status-ipv4' => 'good', 'ipv4' => '192.0.2.1', 'mtime' => $ddclient::now},
|
||||||
h3 => {'status-ipv4' => 'unknown'},
|
h3 => {'status-ipv4' => 'unknown'},
|
||||||
|
@ -252,6 +252,7 @@ for my $tc (@test_cases) {
|
||||||
local $ddclient::globals{verbose} = 1;
|
local $ddclient::globals{verbose} = 1;
|
||||||
my $l = Logger->new($ddclient::_l);
|
my $l = Logger->new($ddclient::_l);
|
||||||
local %ddclient::config;
|
local %ddclient::config;
|
||||||
|
local %ddclient::recap;
|
||||||
$ddclient::config{$_} = {
|
$ddclient::config{$_} = {
|
||||||
login => 'username',
|
login => 'username',
|
||||||
password => 'password',
|
password => 'password',
|
||||||
|
@ -267,18 +268,9 @@ for my $tc (@test_cases) {
|
||||||
local $ddclient::_l = $l;
|
local $ddclient::_l = $l;
|
||||||
ddclient::nic_dyndns2_update(sort(keys(%{$tc->{cfg}})));
|
ddclient::nic_dyndns2_update(sort(keys(%{$tc->{cfg}})));
|
||||||
}
|
}
|
||||||
# These are the properties in %ddclient::config to check against $tc->{wantstatus}. Keys are
|
is_deeply(\%ddclient::recap, $tc->{wantrecap}, "$tc->{desc}: recap")
|
||||||
# explicitly listed here rather than read from $tc->{wantstatus} to ensure that entries that
|
or diag(ddclient::repr(Values => [\%ddclient::recap, $tc->{wantrecap}],
|
||||||
# should not exist (e.g., wantipv4 and friends) are deleted (or never set).
|
Names => ['*got', '*want']));
|
||||||
my %statuskeys = map(($_ => undef), qw(atime ip ipv4 ipv6 mtime status status-ipv4 status-ipv6
|
|
||||||
wantip wantipv4 wantipv6 wtime));
|
|
||||||
my %gotstatus;
|
|
||||||
for my $h (keys(%ddclient::config)) {
|
|
||||||
$gotstatus{$h} = {map(($_ => $ddclient::config{$h}{$_}),
|
|
||||||
grep(exists($statuskeys{$_}), keys(%{$ddclient::config{$h}})))};
|
|
||||||
}
|
|
||||||
is_deeply(\%gotstatus, $tc->{wantstatus}, "$tc->{desc}: status")
|
|
||||||
or diag(ddclient::repr(\%ddclient::config, Names => ['*ddclient::config']));
|
|
||||||
$tc->{wantlogs} //= [];
|
$tc->{wantlogs} //= [];
|
||||||
subtest("$tc->{desc}: logs" => sub {
|
subtest("$tc->{desc}: logs" => sub {
|
||||||
my @got = @{$l->{logs}};
|
my @got = @{$l->{logs}};
|
||||||
|
|
119
t/read_recap.pl
119
t/read_recap.pl
|
@ -1,6 +1,5 @@
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use File::Temp;
|
use File::Temp;
|
||||||
use Scalar::Util qw(refaddr);
|
|
||||||
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
|
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
|
||||||
eval { require 'ddclient'; } or BAIL_OUT($@);
|
eval { require 'ddclient'; } or BAIL_OUT($@);
|
||||||
|
|
||||||
|
@ -9,42 +8,26 @@ local $ddclient::globals{verbose} = 1;
|
||||||
local %ddclient::protocols = (
|
local %ddclient::protocols = (
|
||||||
protocol_a => {
|
protocol_a => {
|
||||||
variables => {
|
variables => {
|
||||||
'host' => {type => ddclient::T_STRING(), recap => 1},
|
host => {type => ddclient::T_STRING(), recap => 1},
|
||||||
'mtime' => {type => ddclient::T_NUMBER(), recap => 1},
|
var_a => {type => ddclient::T_BOOL(), recap => 1},
|
||||||
'atime' => {type => ddclient::T_NUMBER(), recap => 1},
|
|
||||||
'wtime' => {type => ddclient::T_NUMBER(), recap => 1},
|
|
||||||
'ip' => {type => ddclient::T_IP(), recap => 1},
|
|
||||||
'ipv4' => {type => ddclient::T_IPV4(), recap => 1},
|
|
||||||
'ipv6' => {type => ddclient::T_IPV6(), recap => 1},
|
|
||||||
'status' => {type => ddclient::T_ANY(), recap => 1},
|
|
||||||
'status-ipv4' => {type => ddclient::T_ANY(), recap => 1},
|
|
||||||
'status-ipv6' => {type => ddclient::T_ANY(), recap => 1},
|
|
||||||
'warned-min-error-interval' => {type => ddclient::T_ANY(), recap => 1},
|
|
||||||
'warned-min-interval' => {type => ddclient::T_ANY(), recap => 1},
|
|
||||||
|
|
||||||
'var_a' => {type => ddclient::T_BOOL(), recap => 1},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
protocol_b => {
|
protocol_b => {
|
||||||
variables => {
|
variables => {
|
||||||
'host' => {type => ddclient::T_STRING(), recap => 1},
|
host => {type => ddclient::T_STRING(), recap => 1},
|
||||||
'mtime' => {type => ddclient::T_NUMBER()}, # Intentionally not a recap var.
|
var_b => {type => ddclient::T_NUMBER(), recap => 1},
|
||||||
'var_b' => {type => ddclient::T_NUMBER(), recap => 1},
|
var_b_non_recap => {type => ddclient::T_ANY()},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
local %ddclient::variables =
|
local %ddclient::variables =
|
||||||
(merged => {map({ %{$ddclient::protocols{$_}{variables}}; } sort(keys(%ddclient::protocols)))});
|
(merged => {map({ %{$ddclient::protocols{$_}{variables}}; } sort(keys(%ddclient::protocols)))});
|
||||||
|
|
||||||
# Sentinel value that means "this hash entry should be deleted."
|
|
||||||
my $DOES_NOT_EXIST = [];
|
|
||||||
|
|
||||||
my @test_cases = (
|
my @test_cases = (
|
||||||
{
|
{
|
||||||
desc => "ok value",
|
desc => "ok value",
|
||||||
cachefile_lines => ["var_a=yes host_a"],
|
cachefile_lines => ["var_a=yes host_a"],
|
||||||
want => {host_a => {host => 'host_a', var_a => 1}},
|
want => {host_a => {host => 'host_a', var_a => 1}},
|
||||||
# No config changes are expected because `var_a` is not a "status" recap var.
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc => "unknown host",
|
desc => "unknown host",
|
||||||
|
@ -71,80 +54,16 @@ my @test_cases = (
|
||||||
host_a => {host => 'host_a', var_a => 1},
|
host_a => {host => 'host_a', var_a => 1},
|
||||||
host_b => {host => 'host_b', var_b => 123},
|
host_b => {host => 'host_b', var_b => 123},
|
||||||
},
|
},
|
||||||
# No config changes are expected because `var_a` and `var_b` are not "status" recap vars.
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc => "used to be status vars",
|
desc => "non-recap vars are not loaded to %recap",
|
||||||
cachefile_lines => ["ip=192.0.2.1,status=good host_a"],
|
cachefile_lines => ["var_b_non_recap=foo host_b"],
|
||||||
want => {host_a => {host => 'host_a', ip => '192.0.2.1', status => 'good'}},
|
|
||||||
# No config changes are expected because `ip` and `status` are no longer "status" recap
|
|
||||||
# vars.
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc => "status vars",
|
|
||||||
cachefile_lines => ["mtime=1234567890,atime=1234567891,wtime=1234567892,ipv4=192.0.2.1,ipv6=2001:db8::1,status-ipv4=good,status-ipv6=bad,warned-min-interval=1234567893,warned-min-error-interval=1234567894 host_a"],
|
|
||||||
want => {host_a => {
|
|
||||||
'host' => 'host_a',
|
|
||||||
'mtime' => 1234567890,
|
|
||||||
'atime' => 1234567891,
|
|
||||||
'wtime' => 1234567892,
|
|
||||||
'ipv4' => '192.0.2.1',
|
|
||||||
'ipv6' => '2001:db8::1',
|
|
||||||
'status-ipv4' => 'good',
|
|
||||||
'status-ipv6' => 'bad',
|
|
||||||
'warned-min-interval' => 1234567893,
|
|
||||||
'warned-min-error-interval' => 1234567894,
|
|
||||||
}},
|
|
||||||
want_config_changes => {host_a => {
|
|
||||||
'mtime' => 1234567890,
|
|
||||||
'atime' => 1234567891,
|
|
||||||
'wtime' => 1234567892,
|
|
||||||
'ipv4' => '192.0.2.1',
|
|
||||||
'ipv6' => '2001:db8::1',
|
|
||||||
'status-ipv4' => 'good',
|
|
||||||
'status-ipv6' => 'bad',
|
|
||||||
'warned-min-interval' => 1234567893,
|
|
||||||
'warned-min-error-interval' => 1234567894,
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc => "unset status var clears config",
|
|
||||||
cachefile_lines => ["host_a"],
|
|
||||||
config => {host_a => {
|
|
||||||
'mtime' => 1234567890,
|
|
||||||
'atime' => 1234567891,
|
|
||||||
'wtime' => 1234567892,
|
|
||||||
'ipv4' => '192.0.2.1',
|
|
||||||
'ipv6' => '2001:db8::1',
|
|
||||||
'status-ipv4' => 'good',
|
|
||||||
'status-ipv6' => 'bad',
|
|
||||||
'warned-min-interval' => 1234567893,
|
|
||||||
'warned-min-error-interval' => 1234567894,
|
|
||||||
'var_a' => 1,
|
|
||||||
}},
|
|
||||||
want => {host_a => {host => 'host_a'}},
|
|
||||||
want_config_changes => {host_a => {
|
|
||||||
'mtime' => $DOES_NOT_EXIST,
|
|
||||||
'atime' => $DOES_NOT_EXIST,
|
|
||||||
'wtime' => $DOES_NOT_EXIST,
|
|
||||||
'ipv4' => $DOES_NOT_EXIST,
|
|
||||||
'ipv6' => $DOES_NOT_EXIST,
|
|
||||||
'status-ipv4' => $DOES_NOT_EXIST,
|
|
||||||
'status-ipv6' => $DOES_NOT_EXIST,
|
|
||||||
'warned-min-interval' => $DOES_NOT_EXIST,
|
|
||||||
'warned-min-error-interval' => $DOES_NOT_EXIST,
|
|
||||||
# `var_a` should remain untouched.
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc => "non-recap vars are not loaded to %recap or copied to %config",
|
|
||||||
cachefile_lines => ["mtime=1234567890 host_b"],
|
|
||||||
want => {host_b => {host => 'host_b'}},
|
want => {host_b => {host => 'host_b'}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc => "non-recap vars are scrubbed from %recap",
|
desc => "non-recap vars are scrubbed from %recap",
|
||||||
cachefile_lines => ["mtime=1234567890 host_b"],
|
cachefile_lines => ["var_b_non_recap=foo host_b"],
|
||||||
recap => {host_b => {host => 'host_b', mtime => 1234567891}},
|
recap => {host_b => {host => 'host_b', var_b_non_recap => 'foo'}},
|
||||||
want => {host_b => {host => 'host_b'}},
|
want => {host_b => {host => 'host_b'}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -166,8 +85,6 @@ for my $tc (@test_cases) {
|
||||||
host_a => {protocol => 'protocol_a'},
|
host_a => {protocol => 'protocol_a'},
|
||||||
host_b => {protocol => 'protocol_b'},
|
host_b => {protocol => 'protocol_b'},
|
||||||
);
|
);
|
||||||
$tc->{config} //= {};
|
|
||||||
$want_config{$_} = {%{$want_config{$_} // {}}, %{$tc->{config}{$_}}} for keys(%{$tc->{config}});
|
|
||||||
# Deep clone %want_config so we can check for changes.
|
# Deep clone %want_config so we can check for changes.
|
||||||
local %ddclient::config;
|
local %ddclient::config;
|
||||||
$ddclient::config{$_} = {%{$want_config{$_}}} for keys(%want_config);
|
$ddclient::config{$_} = {%{$want_config{$_}}} for keys(%want_config);
|
||||||
|
@ -180,21 +97,9 @@ for my $tc (@test_cases) {
|
||||||
or diag(ddclient::repr(Values => [\%ddclient::recap, $tc->{want}],
|
or diag(ddclient::repr(Values => [\%ddclient::recap, $tc->{want}],
|
||||||
Names => ['*got', '*want']));
|
Names => ['*got', '*want']));
|
||||||
}
|
}
|
||||||
TODO: {
|
is_deeply(\%ddclient::config, \%want_config, "$tc->{desc}: %config")
|
||||||
local $TODO = $tc->{want_config_changes_TODO};
|
or diag(ddclient::repr(Values => [\%ddclient::config, \%want_config],
|
||||||
$tc->{want_config_changes} //= {};
|
Names => ['*got', '*want']));
|
||||||
$want_config{$_} = {%{$want_config{$_} // {}}, %{$tc->{want_config_changes}{$_}}}
|
|
||||||
for keys(%{$tc->{want_config_changes}});
|
|
||||||
for my $h (keys(%want_config)) {
|
|
||||||
for my $k (keys(%{$want_config{$h}})) {
|
|
||||||
my $a = refaddr($want_config{$h}{$k});
|
|
||||||
delete($want_config{$h}{$k}) if defined($a) && $a == refaddr($DOES_NOT_EXIST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is_deeply(\%ddclient::config, \%want_config, "$tc->{desc}: %config")
|
|
||||||
or diag(ddclient::repr(Values => [\%ddclient::config, \%want_config],
|
|
||||||
Names => ['*got', '*want']));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing();
|
done_testing();
|
||||||
|
|
|
@ -54,9 +54,9 @@ local %ddclient::protocols = (
|
||||||
local $ddclient::_l = ddclient::pushlogctx($h);
|
local $ddclient::_l = ddclient::pushlogctx($h);
|
||||||
ddclient::debug('updating host');
|
ddclient::debug('updating host');
|
||||||
push(@updates, [@_]);
|
push(@updates, [@_]);
|
||||||
$ddclient::config{$h}{status} = 'good';
|
$ddclient::recap{$h}{status} = 'good';
|
||||||
$ddclient::config{$h}{ip} = delete($ddclient::config{$h}{wantip});
|
$ddclient::recap{$h}{ip} = delete($ddclient::config{$h}{wantip});
|
||||||
$ddclient::config{$h}{mtime} = $ddclient::now;
|
$ddclient::recap{$h}{mtime} = $ddclient::now;
|
||||||
}
|
}
|
||||||
ddclient::debug('returning from update');
|
ddclient::debug('returning from update');
|
||||||
}),
|
}),
|
||||||
|
@ -83,12 +83,6 @@ my @test_cases = (
|
||||||
'mtime' => $ddclient::now,
|
'mtime' => $ddclient::now,
|
||||||
'status-ipv4' => 'good',
|
'status-ipv4' => 'good',
|
||||||
},
|
},
|
||||||
want_cfg_changes => {
|
|
||||||
'atime' => $ddclient::now,
|
|
||||||
'ipv4' => '192.0.2.1',
|
|
||||||
'mtime' => $ddclient::now,
|
|
||||||
'status-ipv4' => 'good',
|
|
||||||
},
|
|
||||||
%$_,
|
%$_,
|
||||||
};
|
};
|
||||||
} {cfg => {use => 'web'}}, {cfg => {usev4 => 'webv4'}}),
|
} {cfg => {use => 'web'}}, {cfg => {usev4 => 'webv4'}}),
|
||||||
|
@ -107,12 +101,6 @@ my @test_cases = (
|
||||||
'mtime' => $ddclient::now,
|
'mtime' => $ddclient::now,
|
||||||
'status-ipv6' => 'good',
|
'status-ipv6' => 'good',
|
||||||
},
|
},
|
||||||
want_cfg_changes => {
|
|
||||||
'atime' => $ddclient::now,
|
|
||||||
'ipv6' => '2001:db8::1',
|
|
||||||
'mtime' => $ddclient::now,
|
|
||||||
'status-ipv6' => 'good',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc => 'legacy, fresh, usev6=webv6',
|
desc => 'legacy, fresh, usev6=webv6',
|
||||||
|
@ -128,12 +116,6 @@ my @test_cases = (
|
||||||
'mtime' => $ddclient::now,
|
'mtime' => $ddclient::now,
|
||||||
'status-ipv6' => 'good',
|
'status-ipv6' => 'good',
|
||||||
},
|
},
|
||||||
want_cfg_changes => {
|
|
||||||
'atime' => $ddclient::now,
|
|
||||||
'ipv6' => '2001:db8::1',
|
|
||||||
'mtime' => $ddclient::now,
|
|
||||||
'status-ipv6' => 'good',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc => 'legacy, fresh, usev4=webv4 usev6=webv6',
|
desc => 'legacy, fresh, usev4=webv4 usev6=webv6',
|
||||||
|
@ -150,12 +132,6 @@ my @test_cases = (
|
||||||
'mtime' => $ddclient::now,
|
'mtime' => $ddclient::now,
|
||||||
'status-ipv4' => 'good',
|
'status-ipv4' => 'good',
|
||||||
},
|
},
|
||||||
want_cfg_changes => {
|
|
||||||
'atime' => $ddclient::now,
|
|
||||||
'ipv4' => '192.0.2.1',
|
|
||||||
'mtime' => $ddclient::now,
|
|
||||||
'status-ipv4' => 'good',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
map({
|
map({
|
||||||
my %cfg = %{delete($_->{cfg})};
|
my %cfg = %{delete($_->{cfg})};
|
||||||
|
@ -211,9 +187,6 @@ my @test_cases = (
|
||||||
want_recap_changes => {
|
want_recap_changes => {
|
||||||
'warned-min-interval' => $ddclient::now,
|
'warned-min-interval' => $ddclient::now,
|
||||||
},
|
},
|
||||||
want_cfg_changes => {
|
|
||||||
'warned-min-interval' => $ddclient::now,
|
|
||||||
},
|
|
||||||
%$_,
|
%$_,
|
||||||
};
|
};
|
||||||
} {cfg => {use => 'web'}}, {cfg => {usev4 => 'webv4'}}),
|
} {cfg => {use => 'web'}}, {cfg => {usev4 => 'webv4'}}),
|
||||||
|
@ -238,11 +211,6 @@ my @test_cases = (
|
||||||
'ipv4' => '192.0.2.1',
|
'ipv4' => '192.0.2.1',
|
||||||
'mtime' => $ddclient::now,
|
'mtime' => $ddclient::now,
|
||||||
},
|
},
|
||||||
want_cfg_changes => {
|
|
||||||
'atime' => $ddclient::now,
|
|
||||||
'ipv4' => '192.0.2.1',
|
|
||||||
'mtime' => $ddclient::now,
|
|
||||||
},
|
|
||||||
%$_,
|
%$_,
|
||||||
};
|
};
|
||||||
} {cfg => {use => 'web'}}, {cfg => {usev4 => 'webv4'}}),
|
} {cfg => {use => 'web'}}, {cfg => {usev4 => 'webv4'}}),
|
||||||
|
@ -265,9 +233,6 @@ my @test_cases = (
|
||||||
want_recap_changes => {
|
want_recap_changes => {
|
||||||
'warned-min-error-interval' => $ddclient::now,
|
'warned-min-error-interval' => $ddclient::now,
|
||||||
},
|
},
|
||||||
want_cfg_changes => {
|
|
||||||
'warned-min-error-interval' => $ddclient::now,
|
|
||||||
},
|
|
||||||
%$_,
|
%$_,
|
||||||
};
|
};
|
||||||
} {cfg => {use => 'web'}}, {cfg => {usev4 => 'webv4'}}),
|
} {cfg => {use => 'web'}}, {cfg => {usev4 => 'webv4'}}),
|
||||||
|
@ -293,12 +258,6 @@ my @test_cases = (
|
||||||
'mtime' => $ddclient::now,
|
'mtime' => $ddclient::now,
|
||||||
'status-ipv4' => 'good',
|
'status-ipv4' => 'good',
|
||||||
},
|
},
|
||||||
want_cfg_changes => {
|
|
||||||
'atime' => $ddclient::now,
|
|
||||||
'ipv4' => '192.0.2.1',
|
|
||||||
'mtime' => $ddclient::now,
|
|
||||||
'status-ipv4' => 'good',
|
|
||||||
},
|
|
||||||
%$_,
|
%$_,
|
||||||
};
|
};
|
||||||
} {cfg => {use => 'web'}}, {cfg => {usev4 => 'webv4'}}),
|
} {cfg => {use => 'web'}}, {cfg => {usev4 => 'webv4'}}),
|
||||||
|
@ -317,7 +276,6 @@ for my $tc (@test_cases) {
|
||||||
# $cachef is an object that stringifies to a filename.
|
# $cachef is an object that stringifies to a filename.
|
||||||
local $ddclient::globals{cache} = "$cachef";
|
local $ddclient::globals{cache} = "$cachef";
|
||||||
my %cfg = (
|
my %cfg = (
|
||||||
%{$tc->{recap} // {}}, # Simulate a previous update.
|
|
||||||
web => 'v4',
|
web => 'v4',
|
||||||
webv4 => 'v4',
|
webv4 => 'v4',
|
||||||
webv6 => 'v6',
|
webv6 => 'v6',
|
||||||
|
|
Loading…
Reference in a new issue