# Install ejabberd.
#
# === Global variables
#
#   $ejabberd_hosts:
#       Array of domains serverd by ejabberd. Defaults to [ "$homename" ].
#
#   $ejabberd_admin:
#       Array of users with admin privileges.
#
#   $ejabberd_ssl_key:
#       Path to SSL private key.
#
#   $ejabberd_ssl_cert:
#       Path to SSL certificate.
#
#   $ejabberd_ssl_chain:
#       Path to SSL certificate chain.
#
#   $ejabberd_muclog_datadir:
#       Path where to store chatroom logs. Disabled by default.
#
#   $ejabberd_muclog_format:
#       Chatroom log format. Valid values html or plaintext.
#
#   $ejabberd_auth:
#       Authentication method or array of multiple methods.
#       Valid values internal, external or ldap. Defaults to internal.
#
#   $ejabberd_extauth:
#       Path to external authentication command.
#
#   $ejabberd_ldap_server:
#       Array of LDAP authentication servers.
#
#   $ejabberd_ldap_basedn.
#       LDAP base dn.
#
class ejabberd {

    include user::system
    realize(User["ejabberd"], Group["ejabberd"])

    if !$ejabberd_hosts {
        $ejabberd_hosts = [ $homename ]
    }
    if !$ejabberd_admin {
        $ejabberd_admin = []
    }
    if !$ejabberd_auth {
        $ejabberd_auth = "internal"
    }

    case $ejabberd_muclog_format {
        "","html","plaintext": { }
        default: {
            fail("Invalid value ${ejabberd_muclog_format} for \$ejabberd_muclog_format.")
        }
    }

    package { "ejabberd":
        ensure  => installed,
        require => [ User["ejabberd"], Group["ejabberd"] ],
    }

    service { "ejabberd":
        ensure => running,
        enable => true,
        status => "ejabberdctl status >/dev/null",
    }

    case $::operatingsystem {
        "debian","ubuntu": {
            $cert_prefix = "/etc/ssl"
        }
        "centos","redhat","fedora": {
            $cert_prefix = "/etc/pki/tls"
        }
    }

    if $ejabberd_ssl_key and $ejabberd_ssl_cert {
        file { "${cert_prefix}/private/ejabberd.key":
            ensure => present,
            source => $ejabberd_ssl_key,
            mode   => "0600",
            owner  => "root",
            group  => "root",
            notify => Exec["generate-ejabberd-pem"],
        }
        file { "${cert_prefix}/certs/ejabberd.crt":
            ensure => present,
            source => $ejabberd_ssl_cert,
            mode   => "0644",
            owner  => "root",
            group  => "root",
            notify => Exec["generate-ejabberd-pem"],
        }
        if $ejabberd_ssl_chain {
            file { "${cert_prefix}/certs/ejabberd.chain.crt":
                ensure => present,
                source => $ejabberd_ssl_chain,
                mode   => "0644",
                owner  => "root",
                group  => "root",
                notify => Exec["generate-ejabberd-pem"],
            }
            $cert_files = "private/ejabberd.key certs/ejabberd.crt certs/ejabberd.chain.crt"
        } else {
            $cert_files = "private/ejabberd.key certs/ejabberd.crt"
        }
        exec { "generate-ejabberd-pem":
            path        => "/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin",
            cwd         => $cert_prefix,
            command     => "/bin/sh -c 'umask 077 ; cat ${cert_files} > /etc/ejabberd/ejabberd.pem'",
            refreshonly => true,
            before      => File["/etc/ejabberd/ejabberd.pem"],
            require     => Package["ejabberd"],
            notify      => Service["ejabberd"],
        }
    }

    file { "/etc/ejabberd/ejabberd.pem":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => "ejabberd",
        require => Package["ejabberd"],
    }

