hubcap 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Capfile.example +37 -0
 - data/README.md +168 -0
 - data/Rakefile +10 -0
 - data/bin/hubcap +98 -0
 - data/hubcap.gemspec +17 -0
 - data/lib/hubcap/application.rb +24 -0
 - data/lib/hubcap/group.rb +223 -0
 - data/lib/hubcap/hub.rb +125 -0
 - data/lib/hubcap/recipes/puppet.rb +176 -0
 - data/lib/hubcap/recipes/servers.rb +21 -0
 - data/lib/hubcap/server.rb +46 -0
 - data/lib/hubcap/version.rb +5 -0
 - data/lib/hubcap.rb +29 -0
 - data/test/data/example.rb +68 -0
 - data/test/data/parts/foo_param.rb +1 -0
 - data/test/data/readme.rb +47 -0
 - data/test/data/simple.rb +4 -0
 - data/test/test_helper.rb +2 -0
 - data/test/unit/test_application.rb +20 -0
 - data/test/unit/test_group.rb +176 -0
 - data/test/unit/test_hub.rb +104 -0
 - data/test/unit/test_hubcap.rb +39 -0
 - data/test/unit/test_server.rb +69 -0
 - metadata +94 -0
 
| 
         @@ -0,0 +1,176 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Capistrano::Configuration.instance(:must_exist).load do
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              namespace(:puppet) do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                unless exists?(:puppet_repository)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  set(:puppet_repository) { raise "Required variable: puppet_repository" }
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
                set(:puppet_branch, 'master')
         
     | 
| 
      
 9 
     | 
    
         
            +
                set(:puppet_path, '/var/www/provision/puppet')
         
     | 
| 
      
 10 
     | 
    
         
            +
                set(:puppet_git_password) { Capistrano::CLI.password_prompt }
         
     | 
| 
      
 11 
     | 
    
         
            +
                set(:puppet_manifest_path) { "#{puppet_path}/puppet/host.pp" }
         
     | 
| 
      
 12 
     | 
    
         
            +
                set(:puppet_modules_path) { "#{puppet_path}/puppet/modules" }
         
     | 
| 
      
 13 
     | 
    
         
            +
                set(:puppet_yaml_path) { "#{puppet_path}/puppet/host.yaml" }
         
     | 
| 
      
 14 
     | 
    
         
            +
                set(:puppet_enc_path) { "#{puppet_path}/puppet/enc" }
         
     | 
| 
      
 15 
     | 
    
         
            +
                set(:puppet_enc) { "#!/bin/sh\ncat '#{puppet_yaml_path}'" }
         
     | 
| 
      
 16 
     | 
    
         
            +
                set(:puppet_parameters, '--no-report')
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                desc <<-DESC
         
     | 
| 
      
 20 
     | 
    
         
            +
                  Calls 'check' and 'update' and 'properties', which means it performs a
         
     | 
| 
      
 21 
     | 
    
         
            +
                  check for the necessary puppet dependencies, deploys the puppet scripts
         
     | 
| 
      
 22 
     | 
    
         
            +
                  via git, then pushes up a special yaml file describing the properties of
         
     | 
| 
      
 23 
     | 
    
         
            +
                  this particular server.
         
     | 
| 
      
 24 
     | 
    
         
            +
                DESC
         
     | 
| 
      
 25 
     | 
    
         
            +
                task(:freshen) do
         
     | 
| 
      
 26 
     | 
    
         
            +
                  check
         
     | 
| 
      
 27 
     | 
    
         
            +
                  update
         
     | 
| 
      
 28 
     | 
    
         
            +
                  properties
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                desc <<-DESC
         
     | 
| 
      
 33 
     | 
    
         
            +
                  Looks for Ruby 1.9 on the server. Installs it (and git-core) if not found.
         
     | 
| 
      
 34 
     | 
    
         
            +
                  Also looks for Puppet 3.0 gem on the server, and installs it if not found.
         
     | 
| 
      
 35 
     | 
    
         
            +
                DESC
         
     | 
| 
      
 36 
     | 
    
         
            +
                task(:check) do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  unless exists?(:hubcap_agnostic)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    raise "Hubcap has not configured this Capistrano instance."
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  unless hubcap_agnostic
         
     | 
| 
      
 41 
     | 
    
         
            +
                    raise "Puppet tasks are not available in Hubcap application mode"
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  apt_cmd = [
         
     | 
| 
      
 45 
     | 
    
         
            +
                    "env",
         
     | 
| 
      
 46 
     | 
    
         
            +
                    "DEBCONF_TERSE='yes'",
         
     | 
| 
      
 47 
     | 
    
         
            +
                    "DEBIAN_PRIORITY='critical'",
         
     | 
| 
      
 48 
     | 
    
         
            +
                    "DEBIAN_FRONTEND=noninteractive",
         
     | 
| 
      
 49 
     | 
    
         
            +
                    "apt-get --force-yes -qyu"
         
     | 
| 
      
 50 
     | 
    
         
            +
                  ].join(" ")
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  # Because Ubuntu is weird, the 1.9.1 package installs Ruby 1.9.3-p0.
         
     | 
