# Common nagios variables.
#
class nagios::common {

    case $::operatingsystem {
        "centos","redhat","fedora": {
            $etcdir = "/etc/nagios"
            $confdir = "${etcdir}/conf.d"
            $private = "${etcdir}/private.d"
            $htpasswd = "${etcdir}/passwd"
            $package = "nagios"
            $service = "nagios"
            $scriptalias = "/nagios/cgi-bin/"
            $libdir = $::architecture ? {
                "x86_64" => "/usr/lib64/nagios/plugins",
                default  => "/usr/lib/nagios/plugins",
            }
            $cgibin = $::architecture ? {
                "x86_64" => "/usr/lib64/nagios/cgi-bin",
                default  => "/usr/lib/nagios/cgi-bin",
            }
            $htdocs = "/usr/share/nagios/html"
        }
        "ubuntu","debian": {
            $etcdir = "/etc/nagios3"
            $confdir = "${etcdir}/conf.d"
            $private = "${etcdir}/private.d"
            $htpasswd = "${etcdir}/htpasswd.users"
            $package = "nagios3"
            $service = "nagios3"
            $scriptalias = "/cgi-bin/nagios3/"
            $libdir = "/usr/lib/nagios/plugins"
            $cgibin = "/usr/lib/cgi-bin/nagios3"
            $htdocs = "/usr/share/nagios3/htdocs"
        }
        default: {
            fail("Nagios not supported on ${::operatingsystem}")
        }
    }

}


# Install Nagios server.
#
class nagios::server::manual inherits nagios::common {

    package { "nagios":
        name   => $package,
        ensure => installed,
    }

    case $::operatingsystem {
        "centos","redhat","fedora": {
            package { [ "nagios-plugins-all",
                        "nagios-plugins-nrpe", ]:
                ensure => installed,
            }
        }
        "ubuntu","debian": {
            package { [ "nagios-plugins",
                        "nagios-nrpe-plugin", ]:
                ensure => installed,
            }
            file { "/usr/share/nagios3/htdocs/stylesheets":
                ensure => link,
                target => "/etc/nagios3/stylesheets",
            }
        }
    }

    exec { "usermod-nagios-httpsd":
        path    => "/bin:/usr/bin:/sbin:/usr/sbin",
        command => "usermod -a -G nagios ${apache::sslserver::user}",
        unless  => "id -n -G ${apache::sslserver::user} | grep '\\bnagios\\b'",
        require => Package["nagios"],
    }

    service { "nagios":
        name   => $service,
        ensure => running,
        enable => true,
    }

    apache::configfile { "nagios.conf":
        content => template("nagios/nagios-httpd.conf.erb"),
    }

    file { [ "${htdocs}/.htaccess", "${cgibin}/.htaccess" ]:
        ensure  => present,
        mode    => "0644",
        owner   => "root",
        group   => "root",
        source  => [ "puppet:///files/nagios/htaccess",
                     "puppet:///modules/nagios/htaccess.${::osfamily}", ],
        require => Package["nagios"],
    }

    file { "${htdocs}/config.inc.php":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => $apache::sslserver::group,
        require => Package["nagios"],
    }

    file { "/etc/nagios/nagios.cfg":
        name    => "${etcdir}/nagios.cfg",
        ensure  => present,
        mode    => "0644",
        owner   => "root",
        group   => "root",
        source  => "puppet:///modules/nagios/nagios.cfg.${::osfamily}",
        require => Package["nagios"],
        notify  => Service["nagios"],
    }

    file { "/etc/nagios/cgi.cfg":
        name    => "${etcdir}/cgi.cfg",
        ensure  => present,
        mode    => "0644",
        owner   => "root",
        group   => "root",
        content => template("nagios/cgi.cfg.erb"),
        require => Package["nagios"],
        notify  => Service["nagios"],
    }

    file { "/etc/nagios/commands.cfg":
        name    => "${etcdir}/commands.cfg",
        ensure  => present,
        mode    => "0644",
        owner   => "root",
        group   => "root",
        source  => "puppet:///modules/nagios/commands.cfg",
        require => Package["nagios"],
        notify  => Service["nagios"],
    }

