#!/usr/bin/perl use strict; use warnings; use Martnet::DDNS; use Regexp::Common qw/net/; use Getopt::Long qw/GetOptions/; use JSON::PP qw/encode_json true false/; sub usage { die "Usage: add-vhost [--edit] [--enable-dnssec|--disable-dnssec] --master " + ("[--webserver-ip ] ") + "[--ddns-keyname ...] \n"; } my $master; my $edit = 0; my $enable_dnssec = 0; my $disable_dnssec = 0; my @ddns_keynames; my $webserver_ip; GetOptions( 'master|m=s' => \$master, 'edit' => \$edit, 'enable-dnssec' => \$enable_dnssec, 'disable-dnssec' => \$disable_dnssec, 'ddns-keyname=s@' => \@ddns_keynames, 'webserver-ip=s' => \$webserver_ip, ) or usage(); usage() unless defined $master; die "Cannot specify both --enable-dnssec and --disable-dnssec\n" if ($enable_dnssec && $disable_dnssec); my $host = shift || die "No zonename provided\n"; my $ddns = Martnet::DDNS->new(); die "Zonename must end in a dot\n" unless ($host =~ /^[a-zA-Z0-9\.\-\_]+\.$/); my $regex = $RE{net}{IPv4} . '|' . $RE{net}{IPv6}; die "Master must be an IPv4 or IPv6 address\n" unless ($master =~ /^$regex$/); if (defined $webserver_ip) { die "Webserver IP must be an IPv4 or IPv6 address\n" unless ($webserver_ip =~ /^$regex$/); } my $payload = { master => $master }; if ($enable_dnssec) { $payload->{dnssec} = true; } elsif ($disable_dnssec) { $payload->{dnssec} = false; } if (@ddns_keynames) { # Preserve order but de-dupe my %seen; my @uniq = grep { !$seen{$_}++ } @ddns_keynames; $payload->{ddns_keys} = \@uniq; } if (defined $webserver_ip) { $payload->{webserver_ip} = $webserver_ip; } my $txt = encode_json($payload); if ($edit) { $ddns->set($host, $txt, '_vhosts'); } else { $ddns->add($host, $txt, '_vhosts'); } exit 0;