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 configuration for this node for
      # directly hosted nodes.
      Munin_node <<| title == $hostname |>>
    }
    "third-party": {
      # Apply munin configuration for this node for third-party
      # hosted nodes.
      munin_node { "$hostname": }
    }
  }

  # Define a vserver instance
  define instance($context, $ensure = 'running', $proxy = false,
                  $puppetmaster = false, $gitd = false, $mail = false,
                  $icecast = false, $sound = false, $ticket = false,
                  $memory_limit = 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" }
    }

    vserver { $name:
      ensure       => $ensure,
      context      => "$context",
      mark         => 'default',
      distro       => 'lenny',
      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://$server/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 => "49$id",
    }

    # Sound support
    if $sound {
      if !defined(File["/usr/local/sbin/create-sound-devices"]) {
        file { "/usr/local/sbin/create-sound-devices":
          ensure => present,
          source => "puppet://$server/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"] ],
      }
    }

    # Apply firewall rules just for running vservers
    case $ensure {
      'running': {

        shorewall::rule { "ssh-$context-1":
          action          => 'DNAT',
          source          => 'net',
          destination     => "vm:192.168.0.$context:22",
          proto           => 'tcp',
          destinationport => "22$id",
          ratelimit       => '-',
          order           => "2$id",
        }

        shorewall::rule { "ssh-$context-2":
          action          => 'DNAT',
          source          => '$FW',
          destination     => "fw:192.168.0.$context:22",
          proto           => 'tcp',
          destinationport => "22$id",
          originaldest    => "$ipaddress",
          ratelimit       => '-',
          order           => "3$id",
        }

        shorewall::rule { "munin-$context-1":
          action          => 'DNAT',
          source          => 'net',
          destination     => "fw:192.168.0.$context:49$id",
          proto           => 'tcp',
          destinationport => "49$id",
          ratelimit       => '-',
          order           => "4$id",
        }

        shorewall::rule { "munin-$context-2":
          action          => 'DNAT',
          source          => '$FW',
          destination     => "fw:192.168.0.$context:49$id",
          proto           => 'tcp',
          destinationport => "49$id",
          originaldest    => "$ipaddress",
          ratelimit       => '-',
          order           => "5$id",
        }

        if $proxy {
          shorewall::rule { 'http-route-1':
            action          => 'DNAT',
            source          => 'net',
            destination     => "vm:192.168.0.$context:80",
            proto           => 'tcp',
            destinationport => '80',
            ratelimit       => '-',
            order           => '600',
          }

          shorewall::rule { 'http-route-2':
            action          => 'DNAT',
            source          => '$FW',
            destination     => "fw:192.168.0.$context:80",
            proto           => 'tcp',
            destinationport => '80',
            originaldest    => "$ipaddress",
            ratelimit       => '-',
            order           => '601',
          }

          shorewall::rule { 'https-route-1':
            action          => 'DNAT',
            source          => 'net',
            destination     => "vm:192.168.0.$context:443",
            proto           => 'tcp',
            destinationport => '443',
            ratelimit       => '-',
            order           => '602',
          }

          shorewall::rule { 'https-route-2':
            action          => 'DNAT',
            source          => '$FW',
            destination     => "fw:192.168.0.$context:443",
            proto           => 'tcp',
            destinationport => '443',
            originaldest    => "$ipaddress",
            ratelimit       => '-',
            order           => '602',
          }
        }

        if $puppetmaster {
          shorewall::rule { 'puppetmaster-1':
            action          => 'DNAT',
            source          => 'net',
            destination     => "fw:192.168.0.$context:$puppetmaster_port",
            proto           => 'tcp',
            destinationport => "$puppetmaster_port",
            ratelimit       => '-',
            order           => '700',
          }

          shorewall::rule { 'puppetmaster-2':
            action          => 'DNAT',
            source          => 'net',
            destination     => "fw:192.168.0.$context:$puppetmaster_port",
            proto           => 'udp',
            destinationport => "$puppetmaster_port",
            ratelimit       => '-',
            order           => '701',
          }

          shorewall::rule { 'puppetmaster-3':
            action          => 'DNAT',
            source          => '$FW',
            destination     => "fw:192.168.0.$context:$puppetmaster_port",
            proto           => 'tcp',
            destinationport => "$puppetmaster_port",
            originaldest    => "$ipaddress",
            ratelimit       => '-',
            order           => '702',
          }

          shorewall::rule { 'puppetmaster-4':
            action          => 'DNAT',
            source          => '$FW',
            destination     => "fw:192.168.0.$context:$puppetmaster_port",
            proto           => 'udp',
            destinationport => "$puppetmaster_port",
            originaldest    => "$ipaddress",
            ratelimit       => '-',
            order           => '703',
          }

          shorewall::rule { 'puppetmaster-5':
            action          => 'DNAT',
            source          => 'net',
            destination     => "fw:192.168.0.$context:$puppetmaster_nonssl_port",
            proto           => 'tcp',
            destinationport => "$puppetmaster_nonssl_port",
            ratelimit       => '-',
            order           => '704',
          }

          shorewall::rule { 'puppetmaster-6':
            action          => 'DNAT',
            source          => 'net',
            destination     => "fw:192.168.0.$context:$puppetmaster_nonssl_port",
            proto           => 'udp',
            destinationport => "$puppetmaster_nonssl_port",
            ratelimit       => '-',
            order           => '705',
          }

          shorewall::rule { 'puppetmaster-7':
            action          => 'DNAT',
            source          => '$FW',
            destination     => "fw:192.168.0.$context:$puppetmaster_nonssl_port",
            proto           => 'tcp',
            destinationport => "$puppetmaster_nonssl_port",
            originaldest    => "$ipaddress",
            ratelimit       => '-',
            order           => '706',
          }

          shorewall::rule { 'puppetmaster-8':
            action          => 'DNAT',
            source          => '$FW',
            destination     => "fw:192.168.0.$context:$puppetmaster_nonssl_port",
            proto           => 'udp',
            destinationport => "$puppetmaster_nonssl_port",
            originaldest    => "$ipaddress",
            ratelimit       => '-',
            order           => '707',
          }
        }

        if $gitd {
          shorewall::rule { 'git-daemon-1':
            action          => 'DNAT',
            source          => 'net',
            destination     => "fw:192.168.0.$context:9418",
            proto           => 'tcp',
            destinationport => '9418',
            ratelimit       => '-',
            order           => '800',
          }

          shorewall::rule { 'git-daemon-2':
            action          => 'DNAT',
            source          => '$FW',
            destination     => "fw:192.168.0.$context:9418",
            proto           => 'tcp',
            destinationport => '9418',
            originaldest    => "$ipaddress",
            ratelimit       => '-',
            order           => '801',
          }
        }

        if $icecast {
          shorewall::rule { 'icecast-1':
            action          => 'DNAT',
            source          => 'net',
            destination     => "fw:192.168.0.$context:8000",
            proto           => 'tcp',
            destinationport => '8000',
            ratelimit       => '-',
            order           => '900',
          }

          shorewall::rule { 'icecast-2':
            action          => 'DNAT',
            source          => '$FW',
            destination     => "fw:192.168.0.$context:8000",
            proto           => 'tcp',
            destinationport => '8000',
            originaldest    => "$ipaddress",
            ratelimit       => '-',
            order           => '901',
          }
        }

        if $mail {
          shorewall::rule { 'mail-1':
            action          => 'DNAT',
            source          => 'net',
            destination     => "fw:192.168.0.$context:25",
            proto           => 'tcp',
            destinationport => '25',
            ratelimit       => '-',
            order           => '1000',
          }

          shorewall::rule { 'mail-2':
            action          => 'DNAT',
            source          => '$FW',
            destination     => "fw:192.168.0.$context:25",
            proto           => 'tcp',
            destinationport => '25',
            originaldest    => "$ipaddress",
            ratelimit       => '-',
            order           => '1001',
          }
        }
      }
    }
  }
}