App-Spanel-BuildBindZones
view release on metacpan or search on metacpan
lib/App/Spanel/BuildBindZones.pm view on Meta::CPAN
$SPEC{build_bind_zones} = {
v => 1.1,
summary => 'Build BIND zones from YAML zones',
description => <<'_',
This script will collect all YAML zones from user accounts (/u/*/sysetc/zone=*)
and build BIND zones then write them to the current directory with names db.*
(so /u/foo/sysetc/zone=example.com will become ./db.example.com).
Will not override existing files unless `--overwrite` (`-O`) is specified.
Will skip YAML zones that contain invalid data, e.g. name in record that
contains underscore (`_`), unknown record type, etc.
_
args => {
overwrite => {
summary => 'Whether to overwrite existing output files',
schema => 'bool*',
cmdline_aliases => {O=>{}},
},
},
};
sub build_bind_zones {
#require Data::Sah;
require Data::Transmute;
require DNS::Zone::Struct::To::BIND;
require YAML::XS;
my %args = @_;
#my $code_validate_domain = Data::Sah::gen_validator(
# "net::hostname*",
# {return_type=>"str"},
#);
eval {
local @INC = @INC;
push @INC, "/c/lib/perl";
push @INC, "/c/lib/perl/cpan";
require Spanel::Utils;
Spanel::Utils::load_config();
Spanel::Utils::load_servers_config();
};
if ($@) {
log_info "Cannot load servers config: $@";
}
my $orig_cwd = $CWD;
local $CWD = "/u";
for my $user (glob "*") {
next unless -d $user;
log_info "Processing user $user ...";
if (-f "$user/sysetc/migrated") {
log_info "User $user is migrated, skipping";
next;
}
local $CWD = "$user/sysetc";
for my $yaml_file (glob "zone=*") {
# skip backup files
next if $yaml_file =~ /~$/;
log_info "Processing file $yaml_file ...";
my ($domain) = $yaml_file =~ /^zone=(.+)/;
#if (my $err = $code_validate_domain->($domain)) {
# log_warn "$domain is not a valid hostname, skipping file $yaml_file";
# next;
#}
my $output_file = "$orig_cwd/db.$domain";
if (-f $output_file) {
unless ($args{overwrite}) {
log_info "$yaml_file: Output file $output_file already exists (and we're not overwriting), skipped";
next;
}
}
my $spanel_struct_zone;
eval { $spanel_struct_zone = YAML::XS::LoadFile($yaml_file) };
if ($@) {
log_warn "$yaml_file cannot be loaded: $@, skipped";
next;
}
# replace ^serverXXX in 'address' fields with the server's actual IP addresses
for my $rec (@{ $spanel_struct_zone->{records} }) {
next unless $rec->{address} && $rec->{address} =~ /^\^(.+)/;
my $servername = $1;
if ($main::SPANEL_SERVERS->{$servername}) { $rec->{address} = $main::SPANEL_SERVERS->{$servername}{config}{local}{ip}[0] }
elsif ($main::CPANEL_SERVERS->{$servername}) { $rec->{address} = $main::CPANEL_SERVERS->{$servername}{config}{local}{ip}[0] }
elsif ($main::PLESK_SERVERS ->{$servername}) { $rec->{address} = $main::PLESK_SERVERS ->{$servername}{config}{local}{ip}[0] }
else { log_warn "$yaml_file: Unknown server '$servername' mentioned in DNS records, using 0.0.0.0"; $rec->{address} = "0.0.0.0" }
}
my $struct_zone;
eval {
$struct_zone = Data::Transmute::transmute_data(
data => $spanel_struct_zone,
rules_module => "DNS::Zone::Struct::FromSpanel",
);
};
if ($@) {
log_warn "$yaml_file: cannot transmute data: $@, skipped";
next;
}
my $bind_zone;
eval {
$bind_zone = DNS::Zone::Struct::To::BIND::gen_bind_zone_from_struct(
zone => $struct_zone,
master_host => $domain,
);
};
if ($@) {
log_warn "$yaml_file: cannot generate BIND zone: $@, skipped";
next;
}
# insert header
$bind_zone = join(
( run in 1.044 second using v1.01-cache-2.11-cpan-13bb782fe5a )