| 
      
 53 
     | 
    
         
            +
                  sudo_bash([
         
     | 
| 
      
 54 
     | 
    
         
            +
                    'if [[ `which ruby` && (`ruby -v` =~ "ruby 1.9") ]]; then',
         
     | 
| 
      
 55 
     | 
    
         
            +
                      'echo "Ruby 1.9 verified";',
         
     | 
| 
      
 56 
     | 
    
         
            +
                    'else',
         
     | 
| 
      
 57 
     | 
    
         
            +
                      "#{apt_cmd} update;",
         
     | 
| 
      
 58 
     | 
    
         
            +
                      "#{apt_cmd} install ruby1.9.1 git-core;",
         
     | 
| 
      
 59 
     | 
    
         
            +
                    'fi'
         
     | 
| 
      
 60 
     | 
    
         
            +
                  ].join(' '))
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  # 3.0.0-rc5 is the last version that a) runs on Ruby 1.9 and b) works.
         
     | 
| 
      
 63 
     | 
    
         
            +
                  ppt_ver = '3.0.0.rc5'
         
     | 
| 
      
 64 
     | 
    
         
            +
                  sudo_bash([
         
     | 
| 
      
 65 
     | 
    
         
            +
                    "if [[ `gem q -i -n \"^puppet$\" -v #{ppt_ver}` =~ \"true\" ]]; then",
         
     | 
| 
      
 66 
     | 
    
         
            +
                      'echo "Puppet verified";',
         
     | 
| 
      
 67 
     | 
    
         
            +
                    'else',
         
     | 
| 
      
 68 
     | 
    
         
            +
                      "gem install puppet -v #{ppt_ver} --pre --no-rdoc --no-ri;",
         
     | 
| 
      
 69 
     | 
    
         
            +
                    'fi'
         
     | 
| 
      
 70 
     | 
    
         
            +
                  ].join(' '))
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  # Workaround for: http://projects.puppetlabs.com/issues/9862
         
     | 
| 
      
 73 
     | 
    
         
            +
                  sudo_bash([
         
     | 
| 
      
 74 
     | 
    
         
            +
                    'if [[ `egrep -i "^puppet" /etc/group` =~ "puppet" ]]; then',
         
     | 
| 
      
 75 
     | 
    
         
            +
                      'echo "Puppet group exists";',
         
     | 
| 
      
 76 
     | 
    
         
            +
                    'else',
         
     | 
| 
      
 77 
     | 
    
         
            +
                      'groupadd puppet;',
         
     | 
| 
      
 78 
     | 
    
         
            +
                    'fi'
         
     | 
| 
      
 79 
     | 
    
         
            +
                  ].join(' '))
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                desc <<-DESC
         
     | 
| 
      
 84 
     | 
    
         
            +
                  Basically, this pulls down your puppet scripts so you can run them.
         
     | 
| 
      
 85 
     | 
    
         
            +
                  It does this by cloning the Hubcap repository to each server (if necessary),
         
     | 
| 
      
 86 
     | 
    
         
            +
                  then fetching the latest code and resetting to the HEAD of the
         
     | 
| 
      
 87 
     | 
    
         
            +
                  specified branch.
         
     | 
| 
      
 88 
     | 
    
         
            +
                DESC
         
     | 
| 
      
 89 
     | 
    
         
            +
                task(:update) do
         
     | 
| 
      
 90 
     | 
    
         
            +
                  handle_data = lambda { |channel, stream, text|
         
     | 
| 
      
 91 
     | 
    
         
            +
                    host = channel[:host]
         
     | 
| 
      
 92 
     | 
    
         
            +
                    logger.info "[#{host} :: #{stream}] #{text}"
         
     | 
| 
      
 93 
     | 
    
         
            +
                    out = case text
         
     | 
| 
      
 94 
     | 
    
         
            +
                    when /\bpassword.*:/i, /passphrase/i  # Git password or SSH passphrase.
         
     | 
| 
      
 95 
     | 
    
         
            +
                      "#{puppet_git_password}\n"
         
     | 
| 
      
 96 
     | 
    
         
            +
                    when %r{\(yes/no\)}                   # Should git connect?
         
     | 
| 
      
 97 
     | 
    
         
            +
                      "yes\n"
         
     | 
| 
      
 98 
     | 
    
         
            +
                    when /accept \(t\)emporarily/         # Should git accept certificate?
         
     | 
| 
      
 99 
     | 
    
         
            +
                      "t\n"
         
     | 
| 
      
 100 
     | 
    
         
            +
                    end
         
     | 
| 
      
 101 
     | 
    
         
            +
                    channel.send_data(out)  if out
         
     | 
| 
      
 102 
     | 
    
         
            +
                  }
         
     | 
| 
      
 103 
     | 
    
         
            +
                  sudo("mkdir -p #{File.dirname(puppet_path)}")
         
     | 
| 
      
 104 
     | 
    
         
            +
                  sudo("chown #{user} #{File.dirname(puppet_path)}")
         
     | 
| 
      
 105 
     | 
    
         
            +
                  run(
         
     | 
| 
      
 106 
     | 
    
         
            +
                    "[ -d #{puppet_path} ] || git clone #{puppet_repository} #{puppet_path}",
         
     | 
| 
      
 107 
     | 
    
         
            +
                    :shell => nil,
         
     | 
| 
      
 108 
     | 
    
         
            +
                    &handle_data
         
     | 
| 
      
 109 
     | 
    
         
            +
                  )
         
     | 
