
# Install common parts of DHCP server
#
class dhcp::server::common {

    case $::operatingsystem {
        "centos","redhat": {
            case $::operatingsystemrelease {
                /[45]\.[0-9]/: {
                    $confdir = "/etc"
                }
                default: {
                    $confdir = "/etc/dhcp"
                }
            }
        }
        "debian","ubuntu": {
            $confdir = "/etc/dhcp3"
        }
        "fedora": {
            $confdir = "/etc/dhcp"
        }
        default: {
            $confdir = "/etc"
        }
    }

    package { "dhcp":
        name   => $::operatingsystem ? {
            Debian  => "dhcp3-server",
            OpenBSD => "isc-dhcp-server",
            Ubuntu  => "dhcp3-server",
            default => "dhcp",
        },
        ensure => installed,
    }

    file { "dhcpd.leases":
        name    => $::operatingsystem ? {
            Debian  => "/var/lib/dhcp3/dhcpd.leases",
            OpenBSD => "/var/db/dhcpd.leases",
            Ubuntu  => "/var/lib/dhcp3/dhcpd.leases",
            default => "/var/lib/dhcpd/dhcpd.leases",
        },
        ensure  => present,
        owner   => $::operatingsystem ? {
            debian  => dhcpd,
            ubuntu  => dhcpd,
            default => root,
        },
        group   => $::operatingsystem ? {
            Debian  => dhcpd,
            OpenBSD => wheel,
            Ubuntu  => dhcpd,
            default => root,
        },
        require => Package["dhcp"],
        before  => Service["dhcpd"],
    }

    if $::operatingsystem == "OpenBSD" and $::operatingsystemrelease !~ /4\.[1-8]/ {
        file { "/etc/rc.d/isc_dhcpd":
            ensure => present,
            mode   => "0555",
            owner  => "root",
            group  => "bin",
            source => "puppet:///modules/dhcp/isc_dhcpd.rc",
            before => Service["dhcpd"],
        }
    }

    service { "dhcpd":
        name    => $::operatingsystem ? {
            Debian  => "dhcp3-server",
            OpenBSD => $::operatingsystemrelease ? {
                /4\.[1-8]/ => "isc-dhcpd",
                default    => "isc_dhcpd",
            },
            Ubuntu  => "dhcp3-server",
            default => "dhcpd",
        },
        ensure  => running,
        enable  => true,
        binary  => $::operatingsystem ? {
            OpenBSD => "/usr/local/sbin/dhcpd",
            default => undef,
        },
        start   => $::operatingsystem ? {
            OpenBSD => $dhcp_server_interface ? {
                ""      => "/usr/local/sbin/dhcpd -q",
                default => "/usr/local/sbin/dhcpd -q ${dhcp_server_interface}",
            },
            default => undef,
        },
        require => Package["dhcp"],
    }

    if $dhcp_server_interface {
        case $::operatingsystem {
            "fedora","centos","redhat": {
                file { "/etc/sysconfig/dhcpd":
                    ensure  => present,
                    content => "DHCPDARGS=${dhcp_server_interface}\n",
                    mode    => "0644",
                    owner   => "root",
                    group   => "root",
                    notify  => Service["dhcpd"],
                }
            }
            "openbsd": {}
            default: {
                fail("Variable \${dhcp_server_interface} not supported in ${::operatinsystem}")
            }
        }
    }

}


# Install DHCP server with static config.
#
# === Global variables
#
#   $dhcp_server_interface:
#       Interface that DHCP server should listen. Defaults to all.
#
class dhcp::server inherits dhcp::server::common {

    file { "dhcpd.conf":
        name   => "${confdir}/dhcpd.conf",
        ensure => present,
        source => [ "puppet:///files/dhcp/dhcpd.conf.${fqdn}",
                    "puppet:///files/dhcp/dhcpd.conf", ],
        mode   => "0644",
        owner  => root,
        group  => $::operatingsystem ? {
            openbsd => wheel,
            default => root,
        },
        notify => Service["dhcpd"],
    }

}


# Install DHCP server and generate config from LDAP.
#
# === Global variables
#
#   $dhcp_server_interface:
#       Interface that DHCP server should listen. Defaults to all.
#
class dhcp::server::ldap inherits dhcp::server::common {

    include python
    include ldap::client

    file { "/usr/local/sbin/dhcpdump.py":
        ensure  => present,
        source  => "puppet:///modules/dhcp/dhcpdump.py",
        mode    => "0755",
        owner   => root,
        group   => $::operatingsystem ? {
            OpenBSD => wheel,
            default => root,
        },
    }

    file { "dhcpd.conf.in":
        ensure  => present,
        name    => "${confdir}/dhcpd.conf.in",
        source  => [ "puppet:///files/dhcp/dhcpd.conf.in.${hostname}",
                     "puppet:///files/dhcp/dhcpd.conf.in", ],
        mode    => "0644",
        owner   => root,
        group   => $::operatingsystem ? {
            OpenBSD => wheel,
            default => root,
        },
        require => Package["dhcp"],
    }

    exec { "generate-dhcp-conf":
        path    => "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin",
        command => "dhcpdump.py ${confdir}/dhcpd.conf.in* > ${confdir}/dhcpd.conf",
        unless  => "dhcpdump.py ${confdir}/dhcpd.conf.in* | diff ${confdir}/dhcpd.conf -",
        require => [
          File["dhcpd.conf.in"],
          File["/usr/local/sbin/dhcpdump.py"],
          Class["python"],
          Class["ldap::client"],
        ],
        notify  => Service["dhcpd"],
    }

}

# Configure DHCP relay
#
# === Parameters
#
#   $name:
#       Relay name (can be anything).
#   $interface:
#       IP address for interface to listen.
#   $server_addr:
#       Address for DHCP server to relay requests.
#
# === Sample usage
#
# dhcp::relay { "relay0": interface => "em2", server_addr => "10.20.110.11" }
#

define dhcp::relay ($interface, $server_addr) {
    service { $name:
        name       => $name,
        ensure     => running,
        provider   => "base",
        hasrestart => false,
        hasstatus  => false,
        pattern    => "/usr/sbin/dhcrelay -i ${interface} ${server_addr}",
        start      => $::operatingsystem ? {
            OpenBSD => "/usr/sbin/dhcrelay -i ${interface} ${server_addr}",
            default => undef,
        }
    }
}