    file { "/etc/ejabberd/ejabberd.cfg":
        ensure  => present,
        mode    => "0640",
        owner   => "root",
        group   => "ejabberd",
        content => template("ejabberd/ejabberd.cfg.erb"),
        require => Package["ejabberd"],
        notify  => Service["ejabberd"],
    }

    case $::operatingsystem {
        "debian", "ubuntu": {
            augeas { "set-ejabberd-default":
                context => "/files/etc/default/ejabberd",
                changes => [ "set POLL true",
                             "set SMP auto", ],
                notify  => Service["ejabberd"],
            }
        }
    }

    $htdocs = "/usr/share/ejabberd/htdocs"

    define configwebhost() {
        file { "/srv/www/https/${name}/bosh":
            ensure  => link,
            target  => $htdocs,
            require => File["/srv/www/https/${name}"],
        }
    }

    if $ejabberd_webhosts {
        file { $htdocs:
            ensure  => directory,
            mode    => "0755",
            owner   => "root",
            group   => "root",
            require => Package["ejabberd"],
        }

        file { "${htdocs}/.htaccess":
            ensure  => present,
            mode    => "0644",
            owner   => "root",
            group   => "root",
            source  => "puppet:///modules/ejabberd/htaccess",
            require => File[$htdocs],
        }

        apache::configfile { "ejabberd.conf":
            http   => false,
            source => "puppet:///modules/ejabberd/ejabberd-httpd.conf",
        }

        configwebhost { $ejabberd_webhosts: }
    }

}


# Install ejabberd with collab customizations.
#
# === Global variables
#
#   $ejabberd_package:
#       Name of ejabberd package with collab patches.
#
class ejabberd::collab inherits ejabberd {

    if !$ejabberd_package {
        fail("Must define \$ejabberd_package")
    }

    exec { "usermod-ejabberd":
        path    => "/bin:/usr/bin:/sbin:/usr/sbin",
        command => "usermod -a -G collab ejabberd",
        unless  => "id -n -G ejabberd | grep '\\bcollab\\b'",
        require => [ User["ejabberd"], Group["collab"] ],
    }

    case $::operatingsystem {
        "centos","redhat","fedora": {
            package { ["erlang", "erlang-esasl"]:
                ensure => installed,
                before => Package["ejabberd"],
            }
        }
        "debian","ubuntu": {
            package { ["erlang", "erlang-base"]:
                ensure => installed,
                before => Package["ejabberd"],
            }
        }
    }
    file { "/usr/local/src/${ejabberd_package}":
        ensure => present,
        mode   => "0644",
        owner  => "root",
        group  => "root",
        source => "puppet:///files/packages/${ejabberd_package}",
        before => Package["ejabberd"],
    }
    Package["ejabberd"] {
        provider => $::operatingsystem ? {
            "centos" => "rpm",
            "redhat" => "rpm",
            "fedora" => "rpm",
            "debian" => "dpkg",
            "ubuntu" => "dpkg",
        },
        source   => "/usr/local/src/${ejabberd_package}",
    }

}


# Install ejabberd backup cron script.
#
# === Global variables
#
#   $ejabberd_backup_datadir:
#       Path where to store the backups.
#
class ejabberd::backup {

    if ! $ejabberd_backup_datadir {
        $ejabberd_backup_datadir = "/srv/ejabberd-backup"
    }

    file { $ejabberd_backup_datadir:
        ensure  => directory,
        mode    => "0700",
        owner   => "root",
        group   => "root",
    }

    file { "/usr/local/sbin/ejabberd-backup":
        ensure  => present,
        content => template("ejabberd/ejabberd-backup.erb"),
        mode    => "0755",
        owner   => "root",
        group   => "root",
    }

    cron { "ejabberd-backup":
        ensure  => present,
        command => "/usr/local/sbin/ejabberd-backup",
        user    => "root",
        minute  => 15,
        hour    => 21,
        require => File[ $ejabberd_backup_datadir,
                         "/usr/local/sbin/ejabberd-backup" ],
    }

}
