import "debian.pp"
import "redhat.pp"

# Install Apache, www logrotate script and cron job.
#
class apache::common {

    case $operatingsystem {
        debian,ubuntu: {
            if ! $httpd_user {
                $user = "www-data"
            } else {
                $user = $httpd_user
            }
            if ! $httpd_group {
                $group = "www-data"
            } else {
                $group = $httpd_group
            }
        }
    }

    if $apache_datadir {
        file { "${apache_datadir}":
            ensure  => directory,
            mode    => 0755,
            owner   => "root",
            group   => "root",
            seltype => "httpd_sys_content_t",
        }

        file { "/srv/www":
            ensure  => link,
            target  => "${apache_datadir}",
            require => File["${apache_datadir}"],
        }
    } else {
        file { "/srv/www":
            ensure => directory,
            mode   => 0755,
            owner  => root,
            group  => root,
        }
    }

    file { "/srv/www/log":
        ensure  => directory,
        mode    => 0755,
        owner   => root,
        group   => root,
        require => File["/srv/www"],
    }

    if "${selinux}" == "true" {
        if $apache_datadir {
            selinux::manage_fcontext { "${apache_datadir}(/.*)?":
                type   => "httpd_sys_content_t",
                before => File["${apache_datadir}"],
            }
        }
    }

    package { "httpd":
        name   => $operatingsystem ? {
            debian  => "apache2",
            ubuntu  => "apache2",
            default => "httpd",
        },
        ensure => installed,
    }

    file { "/usr/local/sbin/www-logrotate.sh":
        ensure => present,
        source => "puppet:///modules/apache/www-logrotate.sh",
        mode   => 0755,
        owner  => root,
        group  => root,
        seluser => "system_u",
        selrole => "object_r",
        seltype => "httpd_rotatelogs_exec_t",
    }

    cron { "www-logrotate":
        ensure  => present,
        command => "/usr/local/sbin/www-logrotate.sh",
        user    => "root",
        hour    => "0",
        minute  => "0",
        weekday => "1",
        require => File["/usr/local/sbin/www-logrotate.sh"],
    }

}


# Configure HTTP server.
#
# === Global variables
#
#   $httpd_user:
#       User httpd runs as. Defaults to apache.
#   $httpd_group:
#       Group httpd runs as. Defaults to apache.
#
class apache::server inherits apache::common {

    case $operatingsystem {
        debian,ubuntu: {
            include apache::debian::server
        }
        centos,fedora: {
            if ! $httpd_user {
                $user = "apache"
            } else {
                $user = $httpd_user
            }
            if ! $httpd_group {
                $group = "apache"
            } else {
                $group = $httpd_group
            }
            include apache::redhat::server
        }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Configure HTTP virtual host.
#
# === Parameters
#
#   $name:
#       FQDN of virtual host.
#   $aliases:
#       Optional ServerAlias for this virtual host.
#   $root:
#       Path to document root. Defaults to /srv/www/http/$fqdn
#   $redirect:
#       Add redirect to given URL.
#
# === Sample usage
#
# apache::site { "default":
#     redirect => "http://www.example.com/",
# }
# apache::site { "www.example.com":
#     root   => "/roles/prteam/public/public_access",
# }
#
define apache::site($aliases="", $root="", $redirect="") {

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::site { "${name}":
                aliases  => $aliases,
                root     => $root,
                redirect => $redirect,
            }
        }
        centos,fedora: {
            apache::redhat::site { "${name}":
                aliases  => $aliases,
                root     => $root,
                redirect => $redirect,
            }
        }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

    if !$redirect {
        $site_fqdn = $name ? {
            "default" => "${homename}",
            default   => "${name}",
        }
        apache::webalizer::site { "http/${site_fqdn}":
            site_proto => "http",
            site_fqdn  => $site_fqdn,
        }
    }

}


# Configure HTTPS server.
#
# === Global variables
#
#   $httpsd_user:
#       User httpsd runs as. Defaults to httpsd.
#   $httpsd_group:
#       Group httpsd runs as. Defaults to httpsd.
#
class apache::sslserver inherits apache::common {