    file { "/etc/nagios/passwd":
        name    => $htpasswd,
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => $apache::sslserver::group,
        require => Package["nagios"],
    }

    file { "/etc/nagios/conf.d":
        name    => $confdir,
        ensure  => directory,
        mode    => "0640",
        owner   => "root",
        group   => "nagios",
        purge   => true,
        force   => true,
        recurse => true,
        source  => "puppet:///modules/custom/empty",
        require => Package["nagios"],
        notify  => Service["nagios"],
    }

    file { "/etc/nagios/private.d":
        name    => $private,
        ensure  => directory,
        mode    => "0640",
        owner   => "root",
        group   => "nagios",
        purge   => true,
        force   => true,
        recurse => true,
        source  => "puppet:///modules/custom/empty",
        require => Package["nagios"],
        notify  => Service["nagios"],
    }

    file { "${confdir}/contactgroup_all.cfg":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => "nagios",
        before  => Nagios_Contactgroup["all"],
        require => File["/etc/nagios/conf.d"],
    }
    nagios_contactgroup { "all":
        target  => "${confdir}/contactgroup_all.cfg",
        notify  => Service["nagios"],
    }

    file { "${confdir}/host_default.cfg":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => "nagios",
        before  => Nagios_Host["default"],
        require => File["/etc/nagios/conf.d"],
    }
    nagios_host { "default":
        target                       => "${confdir}/host_default.cfg",
        register                     => "0",
        notifications_enabled        => "1",
        event_handler_enabled        => "1",
        flap_detection_enabled       => "1",
        failure_prediction_enabled   => "1",
        process_perf_data            => "1",
        retain_status_information    => "1",
        retain_nonstatus_information => "1",
        check_command                => "check-host-alive",
        max_check_attempts           => "5",
        notification_interval        => "0",
        notification_period          => "24x7",
        notification_options         => "d,u,r",
        contact_groups               => "all",
        notify                       => Service["nagios"],
    }

    file { "${confdir}/service_default.cfg":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => "nagios",
        before  => Nagios_Service["default"],
        require => File["/etc/nagios/conf.d"],
    }
    nagios_service { "default":
        target                       => "${confdir}/service_default.cfg",
        register                     => "0",
        active_checks_enabled        => "1",
        passive_checks_enabled       => "1",
        parallelize_check            => "1",
        obsess_over_service          => "1",
        check_freshness              => "0",
        notifications_enabled        => "1",
        event_handler_enabled        => "1",
        flap_detection_enabled       => "1",
        failure_prediction_enabled   => "1",
        process_perf_data            => "1",
        retain_status_information    => "1",
        retain_nonstatus_information => "1",
        notification_interval        => "0",
        is_volatile                  => "0",
        check_period                 => "24x7",
        normal_check_interval        => "5",
        retry_check_interval         => "1",
        max_check_attempts           => "2",
        notification_period          => "24x7",
        notification_options         => "w,u,c,r",
        contact_groups               => "all",
        notify                       => Service["nagios"],
    }

    file { "${confdir}/timeperiod_24x7.cfg":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => "nagios",
        before  => Nagios_Timeperiod["24x7"],
        require => File["/etc/nagios/conf.d"],
    }
    nagios_timeperiod { "24x7":
        target    => "${confdir}/timeperiod_24x7.cfg",
        alias     => "24x7",
        monday    => "00:00-24:00",
        tuesday   => "00:00-24:00",
        wednesday => "00:00-24:00",
        thursday  => "00:00-24:00",
        friday    => "00:00-24:00",
        saturday  => "00:00-24:00",
        sunday    => "00:00-24:00",
        notify    => Service["nagios"],
    }

}


# Install Nagios server and collect node configurations.
#
class nagios::server inherits nagios::server::manual {

    Nagios::Host <<||>> {
        confdir => $confdir,
        notify  => Service["nagios"],
    }
    Nagios::Service <<||>> {
        confdir => $confdir,
        notify  => Service["nagios"],
    }

}


