#!/usr/bin/perl use strict; use warnings; use Martnet::DDNS; use Getopt::Long qw/GetOptions/; use JSON::PP qw//; sub usage { die "Usage: update-config [--default-master IP] [--vhost-default-web-ip IP] [--soa-mname FQDN] [--soa-rname FQDN]\n" . " [--ns FQDN --ns FQDN ...] [--mx PRIORITY:FQDN --mx PRIORITY:FQDN ...]\n" . " [--master-ddns-keyname NAME] [--master-ddns-keyfile PATH]\n"; } my $default_master; my $vhost_default_web_ip; my $soa_mname; my $soa_rname; my @ns; my @mx; my $master_ddns_keyname; my $master_ddns_keyfile; GetOptions( 'default-master=s' => \$default_master, 'vhost-default-web-ip=s' => \$vhost_default_web_ip, 'soa-mname=s' => \$soa_mname, 'soa-rname=s' => \$soa_rname, 'ns=s@' => \@ns, 'mx=s@' => \@mx, 'master-ddns-keyname=s' => \$master_ddns_keyname, 'master-ddns-keyfile=s' => \$master_ddns_keyfile, ) or usage(); my $ddns = Martnet::DDNS->new(); my $old = $ddns->get_config(); my $json = JSON::PP->new->canonical(1)->pretty(1); print "Current _config:\n"; print $json->encode($old); # Build new config (copy then modify) my %new = %$old; $new{default_master} = $default_master if defined $default_master; $new{vhost_default_web_ip} = $vhost_default_web_ip if defined $vhost_default_web_ip; $new{soa_mname} = $soa_mname if defined $soa_mname; $new{soa_rname} = $soa_rname if defined $soa_rname; $new{master_ddns_keyname} = $master_ddns_keyname if defined $master_ddns_keyname; $new{master_ddns_keyfile} = $master_ddns_keyfile if defined $master_ddns_keyfile; if (@ns) { $new{ns} = \@ns; } if (@mx) { my @mx_arr; foreach my $m (@mx) { die "Invalid --mx format (expected PRIORITY:FQDN): $m\n" unless ($m =~ /^(\d+):(\S+)$/); push @mx_arr, { priority => int($1), host => $2 }; } $new{vhost_mx} = \@mx_arr; } print "\nNew _config to apply:\n"; print $json->encode(\%new); print "\nApplying...\n"; $ddns->set_config(\%new); my $after = $ddns->get_config(); print "Applied. Current _config after update:\n"; print $json->encode($after); # Basic success check foreach my $k (keys %new) { next unless exists $after->{$k}; if (JSON::PP->new->canonical(1)->encode($after->{$k}) ne JSON::PP->new->canonical(1)->encode($new{$k})) { die "Update failed for key '$k'\n"; } } print "Update succeeded.\n"; exit 0;