    case $operatingsystem {
        debian,ubuntu: {
            include apache::debian::sslserver
        }
        centos,fedora: {
            if ! $httpsd_user {
                $user = "httpsd"
            } else {
                $user = $httpsd_user
            }
            if ! $httpsd_group {
                $group = "httpsd"
            } else {
                $group = $httpsd_group
            }
            include apache::redhat::sslserver
        }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Enable SSL on port 443.
#
class apache::sslserver::listen {

    apache::configfile { "ssl.conf":
        content => template("apache/ssl.conf.erb"),
        http    => false,
        require => Class["apache::sslserver"],
    }

}


# Configure HTTPS virtual host.
#
# === Parameters
#
#   $name:
#       FQDN of virtual host.
#   $ipaddr:
#       IP address of virtual host. Defaults to _default_.
#   $root:
#       Path to document root. Defaults to /srv/www/https/$fqdn
#   $ssl_cert:
#       Path to SSL certificate. Defaults to puppet client certificate.
#   $ssl_key:
#       Path to SSL private key. Defaults to puppet client certificate.
#   $ssl_chain:
#       Path to SSL certificate chain. Defaults to none.
#
# === Sample usage
#
# apache::site { "www.example.com":
#     root     => "/roles/prteam/public/secure_access",
#     ssl_cert => "puppet:///path/to/www.example.com.crt",
#     ssl_key  => "puppet:///path/to/www.example.com.key",
# }
#
define apache::sslsite($ipaddr="_default_", $root="", $ssl_cert="", $ssl_key="", $ssl_chain="") {

    include apache::sslserver::listen

    case $operatingsystem {
        debian,ubuntu: {
            $apache_ssldir = "/etc/ssl"
            apache::debian::sslsite { "${name}":
                ipaddr    => $ipaddr,
                root      => $root,
                ssl_cert  => $ssl_cert,
                ssl_key   => $ssl_key,
                ssl_chain => $ssl_chain,
                require   => Class["apache::sslserver::listen"],
            }
        }
        centos,fedora: {
            $apache_ssldir = "/etc/pki/tls"
            apache::redhat::sslsite { "${name}":
                ipaddr    => $ipaddr,
                root      => $root,
                ssl_cert  => $ssl_cert,
                ssl_key   => $ssl_key,
                ssl_chain => $ssl_chain,
                require   => Class["apache::sslserver::listen"],
            }
        }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

    $site_fqdn = $name ? {
        "default" => "${homename}",
        default   => "${name}",
    }
    apache::webalizer::site { "https/${site_fqdn}":
        site_proto => "https",
        site_fqdn  => $site_fqdn,
    }

}


# Install extra configuration file.
#
# === Parameters
#
#   $name:
#       Config file name.
#   $source:
#       Config file source. Defaults to /etc/httpd/conf.d/$name
#       if neither $source nor $content is defined.
#   $content:
#       Config file content. See also $source.
#   $require:
#       Dependencies for the config file.
#   $http:
#       Set to false to disable config on http server.
#   $https:
#       Set to false to disable config on https server.
#
# === Sample usage
#
#apache::configfile { "auth_kerb.conf":
#    content => template("apache/auth_kerb.conf.erb"),
#    require => Package["mod_auth_kerb"],
#    http    => false,
#}
#
define apache::configfile($source="", $content="", $http=true, $https=true) {

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::configfile { "${name}":
                source  => "${source}",
                content => "${content}",
                http    => $http,
                https   => $https,
            }
        }
        centos,fedora: {
            apache::redhat::configfile { "${name}":
                source  => "${source}",
                content => "${content}",
                http    => $http,
                https   => $https,
            }
        }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install mod_auth_kerb.
#
class apache::mod::auth_kerb {

    package { "mod_auth_kerb":
        ensure  => installed,
        require => Package["httpd"],
    }

    apache::configfile { "auth_kerb.conf":
        content => template("apache/auth_kerb.conf.erb"),
        require => Package["mod_auth_kerb"],
        http    => false,
    }

}


# Install mod_authnz_ldap.
#
class apache::mod::authnz_ldap {

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "authnz_ldap": }
        }
        centos,fedora: { }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}

# Install mod_include
#
class apache::mod::include {

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "include": }
        }
        centos,fedora: { }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}

# Install mod_fcgid.
#
class apache::mod::fcgid {

    package { "mod_fcgid":
        name    => $operatingsystem ? {
            debian  => "libapache2-mod-fcgid",
            ubuntu  => "libapache2-mod-fcgid",
            default => "mod_fcgid",
        },
        ensure => installed,
        require => Package["httpd"],
    }

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "fcgid":
                require => Package ["libapache2-mod-fcgid"],
            }
        }
        centos,fedora: {
            apache::configfile { "fcgid.conf":
                require => Package["mod_fcgid"],
            }
        }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install mod_headers.
#
class apache::mod::headers {

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "headers": }
        }
        centos,fedora: { }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install mod_ldap.
#
class apache::mod::ldap {

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "ldap": }
        }
        centos,fedora: { }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install mod_perl.
#
class apache::mod::perl {

    package { "mod_perl":
        name    => $operatingsystem ? {
            debian  => "libapache2-mod-perl2",
            ubuntu  => "libapache2-mod-perl2",
            default => "mod_perl",
        },
        ensure => installed,
        require => Package["httpd"],
    }

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "perl2":
                require => Package ["libapache2-mod-perl2"],
            }
        }
        centos,fedora: {
            apache::configfile { "perl.conf":
                require => Package["mod_perl"],
            }
        }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install PHP.
#
class apache::mod::php {

    package { "php":
        name    => $operatingsystem ? {
            debian  => "libapache2-mod-php5",
            ubuntu  => "libapache2-mod-php5",
            default => "php",
        },
        ensure => installed,
        require => Package["httpd"],
    }

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "php5":
                require => Package ["libapache2-mod-php5"],
            }
        }
        centos,fedora: {
            apache::configfile { "php.conf":
                require => Package["php"],
            }
        }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install mod_proxy
