#!/usr/bin/perl -I /root/tgmanage use strict; use Net::IP; use NetAddr::IP; use POSIX qw(strftime); BEGIN { require "include/config.pm"; eval { require "include/config.local.pm"; }; } my $serial = strftime("%Y%m%d", localtime(time())) . "01"; unless ( (($#ARGV == 0 ) || ( $#ARGV == 1)) && (( $ARGV[0] eq "master" ) || ( $ARGV[0] eq "slave" )) ) { print STDERR "Invalid usage!\ncat netnames.txt | $0 [basedir]\n"; exit 1; } my $role = $ARGV[0]; my $base = "/etc"; $base = $ARGV[1] if $#ARGV == 1; $base .= "/" if not $base =~ m/\/$/ and not $base eq ""; print STDERR "Role is " . $role . "\n"; print STDERR "Base dir is " . $base . "\n"; my $bind_base = $base . "bind/"; my $dhcpd_base = $base . "dhcp/"; my $bind_conf_master = $bind_base . "conf-master/"; my $bind_conf_slave = $bind_base . "conf-slave/"; my $base_ipv4 = Net::IP->new( $nms::config::base_ipv4net ); my ($cp_oct, $cs_oct, $ct_oct) = ($nms::config::base_ipv4net =~ m/^(\d+)\.(\d+)\.(\d+)\..*/); while ( ){ next if ( $_ =~ m/^(#|$)/); # comment or blank line my $line = $_; chomp $line; # # 151.216.129.0/26 2a02:ed02:129a::/64 noc # we assume not smaller than /64 on v6 die ("Invalid format on input.\n") if not $line =~ m/^((\d+\.){3}\d+\/\d+)\s+(([a-fA-F0-9]+\:){1,4}\:\/\d+)\s+([\w|-]+).*/; my ( $v4_net, $v6_net, $name ) = ( $1, $3, $5 ); my $master_config = $bind_conf_master . $name . ".conf"; my $slave_config = $bind_conf_slave . $name . ".conf"; my $zone_file = $bind_base . "dynamic/$name.$nms::config::tgname.gathering.org.zone"; # DHCP4 my $dhcp_dynconf_dir = $dhcpd_base . "conf-v4/"; my $dhconfig = $dhcp_dynconf_dir . $name . ".conf"; if ( not -f $dhconfig ){ print STDERR "Creating file " . $dhconfig . "\n"; my $network = Net::IP->new($v4_net)->ip(); my $netmask = Net::IP->new($v4_net)->mask(); (my $first = NetAddr::IP->new($v4_net)->nth(3)) =~ s/\/[0-9]{1,2}//; # we reserve the three first addresses (my $last = NetAddr::IP->new($v4_net)->last()) =~ s/\/[0-9]{1,2}//; (my $gw = NetAddr::IP->new($v4_net)->first()) =~ s/\/[0-9]{1,2}//; open DFILE, ">" . $dhconfig or die ( $! . " " . $dhconfig); print DFILE <<"EOF"; zone $name.$nms::config::tgname.gathering.org { primary $nms::config::ddns_to; key DHCP_UPDATER; } subnet $network netmask $netmask { option subnet-mask $netmask; option routers $gw; option domain-name "$name.$nms::config::tgname.gathering.org"; ddns-domainname "$name.$nms::config::tgname.gathering.org"; range $first $last; } EOF close DFILE; } # DHCP6 $dhcp_dynconf_dir = $dhcpd_base . "conf-v6/"; $dhconfig = $dhcp_dynconf_dir . $name . ".conf"; if ( not -f $dhconfig ){ print STDERR "Creating file " . $dhconfig . "\n"; my $network = Net::IP->new($v6_net)->short(); my ($first, $last) = ("1000", "9999"); open DFILE, ">" . $dhconfig or die ( $! . " " . $dhconfig); print DFILE <<"EOF"; zone $name.$nms::config::tgname.gathering.org { primary $nms::config::ddns_to; key DHCP_UPDATER; } subnet6 $v6_net { option domain-name "$name.$nms::config::tgname.gathering.org"; range6 ${network}${first} ${network}${last}; } EOF close DFILE; } # Create zone files for bind9 on master/primary if ( ( not -f $zone_file ) && ( $role eq "master" ) ) { print STDERR "Creating file " . $zone_file . "\n"; open ZFILE, ">" . $zone_file or die ( $! . " " . $zone_file); print ZFILE << "EOF"; ; Base reverse zones are updated from dhcpd -- DO NOT TOUCH! \$TTL 3600 @ IN SOA $nms::config::pri_hostname.$nms::config::tgname.gathering.org. abuse.gathering.org. ( $serial ; serial 3600 ; refresh 1800 ; retry 608400 ; expire 3600 ) ; minimum and default TTL IN NS $nms::config::pri_hostname.$nms::config::tgname.gathering.org. IN NS $nms::config::sec_hostname.$nms::config::tgname.gathering.org. \$ORIGIN $name.$nms::config::tgname.gathering.org. EOF close ZFILE; } # Create bind9 configuration files for zones. my $bind_file = ""; $bind_file = $master_config if ( $role eq "master"); $bind_file = $slave_config if ( $role eq "slave"); die ("WTF, role does not match 'master' or 'slave'" ) if ( $bind_file eq ""); if ( not -f $bind_file ){ print STDERR "Creating file " . $bind_file . "\n"; open NFILE, ">" . $bind_file or die ( $! . " " . $bind_file); print NFILE <<"EOF"; zone "$name.$nms::config::tgname.gathering.org" { allow-transfer { ns-xfr; }; EOF if ( $role eq "master" ) { print NFILE <<"EOF"; type master; notify yes; allow-update { key DHCP_UPDATER; }; file "dynamic/$name.$nms::config::tgname.gathering.org.zone"; }; EOF } else { print NFILE <<"EOF"; type slave; notify no; masters { master_ns; }; file "slave/$name.$nms::config::tgname.gathering.org.zone"; }; EOF } close NFILE; } }