diff --git a/manage-dns.pl b/manage-dns.pl index d947810..4ae2811 100755 --- a/manage-dns.pl +++ b/manage-dns.pl @@ -15,6 +15,10 @@ my $ua = LWP::UserAgent->new; my %seen; my $DRY_RUN = $ENV{DRY_RUN}; +my @to_create; +my @to_delete; +my @to_update; + sub _debug { print STDERR ("=== DEBUG ===\n", Dumper(@_), "=== END ===\n") if $ENV{DEBUG} or $in->[0]->{debug}; } @@ -204,41 +208,22 @@ sub check_and_update_record($$$$$) { if($record->{ttl} ne $in->[0]->{defaults}->{ttl}->{$zone}) { # Update the record $record->{ttl} = $in->[0]->{defaults}->{ttl}->{$zone}; - _debug("Update ", $url, $record, to_json($record)); - unless ($DRY_RUN) { - my $res = $ua->put( - $url, - "Content-Type" => "application/json", - "Content" => to_json({ records => [ $record ] }), - ); - warn "Failed to update $url: " . $res->status_line unless $res->is_success; - } + _debug("Will update ", $url, $record, to_json($record)); + push(@to_update, [$url,$record]); } } else { # Create new record my $new = format_record($zone, $type, $host, $value); - _notice("Created new record: %s %s %s", $host, $type, $value); - _debug($new); - unless ($DRY_RUN) { - my $res = $ua->post( - $url, - "Content-Type" => "application/json", - Content => to_json({ - records => [ $new ] - }) - ); - warn "Failed to create $url: " . $res->status_line . "\n" . $res->content unless $res->is_success; - } + _notice("Will create new record: %s %s %s", $host, $type, $value); + push(@to_create, [$url,$new]); } } sub delete_record($$) { my ($zone, $record) = @_; - return if $DRY_RUN; - my $url = $in->[0]->{defaults}->{api} . "/$zone/records/$record->{host}/$record->{type}?host=$record->{host}&data=$record->{data}"; - my $res = $ua->delete($url); - warn "Failed to delete $url: " . $res->status_line . "\n" . $res->content unless $res->is_success; + _notice("Will delete: %s %s %s", $record->{host}, $record->{type}, $record->{data}); + push(@to_delete, $url); } foreach my $z (keys %{$in->[0]->{zones}}) { @@ -292,10 +277,46 @@ foreach my $z (keys %{$in->[0]->{zones}}) { } } unless ($skip) { - _notice("Delete %s %s %s", $record->{host}, $record->{type}, $record->{data}); + # _notice("Will delete %s %s %s", $record->{host}, $record->{type}, $record->{data}); delete_record($z, $record); } } } - _info("Finished processing %s", $z); + _info("Finished pre-processing %s", $z); +} + +unless($DRY_RUN) { + _info("Applying changes (%d creates, %d updates, %d deletes)", scalar @to_create, scalar @to_update, scalar @to_delete); + + # Delete + foreach my $url (@to_delete) { + my $res = $ua->delete($url); + warn "Failed to delete $url: " . $res->status_line . "\n" . $res->content unless $res->is_success; + } + + # Create + foreach my $record (@to_create) { + my $res = $ua->post( + $record->[0], + "Content-Type" => "application/json", + Content => to_json({ + records => [ $record->[1] ] + }) + ); + warn "Failed to create $record->[0]: " . $res->status_line . "\n" . $res->content unless $res->is_success; + } + + # Update + foreach my $record (@to_update) { + my $res = $ua->put( + $record->[0], + "Content-Type" => "application/json", + "Content" => to_json({ records => [ $record->[1] ] }), + ); + warn "Failed to update $record->[0]: " . $res->status_line unless $res->is_success; + } + + _info("Finished applying changes") +} else { + _info("DRY RUN: Skipped applying changes (%d creates, %d updates, %d deletes)", scalar @to_create, scalar @to_update, scalar @to_delete); }