# Define nagios email contact.
#
# === Parameters
#
#   $name:
#       Email address.
#   $group:
#       List of contact groups. Defaults to "all".
#
define nagios::contact::email($group=["all"],
                              $confdir=$nagios::common::confdir) {

    $contactgroups = inline_template('<%= group.join(",") -%>')

    file { "${confdir}/contact_${name}.cfg":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => "nagios",
        before  => Nagios_Contact[$name],
        require => File["/etc/nagios/conf.d"],
    }
    nagios_contact { $name:
        target                        => "${confdir}/contact_${name}.cfg",
        contactgroups                 => $contactgroups,
        host_notification_commands    => "notify-host-by-email",
        host_notification_options     => "d,r",
        host_notification_period      => "24x7",
        service_notification_commands => "notify-service-by-email",
        service_notification_options  => "w,u,c,r",
        service_notification_period   => "24x7",
        email                         => $name,
        notify                        => Service["nagios"],
    }

}


# Define nagios prowl contact.
#
# === Parameters
#
#   $name:
#       Prowl API key.
#   $group:
#       List of contact groups. Defaults to "all".
#
define nagios::contact::prowl($group=["all"],
                              $confdir=$nagios::common::confdir) {

    $contactgroups = inline_template('<%= group.join(",") -%>')

    file { "${confdir}/contact_prowl_${name}.cfg":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => "nagios",
        before  => Nagios_Contact["prowl-${name}"],
        require => File["/etc/nagios/conf.d"],
    }
    nagios_contact { "prowl-${name}":
        target                        => "${confdir}/contact_prowl_${name}.cfg",
        contactgroups                 => $contactgroups,
        host_notification_commands    => "notify-host-by-prowl",
        host_notification_options     => "d,r",
        host_notification_period      => "24x7",
        service_notification_commands => "notify-service-by-prowl",
        service_notification_options  => "w,u,c,r",
        service_notification_period   => "24x7",
        address1                      => $name,
        notify                        => Service["nagios"],
    }

}


# Define nagios pushover contact.
#
# === Parameters
#
#   $name:
#       Pushover user key.
#   $token:
#       Pushover application token.
#   $group:
#       List of contact groups. Defaults to "all".
#
define nagios::contact::pushover($token, $group=["all"],
                                 $confdir=$nagios::common::confdir) {

    $contactgroups = inline_template('<%= group.join(",") -%>')

    file { "${confdir}/contact_pushover_${name}.cfg":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => "nagios",
        before  => Nagios_Contact["pushover-${name}"],
        require => File["/etc/nagios/conf.d"],
    }
    nagios_contact { "pushover-${name}":
        target                        => "${confdir}/contact_pushover_${name}.cfg",
        contactgroups                 => $contactgroups,
        host_notification_commands    => "notify-host-by-pushover",
        host_notification_options     => "d,r",
        host_notification_period      => "24x7",
        service_notification_commands => "notify-service-by-pushover",
        service_notification_options  => "w,u,c,r",
        service_notification_period   => "24x7",
        address1                      => $name,
        address2                      => $token,
        notify                        => Service["nagios"],
    }

}


