class nodo::vserver inherits nodo {
  include sshd
  include timezone
  include syslog-ng::vserver

  backupninja::sys { "sys":
    ensure     => present,
    partitions => false,
    hardware   => false,
    dosfdisk   => false,
    dohwinfo   => false,
  }

  $hosting_type = $node_hosting_type ? {
    ''      => "direct",
    default => "$node_hosting_type",
  }

  case $hosting_type {
    "direct": {
      # Apply munin and monkeysphere configuration for
      # for directly hosted nodes.
      Munin_node        <<| title == $hostname |>>
      Monkeysphere_host <<| title == $hostname |>>

      # Set proxy configuration
      $apache_https_proxy = 'yes'
    }
    "third-party": {
      # Apply munin and monkeysphere configuration for
      # nodes hosted by third-parties.
      munin_node { "$hostname": }
      monkeysphere_host { "$hostname":
        port => $node_ssh_port,
      }

      # Nagios configuration
      if $use_nagios != false {
        include nagios::target::fqdn
        nagios::service::ping { "$fqdn": }
      }
    }
  }

  # Define a vserver instance
  define instance($context, $ensure = 'running', $proxy = false,
                  $puppetmaster = false, $gitd = false, $mail = false,
                  $icecast = false, $sound = false, $tor = false,
                  $ticket = false, $memory_limit = false, $distro = 'squeeze',
                  $dns = false, $munin_port = false, $monkeysphere_ssh_port = false,
                  $jabber = false, $mumble = false, $gobby = false, $yacy = false, $rsync = false) {

    # set instance id
    if $context <= 9 {
      $id = "0$context"
    } else {
      $id = $context
    }

    # set puppetmaster ssl port
    case $puppetmaster_port {
      '': { $puppetmaster_port = "8140" }
    }

    # set puppetmaster non-ssl port
    case $puppetmaster_nonssl_port {
      '': { $puppetmaster_nonssl_port = "8141" }
    }

    # set tor port
    case $tor_port {
      '': { $tor_port = "9001" }
    }

    vserver { $name:
      ensure       => $ensure,
      context      => "$context",
      mark         => 'default',
      distro       => $distro,
      interface    => "eth0:192.168.0.$context/24",
      hostname     => "$name.$domain",
      memory_limit => $memory_limit,
    }

    # Some nodes need a lot of space at /tmp otherwise some admin
    # tasks like backups might not run.
    file { "/etc/vservers/${name}/fstab":
      source  => [ "puppet:///modules/site-nodo/etc/fstab/vserver/$name",
                   "puppet:///modules/nodo/etc/fstab/vserver" ],
      owner   => "root",
      group   => "root",
      mode    => 0644,
      ensure  => present,
      notify  => Exec["vs_restart_${name}"],
      require => Exec["vs_create_${name}"],
    }

    # Create a munin virtual resource to be realized in the node
    @@munin_node { "$name":
      port => $munin_port ? {
        false   => "49$id",
        default => $munin_port,
      }
    }

    # Create a monkeysphere virtual resource to be realized in the node
    @@monkeysphere_host { "$name":
      port => $monkeysphere_ssh_port ? {
        false   => "22$id",
        default => $monkeysphere_ssh_port,
      }
    }

    # Sound support
    if $sound {
      if !defined(File["/usr/local/sbin/create-sound-devices"]) {
        file { "/usr/local/sbin/create-sound-devices":
          ensure => present,
          source => "puppet:///modules/nodo/sound/devices.sh",
          owner  => root,
          group  => root,
          mode   => 755,
        }
      }
      exec { "/usr/local/sbin/create-sound-devices ${name}":
        unless  => "/usr/local/sbin/create-sound-devices ${name} --check",
        user    => root,
        require => [ Exec["vs_create_${name}"], File["/usr/local/sbin/create-sound-devices"] ],
      }
    }

    # SSL computational DoS mitigation
    # See http://vincent.bernat.im/en/blog/2011-ssl-dos-mitigation.html
    $firewall_ssl_ratelimit = $firewall_ssl_ratelimit ? {
      ''      => $firewall_global_ssl_ratelimit ? {
        ''      => '-',
        default => $firewall_global_ssl_ratelimit,
      },
      default => $firewall_ssl_ratelimit,
    }

    # Apply firewall rules just for running vservers
    case $ensure {
      'running': {
        firewall::vserver::ssh { "$name":
          destination => "192.168.0.$context",
          port_orig => "22$id",
          port_dest => "22",
        }

        firewall::vserver::munin { "$name":
          destination => "192.168.0.$context",
          port_orig   => "49$id",
          port_dest   => "49$id",
        }

        if $proxy {
          class {
            "firewall::vserver::http":  destination => "192.168.0.$context";
            "firewall::vserver::https": destination => "192.168.0.$context";
          }
        }

        if $puppetmaster {
          class {
            "firewall::vserver::puppetmaster":
              destination              => "192.168.0.$context",
              puppetmaster_port        => $puppetmaster_port,
              puppetmaster_nonssl_port => $puppetmaster_nonssl_port,
          }
        }

        if $gitd {
          class {
            "firewall::vserver::gitd": destination => "192.168.0.$context";
          }
        }

        if $icecast {
          class {
            "firewall::vserver::icecast": destination => "192.168.0.$context";
          }
        }

        if $mail {
          class {
            "firewall::vserver::mail": destination => "192.168.0.$context";
          }
        }

        if $dns {
          class {
            "firewall::vserver::dns": destination => "192.168.0.$context";
          }
        }

        if $tor {
          class {
            "firewall::vserver::tor": destination => "192.168.0.$context";
          }
        }

        if $jabber {
          class {
            "firewall::vserver::jabber": destination => "192.168.0.$context";
          }
        }

        if $mumble {
          class {
            "firewall::vserver::mumble": destination => "192.168.0.$context";
          }
        }

        if $gobby {
          class {
            "firewall::vserver::gobby": destination => "192.168.0.$context";
          }
        }

        if $yacy {
          class {
            "firewall::vserver::yacy": destination => "192.168.0.$context";
          }
        }

        if $rsync {
          class {
            "firewall::vserver::rsync": destination => "192.168.0.$context";
          }
        }
      }
    }
  }
}