#
class apache::mod::proxy {

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "proxy":
                content => template("apache/proxy.conf.erb"),
            }
        }
        centos,fedora: {
            apache::configfile { "proxy.conf":
                content => template("apache/proxy.conf.erb"),
            }
        }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install mod_proxy_http
#
class apache::mod::proxy_http {

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "proxy_http": }
        }
        centos,fedora: { }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install mod_proxy_balancer
#
class apache::mod::proxy_balancer {

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "proxy_balancer": }
        }
        centos,fedora: { }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install mod_python.
#
class apache::mod::python {

    package { "mod_python":
        name    => $operatingsystem ? {
            debian  => "libapache2-mod-python",
            ubuntu  => "libapache2-mod-python",
            default => "mod_python",
        },
        ensure => installed,
        require => Package["httpd"],
    }

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "python":
                require => Package ["libapache2-mod-python"],
            }
        }
        centos,fedora: {
            apache::configfile { "python.conf":
                require => Package["mod_python"],
            }
        }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install mod_rewrite.
#
class apache::mod::rewrite {

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "rewrite": }
        }
        centos,fedora: { }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install mod_wsgi.
#
class apache::mod::wsgi {

    package { "mod_wsgi":
        name    => $operatingsystem ? {
            debian  => "libapache2-mod-wsgi",
            ubuntu  => "libapache2-mod-wsgi",
            default => "mod_wsgi",
        },
        ensure  => installed,
        require => Package["httpd"],
    }

    case $operatingsystem {
        debian,ubuntu: {
            apache::debian::a2enmod { "wsgi":
                require => Package ["libapache2-mod-wsgi"],
            }
        }
        centos,fedora: {
            apache::configfile { "wsgi.conf":
                require => Package["mod_wsgi"],
            }
        }
        default: {
            fail("Apache module not supported in ${operatingsystem}.")
        }
    }

}


# Install and configure webalizer.
#
class apache::webalizer {

    package { "webalizer":
        ensure => installed,
    }

    file { [ "/srv/www/webalizer",
             "/srv/www/webalizer/history",
             "/srv/www/webalizer/history/http",
             "/srv/www/webalizer/history/https",
             "/srv/www/webalizer/html/http",
             "/srv/www/webalizer/html/https",
             "/srv/www/webalizer/html", ]:
        ensure  => directory,
        mode    => 0755,
        owner   => $operatingsystem ? {
            debian  => root,
            ubuntu  => root,
            default => webalizer,
        },
        group   => root,
        require => [ File["/srv/www"], Package["webalizer"], ],
    }

    file { [ "/etc/webalizer",
             "/etc/webalizer/http",
             "/etc/webalizer/https", ]:
        ensure  => directory,
        mode    => 0644,
        owner   => root,
        group   => root,
    }

    File["/etc/webalizer/http", "/etc/webalizer/https"] {
        purge   => true,
        force   => true,
        recurse => true,
        source  => "puppet:///modules/custom/empty",
    }

    case $operatingsystem {
        debian,ubuntu: {
            file { "/etc/cron.daily/webalizer":
                ensure  => absent,
                require => Package["webalizer"],
            }
        }
        default: {
            file { "/etc/cron.daily/00webalizer":
                ensure  => absent,
                require => Package["webalizer"],
            }
        }
    }

    file { "/usr/local/sbin/www-webalizer.sh":
        ensure  => present,
        source  => "puppet:///modules/apache/www-webalizer.sh",
        mode    => 0755,
        owner   => root,
        group   => root,
        require => Package["webalizer"],
    }

    cron { "www-webalizer":
        ensure  => present,
        command => "/usr/local/sbin/www-webalizer.sh",
        user    => $operatingsystem ? {
            debian  => root,
            ubuntu  => root,
            default => webalizer,
        },
        hour    => 23,
        minute  => 59,
        require => File["/usr/local/sbin/www-webalizer.sh"],
    }

    File <| tag == "webalizer" |>

}


define apache::webalizer::site($site_proto, $site_fqdn) {

    @file { "/etc/webalizer/${name}.conf":
        ensure  => present,
        mode    => 0644,
        owner   => root,
        group   => root,
        content => template("apache/webalizer.conf.erb"),
        require => File["/etc/webalizer/${site_proto}"],
        tag     => "webalizer",
    }

    @file { [ "/srv/www/webalizer/history/${name}",
              "/srv/www/webalizer/html/${name}", ]:
        ensure  => directory,
        mode    => 0755,
        owner   => $operatingsystem ? {
            debian  => root,
            ubuntu  => root,
            default => webalizer,
        },
        group   => root,
        require => [ File["/srv/www/webalizer/history/${site_proto}"],
                     File["/srv/www/webalizer/html/${site_proto}"], ],
        tag     => "webalizer",
    }

}