| 
      
 110 
     | 
    
         
            +
                  run(
         
     | 
| 
      
 111 
     | 
    
         
            +
                    [
         
     | 
| 
      
 112 
     | 
    
         
            +
                      "cd #{puppet_path}",
         
     | 
| 
      
 113 
     | 
    
         
            +
                      "git fetch origin",
         
     | 
| 
      
 114 
     | 
    
         
            +
                      "git reset --hard origin/#{puppet_branch}"
         
     | 
| 
      
 115 
     | 
    
         
            +
                    ].join(' && '),
         
     | 
| 
      
 116 
     | 
    
         
            +
                    :shell => nil,
         
     | 
| 
      
 117 
     | 
    
         
            +
                    &handle_data
         
     | 
| 
      
 118 
     | 
    
         
            +
                  )
         
     | 
| 
      
 119 
     | 
    
         
            +
                end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                desc <<-DESC
         
     | 
| 
      
 123 
     | 
    
         
            +
                  Pushes a YAML file containing all the classes and parameters that Puppet
         
     | 
| 
      
 124 
     | 
    
         
            +
                  needs to know about in order to provision this server. Each file is
         
     | 
| 
      
 125 
     | 
    
         
            +
                  server-specific.
         
     | 
| 
      
 126 
     | 
    
         
            +
                DESC
         
     | 
| 
      
 127 
     | 
    
         
            +
                task(:properties) do
         
     | 
| 
      
 128 
     | 
    
         
            +
                  hubcap.servers.each { |s|
         
     | 
| 
      
 129 
     | 
    
         
            +
                    put(s.yaml, puppet_yaml_path, :hosts => s.address)
         
     | 
| 
      
 130 
     | 
    
         
            +
                  }
         
     | 
| 
      
 131 
     | 
    
         
            +
                  put(puppet_enc, puppet_enc_path)
         
     | 
| 
      
 132 
     | 
    
         
            +
                  run("chmod +x #{puppet_enc_path}")
         
     | 
| 
      
 133 
     | 
    
         
            +
                end
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                desc <<-DESC
         
     | 
| 
      
 137 
     | 
    
         
            +
                  Tells you what would happen if you ran puppet:apply. This is a safe way
         
     | 
| 
      
 138 
     | 
    
         
            +
                  to test your changes.
         
     | 
| 
      
 139 
     | 
    
         
            +
                DESC
         
     | 
| 
      
 140 
     | 
    
         
            +
                task(:noop) do
         
     | 
| 
      
 141 
     | 
    
         
            +
                  run_puppet('--noop')
         
     | 
| 
      
 142 
     | 
    
         
            +
                end
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                desc <<-DESC
         
     | 
| 
      
 146 
     | 
    
         
            +
                  Runs the puppet scripts on each server. Be careful!
         
     | 
| 
      
 147 
     | 
    
         
            +
                DESC
         
     | 
| 
      
 148 
     | 
    
         
            +
                task(:apply) do
         
     | 
| 
      
 149 
     | 
    
         
            +
                  run_puppet
         
     | 
| 
      
 150 
     | 
    
         
            +
                end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
                def sudo_bash(cmd, options = {}, &blk)
         
     | 
| 
      
 154 
     | 
    
         
            +
                  sudo("/bin/bash -c \'#{cmd}\'", options, &blk)
         
     | 
| 
      
 155 
     | 
    
         
            +
                end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                def run_puppet(params = nil)
         
     | 
| 
      
 159 
     | 
    
         
            +
                  sudo([
         
     | 
| 
      
 160 
     | 
    
         
            +
                    "puppet apply",
         
     | 
| 
      
 161 
     | 
    
         
            +
                    "--node_terminus exec",
         
     | 
| 
      
 162 
     | 
    
         
            +
                    "--external_nodes '#{puppet_enc_path}'",
         
     | 
| 
      
 163 
     | 
    
         
            +
                    "--modulepath '#{puppet_modules_path}'",
         
     | 
| 
      
 164 
     | 
    
         
            +
                    puppet_parameters,
         
     | 
| 
      
 165 
     | 
    
         
            +
                    params,
         
     | 
| 
      
 166 
     | 
    
         
            +
                    "'#{puppet_manifest_path}'"
         
     | 
| 
      
 167 
     | 
    
         
            +
                  ].compact.join(' '))
         
     | 
| 
      
 168 
     | 
    
         
            +
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
                before('puppet:noop', 'puppet:freshen')
         
     | 
| 
      
 172 
     | 
    
         
            +
                before('puppet:apply', 'puppet:freshen')
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
              end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Capistrano::Configuration.instance(:must_exist).load do
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              namespace(:servers) do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                desc <<-DESC
         
     | 
| 
      
 6 
     | 
    
         
            +
                  Lists all the servers that match the filter used when Hubcap was loaded.
         
     | 
| 
      
 7 
     | 
    
         
            +
                DESC
         
     | 
| 
      
 8 
     | 
    
         
            +
                task(:list) do
         
     | 
| 
      
 9 
     | 
    
         
            +
                  puts(hubcap.servers.collect(&:tree))
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                desc <<-DESC
         
     | 
| 
      
 13 
     | 
    
         
            +
                  Show the entire Hubcap configuration tree for the given filter.
         
     | 
| 
      
 14 
     | 
    
         
            +
                DESC
         
     | 