# Define nagios target host.
#
# === Parameters
#
#   $name:
#       Hostname of target.
#   $group:
#       Hostgroup name.
#   $osname:
#       Operating system name for hostextinfo.
#   $osicon:
#       Operating system icon name for hostextinfo.
#
define nagios::host($group="NONE", $osname="NONE", $osicon="NONE",
                    $confdir=$nagios::common::confdir) {

    file { "${confdir}/host_${name}.cfg":
        ensure  => present,
                mode    => "0640",
                owner   => "root",
                group   => "nagios",
                before  => Nagios_Host[$name],
                require => File["/etc/nagios/conf.d"],
    }
    nagios_host { $name:
        ensure => present,
        use    => "default",
        target => "${confdir}/host_${name}.cfg"
    }

    if $osicon != "NONE" {
        case $::operatingsystem {
            "debian","ubuntu": {
                $iconpath = "base/"
            }
            default: {
                $iconpath = ""
            }
        }
        file { "${confdir}/hostextinfo_${name}.cfg":
            ensure  => present,
            mode    => "0640",
            owner   => "root",
            group   => "nagios",
            before  => Nagios_Hostextinfo[$name],
            require => File["/etc/nagios/conf.d"],
        }
        nagios_hostextinfo { $name:
            ensure          => present,
            icon_image_alt  => $osname,
            icon_image      => "${iconpath}${osicon}.png",
            statusmap_image => "${iconpath}${osicon}.gd2",
            target          => "${confdir}/hostextinfo_${name}.cfg"
        }
    }

    if $group != "NONE" {
        if !defined(Nagios_Contactgroup[$group]) {
            file { "${confdir}/contactgroup_${group}.cfg":
                ensure  => present,
                mode    => "0640",
                owner   => "root",
                group   => "nagios",
                before  => Nagios_Contactgroup[$group],
                require => File["/etc/nagios/conf.d"],
            }
            nagios_contactgroup { $group:
                target  => "${confdir}/contactgroup_${group}.cfg",
                notify  => Service["nagios"],
            }
        }
        if !defined(Nagios_Hostgroup[$group]) {
            file { "${confdir}/hostgroup_${group}.cfg":
                ensure  => present,
                mode    => "0640",
                owner   => "root",
                group   => "nagios",
                before  => Nagios_Hostgroup[$group],
                require => File["/etc/nagios/conf.d"],
            }
            nagios_hostgroup { $group:
                target  => "${confdir}/hostgroup_${group}.cfg",
                notify  => Service["nagios"],
            }
        }
        Nagios_Host[$name] {
            contact_groups => "all,${group}",
            hostgroups     => $group,
        }
    }

}


# Define nagios target service.
#
# === Parameters
#
#   $host:
#       Target hostname.
#   $command:
#       Check command.
#   $description:
#       Service description.
#   $group:
#       Hostgroup name.
#
define nagios::service($host, $command, $description, $group="NONE",
                       $confdir=$nagios::common::confdir) {

    file { "${confdir}/service_${name}.cfg":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => "nagios",
        before  => Nagios_Service[$name],
        require => File["/etc/nagios/conf.d"],
    }
    nagios_service { $name:
        host_name           => $host,
        check_command       => $command,
        service_description => $description,
        use                 => "default",
        target              => "${confdir}/service_${name}.cfg",
        require             => Nagios_Host[$host],
    }

    if $group != "NONE" {
        Nagios_Service[$name] {
            contact_groups => "all,${group}",
        }
    }

}


# Install check_esxi_hardware.py plugin.
#
class nagios::plugin::esxi {

    package { "pywbem":
        ensure => installed,
        name   => $::operatingsystem ? {
            "debian" => "python-pywbem",
            "ubuntu" => "python-pywbem",
            default  => "pywbem",
        },
     }

     file { "${nagios::common::libdir}/check_esxi_hardware.py":
        ensure  => present,
        mode    => "0755",
        owner   => "root",
        group   => "root",
        source  => "puppet:///files/nagios/check_esxi_hardware.py",
        require => Package["nagios"],
    }

}


# Define ESXi target host.
#
# === Parameters
#
#   $name:
#       Target hostname.
#   $user:
#       ESXi host username.
#   $pass:
#       ESXi host password.
#   $vendor:
#       ESXi host vendor. Defaults to "auto".
#
define nagios::host::esxi($user, $pass, $vendor="auto") {

    file { "${nagios::common::private}/esxi_${name}.cfg":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => "nagios",
        content => "${user} ${pass}\n",
        require => File["/etc/nagios/private.d"],
    }

    nagios::host { $name:
        confdir => $nagios::common::confdir,
        notify  => Service["nagios"],
    }

    nagios::service { "${name}_esxi":
        host        => $name,
        command     => "check_esxi_hardware!${nagios::common::private}/esxi_${name}.cfg!${vendor}",
        description => "ESXi",
        confdir     => $nagios::common::confdir,
        notify      => Service["nagios"],
    }

}
