Merge pull request #558 from TinfoilSubmarine/fix/gandi

This commit is contained in:
Lenard Hess 2023-11-25 13:55:09 +01:00
commit e0611ab192
2 changed files with 87 additions and 64 deletions

View file

@ -197,10 +197,10 @@ ssl=yes # use ssl-support. Works with
## Gandi (gandi.net) ## Gandi (gandi.net)
## ##
## Single host update ## Single host update
# protocol=gandi, \ # protocol=gandi
# zone=example.com, \ # zone=example.com
# password=my-gandi-api-key, \ # password=my-gandi-api-key
# ttl=3h \ # ttl=10800 # optional
# myhost.example.com # myhost.example.com
## ##

View file

@ -7346,20 +7346,20 @@ Available configuration variables:
Required. Required.
* zone: The DNS zone to be updated. Required. * zone: The DNS zone to be updated. Required.
* ttl: The time-to-live value associated with the updated DNS record. * ttl: The time-to-live value associated with the updated DNS record.
Optional; uses Gandi's default (3h) if unset. Optional; uses Gandi's default (10800) if unset.
Example ${program}.conf file entries: Example ${program}.conf file entries:
## Single host update. ## Single host update.
protocol=gandi, \\ protocol=gandi
zone=example.com, \\ zone=example.com
password=my-gandi-api-key, \\ password=my-gandi-api-key
host.example.com host.example.com
## Multiple host update. ## Multiple host update.
protocol=gandi, \\ protocol=gandi
zone=example.com, \\ zone=example.com
password=my-gandi-api-key, \\ password=my-gandi-api-key
ttl=1h \\ ttl=3600 # optional
hosta.example.com,hostb.sub.example.com hosta.example.com,hostb.sub.example.com
EoEXAMPLE EoEXAMPLE
} }
@ -7369,68 +7369,91 @@ EoEXAMPLE
###################################################################### ######################################################################
sub nic_gandi_update { sub nic_gandi_update {
debug("\nnic_gandi_update -------------------"); debug("\nnic_gandi_update -------------------");
# Update each set configured host. # Update each set configured host.
foreach my $h (@_) { foreach my $h (@_) {
my $ip = delete $config{$h}{'wantip'}; foreach my $ipv ('ipv4', 'ipv6') {
(my $hostname = $h) =~ s/\.\Q$config{$h}{zone}\E$//; my $ip = delete $config{$h}{"want$ipv"};
if(!$ip) {
next;
}
(my $hostname = $h) =~ s/\.\Q$config{$h}{zone}\E$//;
info("%s -- Setting IP address to %s.", $h, $ip);
verbose("UPDATE:", "updating %s", $h);
info("%s -- Setting IP address to %s.", $h, $ip); my $headers;
verbose("UPDATE:", "updating %s", $h); $headers = "Content-Type: application/json\n";
$headers .= "Authorization: Apikey $config{$h}{'password'}\n";
my $headers;
$headers = "Content-Type: application/json\n";
$headers .= "Authorization: Apikey $config{$h}{'password'}\n";
my $data = encode_json({
defined($config{$h}{'ttl'}) ? (rrset_ttl => $config{$h}{'ttl'}) : (),
rrset_values => [$ip],
});
my $rrset_type = is_ipv6($ip) ? "AAAA" : "A"; my $rrset_type = $ipv eq 'ipv6' ? 'AAAA' : 'A';
my $url; my $url;
$url = "https://$config{$h}{'server'}$config{$h}{'script'}"; $url = "https://$config{$h}{'server'}$config{$h}{'script'}";
$url .= "/livedns/domains/$config{$h}{'zone'}/records/$hostname/$rrset_type"; $url .= "/livedns/domains/$config{$h}{'zone'}/records/$hostname/$rrset_type";
my $reply = geturl( my $reply = geturl(
proxy => opt('proxy'), proxy => opt('proxy'),
url => $url, url => $url,
headers => $headers, headers => $headers,
method => 'PUT', method => 'GET'
data => $data, );
); unless ($reply) {
unless ($reply) { failed("%s -- Could not connect to %s.", $h, $config{$h}{'server'});
failed("%s -- Could not connect to %s.", $h, $config{$h}{'server'}); next;
next; }
} my $ok = header_ok($h, $reply);
my $ok = header_ok($h, $reply);
$reply =~ s/^.*?\n\n//s; $reply =~ s/^.*?\n\n//s;
my $response = eval { decode_json($reply) }; my $response = eval { decode_json($reply) };
if (!defined($response)) { if (!defined($response)) {
$config{$h}{'status'} = "bad"; $config{$h}{"status-$ipv"} = "bad";
failed("%s -- Unexpected service response.", $h);
next;
}
if ($ok) {
$config{$h}{'ip'} = $ip;
$config{$h}{'mtime'} = $now;
$config{$h}{'status'} = "good";
success("%s -- Updated successfully to %s.", $h, $ip);
} else {
$config{$h}{'status'} = "bad";
if (defined($response->{status}) && $response->{status} eq "error") {
my @errors;
for my $err (@{$response->{errors}}) {
push(@errors, $err->{description});
}
failed("%s -- %s.", $h, join(", ", @errors));
} else {
failed("%s -- Unexpected service response.", $h); failed("%s -- Unexpected service response.", $h);
next;
}
if($response->{'rrset_values'}->[0] eq $ip && (!defined($config{$h}{'ttl'}) ||
$response->{'rrset_ttl'} eq $config{$h}{'ttl'})) {
$config{$h}{'ip'} = $ip;
$config{$h}{'mtime'} = $now;
$config{$h}{"status-$ipv"} = "good";
success("updating %s: skipped: address was already set to %s.", $h, $ip);
next;
}
my $data = encode_json({
defined($config{$h}{'ttl'}) ? (rrset_ttl => $config{$h}{'ttl'}) : (),
rrset_values => [$ip],
});
$reply = geturl(
proxy => opt('proxy'),
url => $url,
headers => $headers,
method => 'PUT',
data => $data,
);
unless ($reply) {
failed("%s -- Could not connect to %s.", $h, $config{$h}{'server'});
next;
}
$ok = header_ok($h, $reply);
if ($ok) {
$config{$h}{'ip'} = $ip;
$config{$h}{'mtime'} = $now;
$config{$h}{"status-$ipv"} = "good";
success("%s -- Updated successfully to %s.", $h, $ip);
} else {
$config{$h}{"status-$ipv"} = "bad";
if (defined($response->{status}) && $response->{status} eq "error") {
my @errors;
for my $err (@{$response->{errors}}) {
push(@errors, $err->{description});
}
failed("%s -- %s.", $h, join(", ", @errors));
} else {
failed("%s -- Unexpected service response.", $h);
}
} }
} }
} }