| 
      
 15 
     | 
    
         
            +
                task(:tree) do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  puts(hubcap.tree)
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Hubcap::Server < Hubcap::Group
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              attr_reader(:address)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def initialize(parent, name, options = {}, &blk)
         
     | 
| 
      
 7 
     | 
    
         
            +
                @address = options[:address] || name
         
     | 
| 
      
 8 
     | 
    
         
            +
                super(parent, name, &blk)
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def application(*args)
         
     | 
| 
      
 13 
     | 
    
         
            +
                raise(Hubcap::ServerSubgroupDisallowed, 'application')
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              def server(*args)
         
     | 
| 
      
 18 
     | 
    
         
            +
                raise(Hubcap::ServerSubgroupDisallowed, 'server')
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def group(*args)
         
     | 
| 
      
 23 
     | 
    
         
            +
                raise(Hubcap::ServerSubgroupDisallowed, 'group')
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              def application_parent
         
     | 
| 
      
 28 
     | 
    
         
            +
                p = self
         
     | 
| 
      
 29 
     | 
    
         
            +
                while p && p != hub
         
     | 
| 
      
 30 
     | 
    
         
            +
                  return p  if p.kind_of?(Hubcap::Application)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  p = p.instance_variable_get(:@parent)
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def yaml
         
     | 
| 
      
 37 
     | 
    
         
            +
                {
         
     | 
| 
      
 38 
     | 
    
         
            +
                  'classes' => @puppet_roles.collect(&:to_s),
         
     | 
| 
      
 39 
     | 
    
         
            +
                  'parameters' => @params
         
     | 
| 
      
 40 
     | 
    
         
            +
                }.to_yaml
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              class Hubcap::ServerSubgroupDisallowed < StandardError; end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/hubcap.rb
    ADDED
    
    | 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'yaml'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Hubcap
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              def self.hub(filter_string = '', &blk)
         
     | 
| 
      
 6 
     | 
    
         
            +
                Hubcap::Hub.new(filter_string).tap { |scope| scope.instance_eval(&blk) }
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def self.load(filter_string, *paths)
         
     | 
| 
      
 11 
     | 
    
         
            +
                Hubcap::Hub.new(filter_string).tap { |scope|
         
     | 
| 
      
 12 
     | 
    
         
            +
                  while paths.any?
         
     | 
| 
      
 13 
     | 
    
         
            +
                    path = paths.shift
         
     | 
| 
      
 14 
     | 
    
         
            +
                    if File.directory?(path)
         
     | 
| 
      
 15 
     | 
    
         
            +
                      paths += Dir.glob(File.join(path, '*.rb'))
         
     | 
| 
      
 16 
     | 
    
         
            +
                    else
         
     | 
| 
      
 17 
     | 
    
         
            +
                      scope.absorb(path)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                }
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            require 'hubcap/group'
         
     | 
| 
      
 27 
     | 
    
         
            +
            require 'hubcap/application'
         
     | 
| 
      
 28 
     | 
    
         
            +
            require 'hubcap/server'
         
     | 
| 
      
 29 
     | 
    
         
            +
            require 'hubcap/hub'
         
     | 
