#!/usr/bin/perl
#
# Parsen van nagios config uit Genesis
# by maarten@wirelessleiden.nl
#
# v0.7 - Notes directive points to the remote log
# v0.6 - Traffic interface check. checking via SNMP
# v0.5 - added args support for location output and genesis and added count to parser
# v0.4 - handeling proxies
# v0.3 - added hostgroups on postcode
# v0.2 - append host ext info and xy for statusmap
# v0.1 - loops trough all nodes and interfaces
#
# Inspired by:
# - configcleaner.pl by Rick van der Zwet (rick@wirelessleiden.nl)
# - conf2inc.pl

#maak een mooi systeem met hash aanroepen om snel gegevens te verwerken
sub parse_config {
  foreach my $id (sort keys %config) {
    my $rawData = $config{$id};
    $rawData =~ s/#.*\n/\n/g;                  #wegslopen comments
    $rawData =~ s/\s*[\r,\n]+\s*/:::/g;        #spaties+enter+spaties vervangen door :::
    $rawData =~ s/^::://;                      #::: aan het begin weghalen
    $rawData =~ s/:::$//;                      #::: aan het eind weghalen
    my @configArray = split( /:::/, $rawData); #array er van maken
    foreach $line (@configArray) {
      (my $name, my $value) = split( /\=/, $line);
      $$name{$id} = $value;
    }
  }
}

sub generateConfig {
  my $configfile = $_[0];
  open( CONF, "> $configfile");

### Pre render variables
  # make genesis configname needed for naming convention proxy
  my $configname = $nodetype.$nodename;
  if ($nodetype eq Proxy) { $configname = lc($nodename)};
  # get current date
  $DATE = localtime(time());

  # get all WL IP's for host alive check and exclude aliases
  my $IPS = $master_ip;
  foreach my $key (sort keys %config) {
      if (($key !~ m/(:\d)$/) && ($IP{$key} =~/^172\../)) {
        $IPS = join(' ',$IPS, substr($IP{$key}, 0, -3));
      }
  }

  # sanitize edugis coords for statusmap
   # X=0 uiterst links zwaluwak edugis x,y 90739,463249 
   # Y=0 uiterst boven LMkempers1 edugis x,y 107030,471206
   # X=800 uiterst rechts LMkempers1 edugis x,y 107030,471206
   # Y=600 uiterst onder PPFortis edugis x,y 104920,458730
  $X = int(($X-90739)/((107030-90739)/800));
  $Y = int((471206-$Y)/((471206-458730)/600));

  # Create hostgroups on location postcode
  my @Alphen = (2445, 2400..2409, 2470, 2471, 2770, 2771, 2420, 2421, 2440, 2441, 2430..2432, 2460, 2461, 1428, 3651..3653, 2435);
  my @Rijnwoude = (2730, 2731, 2390, 2391, 2394, 2396);
  my @Oegstgeest = (2223,2340..2343);
  my @Voorschoten = (2250..2254);
  my @Jacobswoude = (2452, 2355, 2450, 2451, 2465, 2480, 2481, 1430..1432);
  my @Leiden = (2159, 2376, 2374, 2377, 2375, 2370, 2371, 2300..2334, 2350..2353, 2200..2204, 2190, 2191, 2210, 2211, 2240..2245, 2735, 2380..2382);
  $group = "Rest";
  if ($location =~ m/(\d\d\d\d)/) {
    for (@Alphen) {if ($_ eq $1) {$group = "Alphen"}}
    for (@Rijnwoude) {if ($_ eq $1) {$group = "Rijnwoude"}}
    for (@Oegstgeest) {if ($_ eq $1) {$group = "Oegstgeest"}}
    for (@Voorschoten) {if ($_ eq $1) {$group = "Voorschoten"}}
    for (@Jacobswoude) {if ($_ eq $1) {$group = "Jacobswoude"}}
    for (@Leiden) {if ($_ eq $1) {$group = "Leiden"}}
    if ($group eq "Rest") {$group = "Onbekend"}
  }

  # Create hostgroup for proxies
  if ($nodetype eq "Proxy") { $group = "Proxy"}

### begin config file

  print CONF <<EOP;
# Config for $nodetype $nodename
# Generated $DATE from Genesis (by gen2nag.pl)
#
# host definitions can be done in hosts.cfg
# service definitions can be done in services.cfg

define host {
	host_name	$nodename
	alias		$nodetype$nodename.wleiden.net
	use		nodes
	address		$master_ip
	check_command	check_alive!$IPS
	hostgroups	$group
}

# Host extra info
define hostextinfo{
	host_name	$nodename
	notes 		This node is generated $DATE from genesis
	notes_url	http://watch.wirelessleiden.nl/logs/$configname
	icon_image	$nodetype.png
	icon_image_alt	$nodetype $nodename
	statusmap_image	$nodetype.gd2
	2d_coords	$X,$Y
}

#Service definitions for interfaces
EOP
 # loop trough all interfaces for service checks 
    foreach my $key (sort keys %config) {

	  ### Prerender 
	  #Strip subnet
	  $IP{$key} = substr($IP{$key}, 0, -3);

	  # Service checks for all WL interfaces and exclude aliases
	  if (($key !~ m/(:\d)$/) && ($IP{$key} =~/^172\../)) {
	    print CONF <<EOP;
define service {
	host_name		$nodename
	use			check-if
	service_description	Ping $key
	check_command		check_if_ip!$IP{$key}
}

define service {
	host_name		$nodename
	use			check-if
	service_description	Traffic $key
	check_command		check_if_snmp!$key
}

EOP
	    # Service definition for wireless interfaces only 
	    if ( lc($TYPE{$key}) eq "wireless" && 1==0 ) {  # disabled with && 1==0 , not used yet
      		    print CONF <<EOP;
# Service definition for wireless interface $key
EOP
	    }
	  }
    }
  # close the config file
  close ( CONF );
}

# check if any args
if ($#ARGV < 0 ) {
  print "Usage: gen2nag.pl outputdir/nagios/config [genesis/localtion(default=.)]\n";
  exit;
}

# Set the output dir
my $OUTPUTDIR=$ARGV[0]; # location for nagios object files

# Set the config dir / The location of genesis
my $CONFDIR='.';
if ($#ARGV == 1) {
  $CONFDIR=$ARGV[1];
}

opendir(DIR,$CONFDIR) or die $!;

my $count=0;
foreach(readdir(DIR)) {
  next unless m/([CH]Node[\w+i]|proxy\d+)/;
  my $n = $_;
  foreach ($n){
    my $file = $CONFDIR.'/'.$n.'/wleiden.conf';
    next unless -r $file;
    my $file_output = $OUTPUTDIR.'/'.$n.'.cfg';
    print "Working on $n...\n";
    $$_ = "" foreach qw(location master_ip gw_open nodetype nodename
                        OS status X Y N E OS DISK AGGREGATE);
    %$_ = () foreach qw(config TYPE IP DESC SDESC SPEED DHCP DHCP_STATIC
                              OSPF_BROADCAST OSPF_NEIGHBORS MODE ESSID CHANNEL
                              POLAR ANTENNA GAIN DIRECTION BEAMWIDTH CABLE
                              HEIGHT ROUTE);
    do($file) || die $!;#("Can't open file $file");
    print "\t Parsing config...";
    parse_config;
    print "DONE\n";
    print "\t Generating nagios objectfile...";
    generateConfig($file_output);
    print "DONE\n";
    $count+=1;
  }
}
print "Created nagios configs for $count nodes in directory $OUTPUTDIR\n";
