Module: Simp::BeakerHelpers
- Defined in:
- lib/simp/beaker_helpers.rb
Constant Summary collapse
- VERSION =
'1.5.3'
Instance Method Summary collapse
-
#clear_temp_hieradata ⇒ Object
Clean up all temporary hiera data files.
-
#copy_fixture_modules_to(suts = hosts, opts = {}) ⇒ Object
Copy the local fixture modules (under ‘spec/fixtures/modules`) onto each SUT.
-
#copy_keydist_to(ca_sut = master, host_keydist_dir = nil) ⇒ Object
Copy a CA keydist/ directory of CA+host certs into an SUT.
-
#copy_pki_to(sut, local_pki_dir, sut_base_dir = '/etc/pki/simp-testing') ⇒ Object
Copy a single SUT’s PKI certs (with cacerts) onto an SUT.
-
#enable_fips_mode_on(suts = hosts) ⇒ Object
Configure and reboot SUTs into FIPS mode.
-
#enable_yum_repos_on(suts = hosts) ⇒ Object
Collect all ‘yum_repos’ entries from the host nodeset.
-
#ensure_fixture_modules ⇒ Object
Ensures that the fixture modules (under ‘spec/fixtures/modules`) exists.
-
#fix_errata_on(suts = hosts) ⇒ Object
Apply known OS fixes we need to run Beaker on each SUT.
-
#fixtures_yml_path ⇒ Object
Locates .fixture.yml in or above this directory.
-
#pfact_on(sut, fact_name) ⇒ Object
use the ‘puppet fact` face to look up facts on an SUT.
-
#pluginsync_on(suts = hosts) ⇒ Object
pluginsync custom facts for all modules.
-
#pupmods_in_fixtures_yml ⇒ Object
returns an Array of puppet modules declared in .fixtures.yml.
-
#run_fake_pki_ca_on(ca_sut = master, suts = hosts, local_dir = '') ⇒ Object
Generate a fake openssl CA + certs for each host on a given SUT.
-
#set_hieradata_on(sut, hieradata, data_file = 'default') ⇒ Object
Set the hiera data file on the provided host to the passed data structure.
Instance Method Details
#clear_temp_hieradata ⇒ Object
Clean up all temporary hiera data files.
Meant to be called from after(:all)
475 476 477 478 479 480 481 482 483 |
# File 'lib/simp/beaker_helpers.rb', line 475 def clear_temp_hieradata if @temp_hieradata_dirs && !@temp_hieradata_dirs.empty? @temp_hieradata_dirs.each do |data_dir| if File.exists?(data_dir) FileUtils.rm_r(data_dir) end end end end |
#copy_fixture_modules_to(suts = hosts, opts = {}) ⇒ Object
Copy the local fixture modules (under ‘spec/fixtures/modules`) onto each SUT
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/simp/beaker_helpers.rb', line 74 def copy_fixture_modules_to( suts = hosts, opts = {}) ensure_fixture_modules opts[:pluginsync] = opts.fetch(:pluginsync, true) unless ENV['BEAKER_copy_fixtures'] == 'no' Array(suts).each do |sut| STDERR.puts " ** copy_fixture_modules_to: '#{sut}'" if ENV['BEAKER_helpers_verbose'] # Use spec_prep to provide modules (this supports isolated networks) unless ENV['BEAKER_use_fixtures_dir_for_modules'] == 'no' # NOTE: As a result of BKR-723, which does not look easy to fix, we # cannot rely on `copy_module_to()` to choose a sane default for # `target_module_path`. This workaround queries each SUT's # `modulepath` and targets the first one. target_module_path = on( sut, 'puppet config print modulepath --environment production' ).output.chomp.split(':').first mod_root = File.( "spec/fixtures/modules", File.dirname( fixtures_yml_path )) pupmods_in_fixtures_yml.each do |pupmod| STDERR.puts " ** copy_fixture_modules_to: '#{sut}': '#{pupmod}'" if ENV['BEAKER_helpers_verbose'] pupmod_root = File.join(mod_root, pupmod) if File.symlink?(pupmod_root) _opts = { :target_module_path => target_module_path, }.merge(opts) _opts = _opts.merge({ :source => pupmod_root, :module_name => pupmod }) copy_module_to(sut, _opts) end end _opts = { :ignore_list => PUPPET_MODULE_INSTALL_IGNORE }.merge(opts) _opts[:ignore] = build_ignore_list(_opts) scp_to(sut, mod_root, File.dirname(target_module_path), _opts) end end end STDERR.puts ' ** copy_fixture_modules_to: finished' if ENV['BEAKER_helpers_verbose'] # sync custom facts from the new modules to each SUT's factpath pluginsync_on(suts) if opts[:pluginsync] end |
#copy_keydist_to(ca_sut = master, host_keydist_dir = nil) ⇒ Object
Copy a CA keydist/ directory of CA+host certs into an SUT
This simulates the output of FakeCA’s gencerts_nopass.sh to keydist/
393 394 395 396 397 398 399 400 401 402 |
# File 'lib/simp/beaker_helpers.rb', line 393 def copy_keydist_to( ca_sut = master, host_keydist_dir = nil ) if !host_keydist_dir modulepath = on(ca_sut, 'puppet config print modulepath --environment production' ).output.chomp.split(':') host_keydist_dir = "#{modulepath.first}/pki/files/keydist" end on ca_sut, "rm -rf #{host_keydist_dir}/*" on ca_sut, "mkdir -p #{host_keydist_dir}/" on ca_sut, "cp -pR /root/pki/keydist/. #{host_keydist_dir}/" on ca_sut, "chgrp -R puppet #{host_keydist_dir}" end |
#copy_pki_to(sut, local_pki_dir, sut_base_dir = '/etc/pki/simp-testing') ⇒ Object
Copy a single SUT’s PKI certs (with cacerts) onto an SUT.
This simulates the result of pki::copy
The directory structure is:
SUT_BASE_DIR/
pki/
cacerts/cacerts.pem
public/fdqn.pub
private/fdqn.pem
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/simp/beaker_helpers.rb', line 358 def copy_pki_to(sut, local_pki_dir, sut_base_dir = '/etc/pki/simp-testing') fqdn = fact_on(sut, 'fqdn') sut_pki_dir = File.join( sut_base_dir, 'pki' ) local_host_pki_tree = File.join(local_pki_dir,'pki','keydist',fqdn) local_cacert = File.join(local_pki_dir,'pki','demoCA','cacert.pem') on sut, %Q(mkdir -p "#{sut_pki_dir}/public" "#{sut_pki_dir}/private" "#{sut_pki_dir}/cacerts") scp_to(sut, "#{local_host_pki_tree}/#{fqdn}.pem", "#{sut_pki_dir}/private/") scp_to(sut, "#{local_host_pki_tree}/#{fqdn}.pub", "#{sut_pki_dir}/public/") # NOTE: to match pki::copy, 'cacert.pem' is copied to 'cacerts.pem' scp_to(sut, local_cacert, "#{sut_pki_dir}/cacerts/cacerts.pem") # Need to hash all of the CA certificates so that apps can use them # properly! This must happen on the host itself since it needs to match # the native hashing algorithms. hash_cmd = <<-EOM.strip cd #{sut_pki_dir}/cacerts; \ for x in *; do \ if [ ! -h "$x" ]; then \ `openssl x509 -in $x >/dev/null 2>&1`; \ if [ $? -eq 0 ]; then \ hash=`openssl x509 -in $x -hash | head -1`; \ ln -sf $x $hash.0; \ fi; \ fi; \ done EOM on(sut, hash_cmd) end |
#enable_fips_mode_on(suts = hosts) ⇒ Object
Configure and reboot SUTs into FIPS mode
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/simp/beaker_helpers.rb', line 133 def enable_fips_mode_on( suts = hosts ) puts '== configuring FIPS mode on SUTs' puts ' -- (use BEAKER_fips=no to disable)' suts.each do |sut| puts " -- enabling FIPS on '#{sut}'" # We need to use FIPS compliant algorithms and keylengths as per the FIPS # certification. on(sut, 'puppet config set digest_algorithm sha256') on(sut, 'puppet config set keylength 2048') # We need to be able to get back into our system! # Make these safe for all systems, even old ones. fips_ssh_ciphers = [ 'aes256-cbc','aes192-cbc','aes128-cbc'] on(sut, %(sed -i '/Ciphers /d' /etc/ssh/sshd_config)) on(sut, %(echo 'Ciphers #{fips_ssh_ciphers.join(',')}' >> /etc/ssh/sshd_config)) if fact_on(sut, 'osfamily') == 'RedHat' pp = <<-EOS # This is necessary to prevent a kernel panic after rebooting into FIPS # (last checked: 20150928) package { ['kernel'] : ensure => 'latest' } package { ['grubby'] : ensure => 'latest' } ~> exec{ 'setup_fips': command => '/bin/bash /root/setup_fips.sh', refreshonly => true, } file{ '/root/setup_fips.sh': ensure => 'file', owner => 'root', group => 'root', mode => '0700', content => "#!/bin/bash # FIPS if [ -e /sys/firmware/efi ]; then BOOTDEV=`df /boot/efi | tail -1 | cut -f1 -d' '` else BOOTDEV=`df /boot | tail -1 | cut -f1 -d' '` fi # In case you need a working fallback DEFAULT_KERNEL_INFO=`/sbin/grubby --default-kernel` DEFAULT_INITRD=`/sbin/grubby --info=\\\${DEFAULT_KERNEL_INFO} | grep initrd | cut -f2 -d'='` DEFAULT_KERNEL_TITLE=`/sbin/grubby --info=\\\${DEFAULT_KERNEL_INFO} | grep -m1 title | cut -f2 -d'='` /sbin/grubby --copy-default --make-default --args=\\\"boot=\\\${BOOTDEV} fips=1\\\" --add-kernel=`/sbin/grubby --default-kernel` --initrd=\\\${DEFAULT_INITRD} --title=\\\"FIPS \\\${DEFAULT_KERNEL_TITLE}\\\" ", notify => Exec['setup_fips'] } EOS apply_manifest_on(sut, pp, :catch_failures => false) on( sut, 'shutdown -r now', { :expect_connection_failure => true } ) end end end |
#enable_yum_repos_on(suts = hosts) ⇒ Object
Collect all ‘yum_repos’ entries from the host nodeset. The acceptable format is as follows: yum_repos:
<repo_name>:
url: <URL>
gpgkeys:
- <URL to GPGKEY1>
- <URL to GPGKEY2>
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/simp/beaker_helpers.rb', line 200 def enable_yum_repos_on( suts = hosts ) repo_attrs = [ :assumeyes, :bandwidth, :cost, :deltarpm_metadata_percentage, :deltarpm_percentage, :descr, :enabled, :enablegroups, :exclude, :failovermethod, :gpgcakey, :gpgcheck, :http_caching, :include, :includepkgs, :keepalive, :metadata_expire, :metalink, :mirrorlist, :mirrorlist_expire, :priority, :protect, :provider, :proxy, :proxy_password, :proxy_username, :repo_gpgcheck, :retries, :s3_enabled, :skip_if_unavailable, :sslcacert, :sslclientcert, :sslclientkey, :sslverify, :target, :throttle, :timeout ] Array(suts).each do |sut| if sut['yum_repos'] sut['yum_repos'].each_pair do |repo, | repo_manifest = %(yumrepo { #{repo}:) repo_manifest_opts = [] # Legacy Support urls = ![:url].nil? ? [:url] : [:baseurl] if urls repo_manifest_opts << 'baseurl => ' + '"' + Array(urls).flatten.join('\n ').gsub('$','\$') + '"' end # Legacy Support gpgkeys = ![:gpgkeys].nil? ? [:gpgkeys] : [:gpgkey] if gpgkeys repo_manifest_opts << 'gpgkey => ' + '"' + Array(gpgkeys).flatten.join('\n ').gsub('$','\$') + '"' end repo_attrs.each do |attr| if [attr] repo_manifest_opts << "#{attr} => '#{[attr]}'" end end repo_manifest = repo_manifest + %(\n#{repo_manifest_opts.join(",\n")}) + "\n}" apply_manifest_on(sut, repo_manifest, :catch_failures => true) end end end end |
#ensure_fixture_modules ⇒ Object
Ensures that the fixture modules (under ‘spec/fixtures/modules`) exists. if any fixture modules are missing, run ’rake spec_prep’ to populate the fixtures/modules
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/simp/beaker_helpers.rb', line 49 def ensure_fixture_modules STDERR.puts " ** ensure_fixture_modules" if ENV['BEAKER_helpers_verbose'] unless ENV['BEAKER_spec_prep'] == 'no' puts "== checking prepped modules from .fixtures.yml" puts " -- (use BEAKER_spec_prep=no to disable)" missing_modules = [] pupmods_in_fixtures_yml.each do |pupmod| STDERR.puts " ** -- ensure_fixture_modules: '#{pupmod}'" if ENV['BEAKER_helpers_verbose'] mod_root = File.( "spec/fixtures/modules/#{pupmod}", File.dirname( fixtures_yml_path )) missing_modules << pupmod unless File.directory? mod_root end puts " -- #{missing_modules.size} modules need to be prepped" unless missing_modules.empty? cmd = 'bundle exec rake spec_prep' puts " -- running spec_prep: '#{cmd}'" %x(#{cmd}) else puts " == all fixture modules present" end end STDERR.puts " ** -- ensure_fixture_modules: finished" if ENV['BEAKER_helpers_verbose'] end |
#fix_errata_on(suts = hosts) ⇒ Object
Apply known OS fixes we need to run Beaker on each SUT
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/simp/beaker_helpers.rb', line 275 def fix_errata_on( suts = hosts ) suts.each do |sut| # SIMP uses structured facts, therefore stringify_facts must be disabled unless ENV['BEAKER_stringify_facts'] == 'yes' on sut, 'puppet config set stringify_facts false' end # Occasionally we run across something similar to BKR-561, so to ensure we # at least have the host defaults: # # :hieradatadir is used as a canary here; it isn't the only missing key unless sut.host_hash.key? :hieradatadir configure_type_defaults_on(sut) end if fact_on(sut, 'osfamily') == 'RedHat' enable_yum_repos_on(sut) # net-tools required for netstat utility being used by be_listening if fact_on(sut, 'operatingsystemmajrelease') == '7' pp = <<-EOS package { 'net-tools': ensure => installed } EOS apply_manifest_on(sut, pp, :catch_failures => false) end # Clean up YUM prior to starting our test runs. on(sut, 'yum clean all') end end # Configure and reboot SUTs into FIPS mode if ENV['BEAKER_fips'] == 'yes' enable_fips_mode_on(suts) end end |
#fixtures_yml_path ⇒ Object
Locates .fixture.yml in or above this directory.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/simp/beaker_helpers.rb', line 15 def fixtures_yml_path STDERR.puts ' ** fixtures_yml_path' if ENV['BEAKER_helpers_verbose'] fixtures_yml = '' dir = '.' while( fixtures_yml.empty? && File.(dir) != '/' ) do file = File.( '.fixtures.yml', dir ) STDERR.puts " ** fixtures_yml_path: #{file}" if ENV['BEAKER_helpers_verbose'] if File.exists? file fixtures_yml = file break end dir = "#{dir}/.." end raise 'ERROR: cannot locate .fixtures.yml!' if fixtures_yml.empty? STDERR.puts " ** fixtures_yml_path:finished (file: '#{file}')" if ENV['BEAKER_helpers_verbose'] fixtures_yml end |
#pfact_on(sut, fact_name) ⇒ Object
use the ‘puppet fact` face to look up facts on an SUT
7 8 9 10 11 |
# File 'lib/simp/beaker_helpers.rb', line 7 def pfact_on(sut, fact_name) facts_json = on(sut,'puppet facts find xxx').output facts = JSON.parse(facts_json).fetch( 'values' ) facts.fetch(fact_name) end |
#pluginsync_on(suts = hosts) ⇒ Object
pluginsync custom facts for all modules
487 488 489 490 491 492 493 494 495 496 497 498 |
# File 'lib/simp/beaker_helpers.rb', line 487 def pluginsync_on( suts = hosts ) puts "== pluginsync_on'" if ENV['BEAKER_helpers_verbose'] suts.each do |sut| puts " ** pluginsync_on: '#{sut}'" if ENV['BEAKER_helpers_verbose'] fact_path = on(sut, %q(puppet config print factpath)).output.strip.split(':').first on(sut, %q(puppet config print modulepath)).output.strip.split(':').each do |mod_path| on(sut, %Q(mkdir -p #{fact_path})) next if on(sut, "ls #{mod_path}/*/lib/facter 2>/dev/null ", :accept_all_exit_codes => true).exit_code != 0 on(sut, %Q(find #{mod_path}/*/lib/facter -type f -name '*.rb' -exec cp -a {} '#{fact_path}/' \\; )) end end end |
#pupmods_in_fixtures_yml ⇒ Object
returns an Array of puppet modules declared in .fixtures.yml
35 36 37 38 39 40 41 42 43 |
# File 'lib/simp/beaker_helpers.rb', line 35 def pupmods_in_fixtures_yml STDERR.puts ' ** pupmods_in_fixtures_yml' if ENV['BEAKER_helpers_verbose'] fixtures_yml = fixtures_yml_path data = YAML.load_file( fixtures_yml ) repos = data.fetch('fixtures').fetch('repositories', {}).keys || [] symlinks = data.fetch('fixtures').fetch('symlinks', {}).keys || [] STDERR.puts ' ** pupmods_in_fixtures_yml: finished' if ENV['BEAKER_helpers_verbose'] (repos + symlinks) end |
#run_fake_pki_ca_on(ca_sut = master, suts = hosts, local_dir = '') ⇒ Object
Generate a fake openssl CA + certs for each host on a given SUT
The directory structure is the same as what FakeCA drops into keydist/
NOTE: This generates everything within an SUT and copies it back out.
This is because it is assumed the SUT will have the appropriate
openssl in its environment, which may not be true of the host.
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/simp/beaker_helpers.rb', line 321 def run_fake_pki_ca_on( ca_sut = master, suts = hosts, local_dir = '' ) puts "== Fake PKI CA" pki_dir = File.( "../../files/pki", File.dirname(__FILE__)) host_dir = '/root/pki' fqdns = fact_on(hosts, 'fqdn') on ca_sut, %Q(mkdir -p "#{host_dir}") Dir[ File.join(pki_dir, '*') ].each{|f| scp_to( ca_sut, f, host_dir)} # generate PKI certs for each SUT Dir.mktmpdir do |dir| pki_hosts_file = File.join(dir, 'pki.hosts') File.open(pki_hosts_file, 'w'){|fh| fqdns.each{|fqdn| fh.puts fqdn}} scp_to(ca_sut, pki_hosts_file, host_dir) # generate certs on(ca_sut, "cd #{host_dir}; cat #{host_dir}/pki.hosts | xargs bash make.sh") end # if a local_dir was provided, copy everything down to it unless local_dir.empty? FileUtils.mkdir_p local_dir scp_from( ca_sut, host_dir, local_dir ) end end |
#set_hieradata_on(sut, hieradata, data_file = 'default') ⇒ Object
Set the hiera data file on the provided host to the passed data structure
Note: This is authoritative, you cannot mix this with other hieradata copies
@param[sut, Array<Host>, String, Symbol] One or more hosts to act upon.
@param[heradata, Hash || String] The full hiera data structure to write to the system.
@param[data_file, String] The filename (not path) of the hiera data
YAML file to write to the system.
@param[hiera_config, Array<String>] The hiera config array to write
to the system. Must contain the
Data_file name as one element.
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
# File 'lib/simp/beaker_helpers.rb', line 438 def set_hieradata_on(sut, hieradata, data_file='default') # Keep a record of all temporary directories that are created # # Should be cleaned by calling `clear_temp_hiera data` in after(:all) # # Omit this call to be able to delve into the hiera data that is # being created @temp_hieradata_dirs = @temp_hieradata_dirs || [] data_dir = Dir.mktmpdir('hieradata') @temp_hieradata_dirs << data_dir fh = File.open(File.join(data_dir,"#{data_file}.yaml"),'w') if hieradata.kind_of? String fh.puts(hieradata) else fh.puts(hieradata.to_yaml) end fh.close # If there is already a directory on the system, the SCP below will # add the local directory to the existing directory instead of # replacing the contents. apply_manifest_on( sut, "file { '#{hiera_datadir(sut)}': ensure => 'absent', force => true, recurse => true }" ) copy_hiera_data_to(sut, data_dir) write_hiera_config_on(sut, Array(data_file)) end |