| 
         @@ -0,0 +1,68 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            application('example', :recipes => 'deploy') {
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              # These cap settings will apply to all the servers within this application
         
     | 
| 
      
 4 
     | 
    
         
            +
              # group or any subgroups. (The same applies for roles, attributes, etc.)
         
     | 
| 
      
 5 
     | 
    
         
            +
              cap_set(:repository, 'git@github.com:example/example.git')
         
     | 
| 
      
 6 
     | 
    
         
            +
              cap_set(:branch, 'master')
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              # Load some ssh keys into param() from a separate (more secure?) file.
         
     | 
| 
      
 9 
     | 
    
         
            +
              # These will be handed to your puppet scripts.
         
     | 
| 
      
 10 
     | 
    
         
            +
              #absorb('nodes/private/admin_ssh_keys')
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              # Just a normal Ruby hash var we can reuse throughout the config.
         
     | 
| 
      
 13 
     | 
    
         
            +
              common_env = {
         
     | 
| 
      
 14 
     | 
    
         
            +
                'PGUSER' => 'example',
         
     | 
| 
      
 15 
     | 
    
         
            +
                'RABBIT_URI' => 'amqp://example:password@localhost:54322'
         
     | 
| 
      
 16 
     | 
    
         
            +
              }
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              # A local dev simulation.
         
     | 
| 
      
 19 
     | 
    
         
            +
              group('vagrant') {
         
     | 
| 
      
 20 
     | 
    
         
            +
                param('env' => common_env.merge('PGPASSWORD' => 'password'))
         
     | 
| 
      
 21 
     | 
    
         
            +
                server('127.0.0.1:2222') {
         
     | 
| 
      
 22 
     | 
    
         
            +
                  role(:app, :db, :queue)
         
     | 
| 
      
 23 
     | 
    
         
            +
                }
         
     | 
| 
      
 24 
     | 
    
         
            +
              }
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              # Your staging environment.
         
     | 
| 
      
 27 
     | 
    
         
            +
              group('staging') {
         
     | 
| 
      
 28 
     | 
    
         
            +
                param('env' => common_env.merge(
         
     | 
| 
      
 29 
     | 
    
         
            +
                  'PGPASSWORD' => 'pa55w3rd',
         
     | 
| 
      
 30 
     | 
    
         
            +
                  'PGHOST' => '10.10.10.20',
         
     | 
| 
      
 31 
     | 
    
         
            +
                  'RABBIT_URI' => 'amqp://example:pa55w3rd@10.10.10.20'
         
     | 
| 
      
 32 
     | 
    
         
            +
                ))
         
     | 
| 
      
 33 
     | 
    
         
            +
                server('app', :address => '10.10.10.10') {
         
     | 
| 
      
 34 
     | 
    
         
            +
                  role(:app)
         
     | 
| 
      
 35 
     | 
    
         
            +
                }
         
     | 
| 
      
 36 
     | 
    
         
            +
                server('db', :address => '10.10.10.15') {
         
     | 
| 
      
 37 
     | 
    
         
            +
                  role(:db)
         
     | 
| 
      
 38 
     | 
    
         
            +
                }
         
     | 
| 
      
 39 
     | 
    
         
            +
                server('queue', :address => '10.10.10.20') {
         
     | 
| 
      
 40 
     | 
    
         
            +
                  role(:queue)
         
     | 
| 
      
 41 
     | 
    
         
            +
                }
         
     | 
| 
      
 42 
     | 
    
         
            +
              }
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              # Your production environment.
         
     | 
| 
      
 45 
     | 
    
         
            +
              group('production') {
         
     | 
| 
      
 46 
     | 
    
         
            +
                prod_env = common_env.merge(
         
     | 
| 
      
 47 
     | 
    
         
            +
                  'PGPASSWORD' => '1391f3a24daef0c78f75cbef9d62eb848c2d454c71a5fd2a',
         
     | 
| 
      
 48 
     | 
    
         
            +
                  'PGHOST' => '20.20.20.20',
         
     | 
| 
      
 49 
     | 
    
         
            +
                  'RABBIT_URI' => 'amqp://example:e18edfa58fa6c5d3a9a@20.20.20.30'
         
     | 
| 
      
 50 
     | 
    
         
            +
                )
         
     | 
| 
      
 51 
     | 
    
         
            +
                param('env' => prod_env)
         
     | 
| 
      
 52 
     | 
    
         
            +
                group('app') {
         
     | 
| 
      
 53 
     | 
    
         
            +
                  role(:app)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  param('env' => prod_env.merge('FORCE_SSL' => '1'))
         
     | 
| 
      
 55 
     | 
    
         
            +
                  server('app-1.example.com')
         
     | 
| 
      
 56 
     | 
    
         
            +
                  server('app-2.example.com')
         
     | 
| 
      
 57 
     | 
    
         
            +
                  server('app-3.example.com')
         
     | 
| 
      
 58 
     | 
    
         
            +
                }
         
     | 
| 
      
 59 
     | 
    
         
            +
                group('db') {
         
     | 
| 
      
 60 
     | 
    
         
            +
                  role(:db)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  server('db-1.example.com')
         
     | 
| 
      
 62 
     | 
    
         
            +
                  server('db-2.example.com')
         
     | 
| 
      
 63 
     | 
    
         
            +
                }
         
     | 
| 
      
 64 
     | 
    
         
            +
                server('queue-1.example.com') {
         
     | 
| 
      
 65 
     | 
    
         
            +
                  role(:queue)
         
     | 
| 
      
 66 
     | 
    
         
            +
                }
         
     | 
| 
      
 67 
     | 
    
         
            +
              }
         
     | 
| 
      
 68 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            param(:foo => 'foo')
         
     | 
    
        data/test/data/readme.rb
    ADDED
    
    | 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # An application called 'readme' that uses Cap's default deployment recipe.
         
     | 
| 
      
 2 
     | 
    
         
            +
            application('readme', :recipes => 'deploy') {
         
     | 
| 
      
 3 
     | 
    
         
            +
              # Set a capistrano variable.
         
     | 
| 
      
 4 
     | 
    
         
            +
              cap_set('repository', 'git@github.com:joseph/readme.git')
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              # Declare that all servers will have the 'baseline' puppet class.
         
     | 
| 
      
 7 
     | 
    
         
            +
              role(:puppet => 'baseline')
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              group('staging') {
         
     | 
| 
      
 10 
     | 
    
         
            +
                # Puppet will have a $::exception_subject_prefix variable on these servers.
         
     | 
| 
      
 11 
     | 
    
         
            +
                param('exception_subject_prefix' => '[STAGING] ')
         
     | 
| 
      
 12 
     | 
    
         
            +
                # For simple staging, just one server that does everything.
         
     | 
| 
      
 13 
     | 
    
         
            +
                server('readme.stage') {
         
     | 
| 
      
 14 
     | 
    
         
            +
                  role(:cap => [:web, :app, :db], :puppet => ['proxy', 'app', 'db'])
         
     | 
| 
      
 15 
     | 
    
         
            +
                }
         
     | 
| 
      
 16 
     | 
    
         
            +
              }
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              group('production') {
         
     | 
| 
      
 19 
     | 
    
         
            +
                # Puppet will have these top-scope variables on all these servers.
         
     | 
| 
      
 20 
     | 
    
         
            +
                param(
         
     | 
| 
      
 21 
     | 
    
         
            +
                  'exception_subject_prefix' => '[PRODUCTION] ',
         
     | 
| 
      
 22 
     | 
    
         
            +
                  'env' => {
         
     | 
| 
      
 23 
     | 
    
         
            +
                    "FORCE_SSL" => true,
         
     | 
| 
      
 24 
     | 
    
         
            +
                    "S3_KEY" => "AKIAKJRK23943202JK",
         
     | 
| 
      
 25 
     | 
    
         
            +
                    "S3_SECRET" => "KDJkaddsalkjfkawjri32jkjaklvjgakljkj"
         
     | 
| 
      
 26 
     | 
    
         
            +
                  }
         
     | 
| 
      
 27 
     | 
    
         
            +
                )
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                group('proxy') {
         
     | 
| 
      
 30 
     | 
    
         
            +
                  # Servers will have the :web role and the 'proxy' puppet class.
         
     | 
| 
      
 31 
     | 
    
         
            +
                  role(:cap => :web, :puppet => 'proxy')
         
     | 
| 
      
 32 
     | 
    
         
            +
                  server('proxy-1', :address => '10.10.10.5')
         
     | 
| 
      
 33 
     | 
    
         
            +
                }
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                group('app') {
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # Servers will have the :app role and the 'app' puppet class.
         
     | 
| 
      
 37 
     | 
    
         
            +
                  role(:app)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  server('app-1', :address => '10.10.10.10')
         
     | 
| 
      
 39 
     | 
    
         
            +
                  server('app-2', :address => '10.10.10.11')
         
     | 
| 
      
 40 
     | 
    
         
            +
                }
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                group('db') {
         
     | 
| 
      
 43 
     | 
    
         
            +
                  role(:db)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  server('db-1', :address => '10.10.10.50')
         
     | 
| 
      
 45 
     | 
    
         
            +
                }
         
     | 
| 
      
 46 
     | 
    
         
            +
              }
         
     | 
| 
      
 47 
     | 
    
         
            +
            }
         
     | 
    
        data/test/data/simple.rb
    ADDED
    
    
    
        data/test/test_helper.rb
    ADDED
    
    
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class Hubcap::TestApplication < Test::Unit::TestCase
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              def test_recipe_paths
         
     | 
| 
      
 6 
     | 
    
         
            +
                hub = Hubcap.hub { application('test', :recipes => 'foo') }
         
     | 
| 
      
 7 
     | 
    
         
            +
                assert_equal(['foo'], hub.applications.first.recipe_paths)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                hub = Hubcap.hub { application('test', :recipes => ['foo', 'bar']) }
         
     | 
| 
      
 10 
     | 
    
         
            +
                assert_equal(['foo', 'bar'], hub.applications.first.recipe_paths)
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def test_nested_application_disallowed
         
     | 
| 
      
 15 
     | 
    
         
            +
                assert_raises(Hubcap::NestedApplicationDisallowed) {
         
     | 
| 
      
 16 
     | 
    
         
            +
                  Hubcap.hub { application('test') { application('child') } }
         
     | 
| 
      
 17 
     | 
    
         
            +
                }
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,176 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class Hubcap::TestGroup < Test::Unit::TestCase
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              def test_name
         
     | 
| 
      
 6 
     | 
    
         
            +
                hub = Hubcap.hub { group('test') }
         
     | 
| 
      
 7 
     | 
    
         
            +
                assert_equal('test', hub.groups.first.name)
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def test_hub
         
     | 
| 
      
 12 
     | 
    
         
            +
                hub = Hubcap.hub { group('test') }
         
     | 
| 
      
 13 
     | 
    
         
            +
                assert_equal(hub, hub.groups.first.hub)
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              def test_must_have_parent_unless_hub
         
     | 
| 
      
 18 
     | 
    
         
            +
                assert_raises(Hubcap::GroupWithoutParent) { Hubcap::Group.new(nil, 'foo') }
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def test_history
         
     | 
| 
      
 23 
     | 
    
         
            +
                hub = Hubcap.hub { group('test') { group('child') } }
         
     | 
| 
      
 24 
     | 
    
         
            +
                assert_equal(['test'], hub.children.first.history)
         
     | 
| 
      
 25 
     | 
    
         
            +
                assert_equal(['test', 'child'], hub.children.first.children.first.history)
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              def test_absorb
         
     | 
| 
      
 30 
     | 
    
         
            +
                hub = Hubcap.hub {
         
     | 
| 
      
 31 
     | 
    
         
            +
                  group('test') { absorb('test/data/parts/foo_param') }
         
     | 
| 
      
 32 
     | 
    
         
            +
                }
         
     | 
| 
      
 33 
     | 
    
         
            +
                assert_equal('foo', hub.groups.first.params[:foo])
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              def test_processable_and_collectable
         
     | 
| 
      
 38 
     | 
    
         
            +
                x = {}
         
     | 
| 
      
 39 
     | 
    
         
            +
                hub = Hubcap.hub('g1.a1') {
         
     | 
| 
      
 40 
     | 
    
         
            +
                  x[:g1] = group('g1') {
         
     | 
| 
      
 41 
     | 
    
         
            +
                    x[:a1] = application('a1') {
         
     | 
| 
      
 42 
     | 
    
         
            +
                      x[:s1] = server('s1')
         
     | 
| 
      
 43 
     | 
    
         
            +
                    }
         
     | 
| 
      
 44 
     | 
    
         
            +
                    x[:a2] = application('a2') {
         
     | 
| 
      
 45 
     | 
    
         
            +
                      x[:s2] = server('s2')
         
     | 
| 
      
 46 
     | 
    
         
            +
                    }
         
     | 
| 
      
 47 
     | 
    
         
            +
                  }
         
     | 
| 
      
 48 
     | 
    
         
            +
                  x[:g2] = group('g2') {
         
     | 
| 
      
 49 
     | 
    
         
            +
                    x[:a3] = application('a3') {
         
     | 
| 
      
 50 
     | 
    
         
            +
                      x[:s3] = server('s3')
         
     | 
| 
      
 51 
     | 
    
         
            +
                    }
         
     | 
| 
      
 52 
     | 
    
         
            +
                  }
         
     | 
| 
      
 53 
     | 
    
         
            +
                }
         
     | 
| 
      
 54 
     | 
    
         
            +
                assert_equal(true, x[:g1].processable?)
         
     | 
| 
      
 55 
     | 
    
         
            +
                assert_equal(false, x[:g1].collectable?)
         
     | 
| 
      
 56 
     | 
    
         
            +
                assert_equal(true, x[:a1].processable?)
         
     | 
| 
      
 57 
     | 
    
         
            +
                assert_equal(true, x[:a1].collectable?)
         
     | 
| 
      
 58 
     | 
    
         
            +
                assert_equal(true, x[:s1].processable?)
         
     | 
| 
      
 59 
     | 
    
         
            +
                assert_equal(true, x[:s1].collectable?)
         
     | 
| 
      
 60 
     | 
    
         
            +
                assert_equal(false, x[:g2].processable?)
         
     | 
| 
      
 61 
     | 
    
         
            +
                assert_equal(false, x[:g2].collectable?)
         
     | 
| 
      
 62 
     | 
    
         
            +
                assert_nil(x[:a3])
         
     | 
| 
      
 63 
     | 
    
         
            +
                assert_nil(x[:s3])
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              def test_cap_set
         
     | 
| 
      
 68 
     | 
    
         
            +
                # Single value, as key, val arguments
         
     | 
| 
      
 69 
     | 
    
         
            +
                hub = Hubcap.hub { group('test') { cap_set(:foo, 'bar') } }
         
     | 
| 
      
 70 
     | 
    
         
            +
                assert_equal('bar', hub.cap_sets[:foo])
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                # Single value, as one hash argument
         
     | 
| 
      
 73 
     | 
    
         
            +
                hub = Hubcap.hub { group('test') { cap_set('baz' => 'yyy') } }
         
     | 
| 
      
 74 
     | 
    
         
            +
                assert_equal('yyy', hub.cap_sets['baz'])
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                # Multiple values
         
     | 
| 
      
 77 
     | 
    
         
            +
                hub = Hubcap.hub { group('test') { cap_set(:a => 1, :z => 0) } }
         
     | 
| 
      
 78 
     | 
    
         
            +
                assert_equal(1, hub.cap_sets[:a])
         
     | 
| 
      
 79 
     | 
    
         
            +
                assert_equal(0, hub.cap_sets[:z])
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                # Lazily-evaluated block
         
     | 
| 
      
 82 
     | 
    
         
            +
                hub = Hubcap.hub { group('test') { cap_set(:blk) { 'garply' } } }
         
     | 
| 
      
 83 
     | 
    
         
            +
                assert_equal('garply', hub.cap_sets[:blk].call)
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
              def test_cap_attribute
         
     | 
| 
      
 88 
     | 
    
         
            +
                # Single value as key, val arguments
         
     | 
| 
      
 89 
     | 
    
         
            +
                hub = Hubcap.hub { server('test') { cap_attribute(:foo, 'bar') } }
         
     | 
| 
      
 90 
     | 
    
         
            +
                assert_equal({ :foo => 'bar' }, hub.servers.first.cap_attributes)
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                # Single value as hash
         
     | 
| 
      
 93 
     | 
    
         
            +
                hub = Hubcap.hub { server('test') { cap_attribute(:foo => 'bar') } }
         
     | 
| 
      
 94 
     | 
    
         
            +
                assert_equal({ :foo => 'bar' }, hub.servers.first.cap_attributes)
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                # Multiple values
         
     | 
| 
      
 97 
     | 
    
         
            +
                hub = Hubcap.hub { server('test') { cap_attribute(:a => 1, :z => 0) } }
         
     | 
| 
      
 98 
     | 
    
         
            +
                assert_equal({ :a => 1, :z => 0 }, hub.servers.first.cap_attributes)
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                # Cap attributes are additive down the tree
         
     | 
| 
      
 101 
     | 
    
         
            +
                hub = Hubcap.hub {
         
     | 
| 
      
 102 
     | 
    
         
            +
                  group('g') {
         
     | 
| 
      
 103 
     | 
    
         
            +
                    cap_attribute(:excellent => true)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    server('s') { cap_attribute(:modest => false) }
         
     | 
| 
      
 105 
     | 
    
         
            +
                  }
         
     | 
| 
      
 106 
     | 
    
         
            +
                }
         
     | 
| 
      
 107 
     | 
    
         
            +
                assert_equal({ :excellent => true }, hub.groups.first.cap_attributes)
         
     | 
| 
      
 108 
     | 
    
         
            +
                assert_equal(
         
     | 
| 
      
 109 
     | 
    
         
            +
                  { :excellent => true, :modest => false },
         
     | 
| 
      
 110 
     | 
    
         
            +
                  hub.servers.first.cap_attributes
         
     | 
| 
      
 111 
     | 
    
         
            +
                )
         
     | 
| 
      
 112 
     | 
    
         
            +
              end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
              def test_role
         
     | 
| 
      
 116 
     | 
    
         
            +
                # Single role
         
     | 
| 
      
 117 
     | 
    
         
            +
                hub = Hubcap.hub {
         
     | 
| 
      
 118 
     | 
    
         
            +
                  role(:baseline)
         
     | 
| 
      
 119 
     | 
    
         
            +
                  server('test')
         
     | 
| 
      
 120 
     | 
    
         
            +
                }
         
     | 
| 
      
 121 
     | 
    
         
            +
                assert_equal([:baseline], hub.servers.first.cap_roles)
         
     | 
| 
      
 122 
     | 
    
         
            +
                assert_equal([:baseline], hub.servers.first.puppet_roles)
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                # Multiple roles in a single declaration
         
     | 
| 
      
 125 
     | 
    
         
            +
                hub = Hubcap.hub {
         
     | 
| 
      
 126 
     | 
    
         
            +
                  role(:baseline, :app)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  server('test')
         
     | 
| 
      
 128 
     | 
    
         
            +
                }
         
     | 
| 
      
 129 
     | 
    
         
            +
                assert_equal([:baseline, :app], hub.servers.first.cap_roles)
         
     | 
| 
      
 130 
     | 
    
         
            +
                assert_equal([:baseline, :app], hub.servers.first.puppet_roles)
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                # Multiple declarations are additive
         
     | 
| 
      
 133 
     | 
    
         
            +
                hub = Hubcap.hub {
         
     | 
| 
      
 134 
     | 
    
         
            +
                  role(:baseline)
         
     | 
| 
      
 135 
     | 
    
         
            +
                  server('test') { role(:db) }
         
     | 
| 
      
 136 
     | 
    
         
            +
                }
         
     | 
| 
      
 137 
     | 
    
         
            +
                assert_equal([:baseline, :db], hub.servers.first.cap_roles)
         
     | 
| 
      
 138 
     | 
    
         
            +
                assert_equal([:baseline, :db], hub.servers.first.puppet_roles)
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                # Separate cap and puppet roles
         
     | 
| 
      
 141 
     | 
    
         
            +
                hub = Hubcap.hub {
         
     | 
| 
      
 142 
     | 
    
         
            +
                  role(:cap => :app, :puppet => 'testapp')
         
     | 
| 
      
 143 
     | 
    
         
            +
                  server('test')
         
     | 
| 
      
 144 
     | 
    
         
            +
                }
         
     | 
| 
      
 145 
     | 
    
         
            +
                assert_equal([:app], hub.servers.first.cap_roles)
         
     | 
| 
      
 146 
     | 
    
         
            +
                assert_equal(['testapp'], hub.servers.first.puppet_roles)
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                # Separate cap/puppet roles can be defined with an array
         
     | 
| 
      
 149 
     | 
    
         
            +
                # Also shows that multiple role declarations are additive
         
     | 
| 
      
 150 
     | 
    
         
            +
                hub = Hubcap.hub {
         
     | 
| 
      
 151 
     | 
    
         
            +
                  role(:cap => [:app, :db])
         
     | 
| 
      
 152 
     | 
    
         
            +
                  server('test') { role(:baseline) }
         
     | 
| 
      
 153 
     | 
    
         
            +
                }
         
     | 
| 
      
 154 
     | 
    
         
            +
                assert_equal([:app, :db], hub.cap_roles)
         
     | 
| 
      
 155 
     | 
    
         
            +
                assert_equal([], hub.puppet_roles)
         
     | 
| 
      
 156 
     | 
    
         
            +
                assert_equal([:app, :db, :baseline], hub.servers.first.cap_roles)
         
     | 
| 
      
 157 
     | 
    
         
            +
                assert_equal([:baseline], hub.servers.first.puppet_roles)
         
     | 
| 
      
 158 
     | 
    
         
            +
              end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
              def test_param
         
     | 
| 
      
 162 
     | 
    
         
            +
                # Single key/val.
         
     | 
| 
      
 163 
     | 
    
         
            +
                hub = Hubcap.hub {
         
     | 
| 
      
 164 
     | 
    
         
            +
                  server('test') { param('foo' => 1) }
         
     | 
| 
      
 165 
     | 
    
         
            +
                }
         
     | 
| 
      
 166 
     | 
    
         
            +
                assert_equal(1, hub.servers.first.params['foo'])
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
                # Multiple key/vals.
         
     | 
| 
      
 169 
     | 
    
         
            +
                hub = Hubcap.hub {
         
     | 
| 
      
 170 
     | 
    
         
            +
                  server('test') { param('foo' => 1, 'baz' => 2) }
         
     | 
| 
      
 171 
     | 
    
         
            +
                }
         
     | 
| 
      
 172 
     | 
    
         
            +
                assert_equal(1, hub.servers.first.params['foo'])
         
     | 
| 
      
 173 
     | 
    
         
            +
                assert_equal(2, hub.servers.first.params['baz'])
         
     | 
| 
      
 174 
     | 
    
         
            +
              end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
            end
         
     |