kitchen-puppet 1.41.2 → 1.42.0

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.
@@ -1,1097 +1,1116 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Chris Lundquist (<chris.lundquist@github.com>) Neill Turner (<neillwturner@gmail.com>)
4
- #
5
- # Copyright (C) 2013,2014 Chris Lundquist, Neill Turner
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
- #
19
- # See https://github.com/neillturner/kitchen-puppet/blob/master/provisioner_options.md
20
- # for documentation configuration parameters with puppet_apply provisioner.
21
- #
22
-
23
- require 'uri'
24
- require 'json'
25
- require 'kitchen'
26
- require 'kitchen/provisioner/puppet/librarian'
27
-
28
- module Kitchen
29
- class Busser
30
- def non_suite_dirs
31
- %w(data data_bags environments nodes roles puppet)
32
- end
33
- end
34
-
35
- module Configurable
36
- def platform_name
37
- instance.platform.name
38
- end
39
- end
40
-
41
- module Provisioner
42
- #
43
- # Puppet Apply provisioner.
44
- #
45
- class PuppetApply < Base
46
- attr_accessor :tmp_dir
47
-
48
- default_config :require_puppet_collections, false
49
- default_config :puppet_yum_collections_repo, 'http://yum.puppetlabs.com/puppetlabs-release-pc1-el-6.noarch.rpm'
50
- default_config :puppet_apt_collections_repo, 'http://apt.puppetlabs.com/puppetlabs-release-pc1-wheezy.deb'
51
- default_config :puppet_coll_remote_path, '/opt/puppetlabs'
52
- default_config :puppet_version, nil
53
- default_config :facter_version, nil
54
- default_config :hiera_version, nil
55
- default_config :install_hiera, false
56
- default_config :hiera_package, 'hiera-puppet'
57
- default_config :require_puppet_repo, true
58
- default_config :require_chef_for_busser, true
59
- default_config :resolve_with_librarian_puppet, true
60
- default_config :puppet_environment, nil
61
- default_config :puppet_apt_repo, 'http://apt.puppetlabs.com/puppetlabs-release-precise.deb'
62
- default_config :puppet_yum_repo, 'https://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm'
63
- default_config :chef_bootstrap_url, 'https://www.getchef.com/chef/install.sh'
64
- default_config :puppet_logdest, nil
65
- default_config :custom_install_command, nil
66
- default_config :puppet_whitelist_exit_code, nil
67
- default_config :require_puppet_omnibus, false
68
- default_config :puppet_omnibus_url, 'https://raw.githubusercontent.com/petems/puppet-install-shell/master/install_puppet.sh'
69
- default_config :puppet_enc, nil
70
- default_config :ignore_spec_fixtures, false
71
-
72
- default_config :puppet_apply_command, nil
73
-
74
- default_config :puppet_git_init, nil
75
- default_config :puppet_git_pr, nil
76
-
77
- default_config :http_proxy, nil
78
- default_config :https_proxy, nil
79
-
80
- default_config :ignored_paths_from_root, []
81
- default_config :hiera_data_remote_path, '/var/lib/hiera'
82
- default_config :manifest, 'site.pp'
83
-
84
- default_config :manifests_path do |provisioner|
85
- provisioner.calculate_path('manifests') ||
86
- raise('No manifests_path detected. Please specify one in .kitchen.yml')
87
- end
88
-
89
- default_config :modules_path do |provisioner|
90
- modules_path = provisioner.calculate_path('modules')
91
- if modules_path.nil? && provisioner.calculate_path('Puppetfile', :file).nil?
92
- raise('No modules_path detected. Please specify one in .kitchen.yml')
93
- end
94
- modules_path
95
- end
96
-
97
- default_config :files_path do |provisioner|
98
- provisioner.calculate_path('files') || 'files'
99
- end
100
-
101
- default_config :hiera_data_path do |provisioner|
102
- provisioner.calculate_path('hiera')
103
- end
104
-
105
- default_config :puppet_config_path do |provisioner|
106
- provisioner.calculate_path('puppet.conf', :file)
107
- end
108
-
109
- default_config :hiera_config_path do |provisioner|
110
- provisioner.calculate_path('hiera.yaml', :file)
111
- end
112
-
113
- default_config :fileserver_config_path do |provisioner|
114
- provisioner.calculate_path('fileserver.conf', :file)
115
- end
116
- default_config :puppetfile_path do |provisioner|
117
- provisioner.calculate_path('Puppetfile', :file)
118
- end
119
-
120
- default_config :modulefile_path do |provisioner|
121
- provisioner.calculate_path('Modulefile', :file)
122
- end
123
-
124
- default_config :metadata_json_path do |provisioner|
125
- provisioner.calculate_path('metadata.json', :file)
126
- end
127
-
128
- default_config :manifests_path do |provisioner|
129
- provisioner.calculate_path('manifests', :directory)
130
- end
131
-
132
- default_config :spec_files_path do |provisioner|
133
- provisioner.calculate_path('spec', :directory)
134
- end
135
-
136
- default_config :spec_files_remote_path, '/etc/puppet/spec'
137
-
138
- default_config :puppet_debug, false
139
- default_config :puppet_verbose, false
140
- default_config :puppet_noop, false
141
- default_config :platform, &:platform_name
142
- default_config :update_package_repos, true
143
- default_config :remove_puppet_repo, false
144
- default_config :install_custom_facts, false
145
- default_config :custom_facts, {}
146
- default_config :facterlib, nil
147
- default_config :puppet_detailed_exitcodes, nil
148
- default_config :facter_file, nil
149
- default_config :librarian_puppet_ssl_file, nil
150
-
151
- default_config :hiera_eyaml, false
152
- default_config :hiera_eyaml_key_remote_path, '/etc/puppet/secure/keys'
153
-
154
- default_config :hiera_eyaml_key_path do |provisioner|
155
- provisioner.calculate_path('hiera_keys')
156
- end
157
-
158
- default_config :hiera_deep_merge, false
159
- default_config :puppet_no_sudo, false
160
-
161
- def calculate_path(path, type = :directory)
162
- base = config[:test_base_path]
163
- candidates = []
164
- candidates << File.join(base, instance.suite.name, 'puppet', path)
165
- candidates << File.join(base, instance.suite.name, path)
166
- candidates << File.join(base, path)
167
- candidates << File.join(Dir.pwd, path)
168
-
169
- candidates.find do |c|
170
- type == :directory ? File.directory?(c) : File.file?(c)
171
- end
172
- end
173
-
174
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
175
- def install_command
176
- return unless config[:require_puppet_collections] || config[:require_puppet_repo] || config[:require_puppet_omnibus]
177
- if config[:require_puppet_omnibus]
178
- install_omnibus_command
179
- elsif config[:require_puppet_collections]
180
- install_command_collections
181
- else
182
- case puppet_platform
183
- when 'debian', 'ubuntu'
184
- info("Installing puppet on #{config[:platform]}")
185
- # need to add a CR to avoid trouble with proxy settings concatenation
186
- <<-INSTALL
187
-
188
- if [ ! $(which puppet) ]; then
189
- #{sudo('apt-get')} -y install wget
190
- #{sudo('wget')} #{wget_proxy_parm} #{puppet_apt_repo}
191
- #{sudo('dpkg')} -i #{puppet_apt_repo_file}
192
- #{update_packages_debian_cmd}
193
- #{sudo_env('apt-get')} -y install facter#{facter_debian_version}
194
- #{sudo_env('apt-get')} -y install puppet-common#{puppet_debian_version}
195
- #{sudo_env('apt-get')} -y install puppet#{puppet_debian_version}
196
- #{install_hiera}
197
- fi
198
- #{install_eyaml}
199
- #{install_deep_merge}
200
- #{install_busser}
201
- #{custom_install_command}
202
- INSTALL
203
- when 'redhat', 'centos', 'fedora', 'oracle', 'amazon'
204
- info("Installing puppet from yum on #{puppet_platform}")
205
- # need to add a CR to avoid trouble with proxy settings concatenation
206
- <<-INSTALL
207
-
208
- if [ ! $(which puppet) ]; then
209
- #{install_puppet_yum_repo}
210
- fi
211
- #{install_eyaml}
212
- #{install_deep_merge}
213
- #{install_busser}
214
- #{custom_install_command}
215
- INSTALL
216
- else
217
- info('Installing puppet, will try to determine platform os')
218
- # need to add a CR to avoid trouble with proxy settings concatenation
219
- <<-INSTALL
220
-
221
- if [ ! $(which puppet) ]; then
222
- if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ] || [ -f /etc/oracle-release ]; then
223
- #{install_puppet_yum_repo}
224
- else
225
- if [ -f /etc/system-release ] || [ grep -q 'Amazon Linux' /etc/system-release ]; then
226
- #{install_puppet_yum_repo}
227
- else
228
- #{sudo('apt-get')} -y install wget
229
- #{sudo('wget')} #{wget_proxy_parm} #{puppet_apt_repo}
230
- #{sudo('dpkg')} -i #{puppet_apt_repo_file}
231
- #{update_packages_debian_cmd}
232
- #{sudo_env('apt-get')} -y install facter#{facter_debian_version}
233
- #{sudo_env('apt-get')} -y install puppet-common#{puppet_debian_version}
234
- #{sudo_env('apt-get')} -y install puppet#{puppet_debian_version}
235
- #{install_hiera}
236
- fi
237
- fi
238
- fi
239
- #{install_eyaml}
240
- #{install_deep_merge}
241
- #{install_busser}
242
- #{custom_install_command}
243
- INSTALL
244
- end
245
- end
246
- end
247
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
248
-
249
- def install_command_collections
250
- case puppet_platform
251
- when 'debian', 'ubuntu'
252
- info("Installing Puppet Collections on #{puppet_platform}")
253
- <<-INSTALL
254
- #{Util.shell_helpers}
255
- if [ ! -d "#{config[:puppet_coll_remote_path]}" ]; then
256
- if [ ! -f "#{config[:puppet_apt_collections_repo]}" ]; then
257
- #{sudo('apt-get')} -y install wget
258
- #{sudo('wget')} #{wget_proxy_parm} #{config[:puppet_apt_collections_repo]}
259
- fi
260
- #{sudo('dpkg')} -i #{puppet_apt_coll_repo_file}
261
- #{sudo('apt-get')} update
262
- #{sudo_env('apt-get')} -y install puppet-agent#{puppet_debian_version}
263
- fi
264
- #{install_eyaml("#{config[:puppet_coll_remote_path]}/puppet/bin/gem")}
265
- #{install_deep_merge}
266
- #{install_busser}
267
- #{custom_install_command}
268
- INSTALL
269
- when 'redhat', 'centos', 'fedora', 'oracle', 'amazon'
270
- info("Installing Puppet Collections on #{puppet_platform}")
271
- <<-INSTALL
272
- #{Util.shell_helpers}
273
- if [ ! -d "#{config[:puppet_coll_remote_path]}" ]; then
274
- echo "-----> #{sudo_env('yum')} -y localinstall #{config[:puppet_yum_collections_repo]}"
275
- #{sudo_env('yum')} -y localinstall #{config[:puppet_yum_collections_repo]}
276
- #{sudo_env('yum')} -y install puppet-agent#{puppet_redhat_version}
277
- fi
278
- #{install_eyaml("#{config[:puppet_coll_remote_path]}/puppet/bin/gem")}
279
- #{install_deep_merge}
280
- #{install_busser}
281
- #{custom_install_command}
282
- INSTALL
283
- else
284
- info('Installing Puppet Collections, will try to determine platform os')
285
- <<-INSTALL
286
- #{Util.shell_helpers}
287
- if [ ! -d "#{config[:puppet_coll_remote_path]}" ]; then
288
- if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ] || [ -f /etc/oracle-release ] || \
289
- [ -f /etc/system-release ] || [ grep -q 'Amazon Linux' /etc/system-release ]; then
290
- echo "-----> #{sudo_env('yum')} -y localinstall #{config[:puppet_yum_collections_repo]}"
291
- #{sudo_env('yum')} -y localinstall #{config[:puppet_yum_collections_repo]}
292
- #{sudo_env('yum')} -y install puppet-agent#{puppet_redhat_version}
293
- else
294
- #{sudo('apt-get')} -y install wget
295
- #{sudo('wget')} #{wget_proxy_parm} #{config[:puppet_apt_collections_repo]}
296
- #{sudo('dpkg')} -i #{puppet_apt_coll_repo_file}
297
- #{sudo('apt-get')} update
298
- #{sudo_env('apt-get')} -y install puppet-agent#{puppet_debian_version}
299
- fi
300
- fi
301
- #{install_eyaml("#{config[:puppet_coll_remote_path]}/puppet/bin/gem")}
302
- #{install_deep_merge}
303
- #{install_busser}
304
- #{custom_install_command}
305
- INSTALL
306
- end
307
- end
308
-
309
- def install_deep_merge
310
- return unless config[:hiera_deep_merge]
311
- <<-INSTALL
312
- # Support for hash merge lookups to recursively merge hash keys
313
- if [[ $(#{sudo('gem')} list deep_merge -i) == 'false' ]]; then
314
- echo '-----> Installing deep_merge to provide deep_merge of hiera hashes'
315
- #{sudo('gem')} install #{gem_proxy_parm} --no-ri --no-rdoc deep_merge
316
- fi
317
- INSTALL
318
- end
319
-
320
- def install_eyaml(gem_cmd = 'gem')
321
- return unless config[:hiera_eyaml]
322
- <<-INSTALL
323
- # A backend for Hiera that provides per-value asymmetric encryption of sensitive data
324
- if [[ $(#{sudo(gem_cmd)} list hiera-eyaml -i) == 'false' ]]; then
325
- echo '-----> Installing hiera-eyaml to provide encryption of hiera data'
326
- #{sudo(gem_cmd)} install #{gem_proxy_parm} --no-ri --no-rdoc highline -v 1.6.21
327
- #{sudo(gem_cmd)} install #{gem_proxy_parm} --no-ri --no-rdoc hiera-eyaml
328
- fi
329
- INSTALL
330
- end
331
-
332
- def install_busser
333
- return unless config[:require_chef_for_busser]
334
- <<-INSTALL
335
- #{Util.shell_helpers}
336
- # install chef omnibus so that busser works as this is needed to run tests :(
337
- # TODO: work out how to install enough ruby
338
- # and set busser: { :ruby_bindir => '/usr/bin/ruby' } so that we dont need the
339
- # whole chef client
340
- if [ ! -d "/opt/chef" ]
341
- then
342
- echo '-----> Installing Chef Omnibus to install busser to run tests'
343
- #{export_http_proxy_parm}
344
- #{export_https_proxy_parm}
345
- do_download #{chef_url} /tmp/install.sh
346
- #{sudo('sh')} /tmp/install.sh
347
- fi
348
- INSTALL
349
- end
350
-
351
- def install_omnibus_command
352
- info('Installing puppet using puppet omnibus')
353
- <<-INSTALL
354
- #{Util.shell_helpers}
355
- if [ ! $(which puppet) ]; then
356
- echo "-----> Installing Puppet Omnibus"
357
- #{export_http_proxy_parm}
358
- #{export_https_proxy_parm}
359
- do_download #{config[:puppet_omnibus_url]} /tmp/install_puppet.sh
360
- #{sudo_env('sh')} /tmp/install_puppet.sh
361
- fi
362
- INSTALL
363
- end
364
-
365
- def install_hiera
366
- return unless config[:install_hiera]
367
- <<-INSTALL
368
- #{sudo_env('apt-get')} -y install #{hiera_package}
369
- INSTALL
370
- end
371
-
372
- def hiera_package
373
- "#{config[:hiera_package]}#{puppet_hiera_debian_version}"
374
- end
375
-
376
- # /bin/wget -P /etc/pki/rpm-gpg/ http://yum.puppetlabs.com/RPM-GPG-KEY-puppetlabs
377
- # changed to curl
378
-
379
- def install_puppet_yum_repo
380
- <<-INSTALL
381
- rhelversion=$(cat /etc/redhat-release | grep 'release 7')
382
- # For CentOS7/RHEL7 the rdo release contains puppetlabs repo, creating conflict. Create temp-repo
383
- #{sudo_env('curl')} -o /etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs http://yum.puppetlabs.com/RPM-GPG-KEY-puppetlabs
384
- if [ -n "$rhelversion" ]; then
385
- echo '[puppettemp-products]
386
- name=Puppet Labs Products - \$basearch
387
- baseurl=http://yum.puppetlabs.com/el/7/products/\$basearch
388
- gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
389
- enabled=0
390
- gpgcheck=1
391
- [puppettemp-deps]
392
- name=Puppet Labs Dependencies - \$basearch
393
- baseurl=http://yum.puppetlabs.com/el/7/dependencies/\$basearch
394
- gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
395
- enabled=0
396
- gpgcheck=1' | sudo tee /etc/yum.repos.d/puppettemp.repo > /dev/null
397
- sudo sed -i 's/^[ \t]*//' /etc/yum.repos.d/puppettemp.repo
398
- #{update_packages_redhat_cmd}
399
- #{sudo_env('yum')} -y --enablerepo=puppettemp-products --enablerepo=puppettemp-deps install puppet#{puppet_redhat_version}
400
- # Clean up temporary puppet repo
401
- sudo rm -rf /etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
402
- sudo rm -rf /etc/yum.repos.d/puppettemp.repo
403
- else
404
- #{sudo('rpm')} -ivh #{proxy_parm} #{puppet_yum_repo}
405
- #{update_packages_redhat_cmd}
406
- #{sudo_env('yum')} -y install puppet#{puppet_redhat_version}
407
- fi
408
- INSTALL
409
- end
410
-
411
- def custom_install_command
412
- <<-INSTALL
413
- #{config[:custom_install_command]}
414
- INSTALL
415
- end
416
-
417
- def init_command
418
- dirs = %w(modules manifests files hiera hiera.yaml facter spec enc)
419
- .map { |dir| File.join(config[:root_path], dir) }.join(' ')
420
- cmd = "#{sudo('rm')} -rf #{dirs} #{hiera_data_remote_path} \
421
- /etc/hiera.yaml #{puppet_dir}/hiera.yaml \
422
- #{spec_files_remote_path} \
423
- #{puppet_dir}/fileserver.conf;"
424
- cmd += config[:puppet_environment] ? "#{sudo('rm')} -f #{File.join(puppet_dir, config[:puppet_environment])};" : ''
425
- cmd += " mkdir -p #{config[:root_path]}; #{sudo('mkdir')} -p #{puppet_dir}"
426
- debug(cmd)
427
- cmd
428
- end
429
-
430
- def create_sandbox
431
- super
432
- debug("Creating local sandbox in #{sandbox_path}")
433
- yield if block_given?
434
- prepare_modules
435
- prepare_manifests
436
- prepare_files
437
- prepare_facter_file
438
- prepare_facts
439
- prepare_puppet_config
440
- prepare_hiera_config
441
- prepare_fileserver_config
442
- prepare_hiera_data
443
- prepare_enc
444
- prepare_spec_files
445
- info('Finished Preparing files for transfer')
446
- end
447
-
448
- def cleanup_sandbox
449
- return if sandbox_path.nil?
450
- debug("Cleaning up local sandbox in #{sandbox_path}")
451
- FileUtils.rmtree(sandbox_path)
452
- return if remove_repo.nil?
453
- debug("Cleaning up remote sandbox: #{remove_repo}")
454
- instance.remote_exec remove_repo
455
- end
456
-
457
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
458
- def prepare_command
459
- commands = []
460
- if puppet_git_init
461
- commands << [
462
- sudo('rm -rf'), '/etc/puppet'
463
- ].join(' ')
464
-
465
- commands << [
466
- sudo('git clone'), puppet_git_init, '/etc/puppet'
467
- ].join(' ')
468
- end
469
-
470
- if puppet_git_pr
471
- commands << [
472
- sudo('git'),
473
- '--git-dir=/etc/puppet/.git/',
474
- 'fetch -f',
475
- 'origin',
476
- "pull/#{puppet_git_pr}/head:pr_#{puppet_git_pr}"
477
- ].join(' ')
478
-
479
- commands << [
480
- sudo('git'),
481
- '--git-dir=/etc/puppet/.git/',
482
- '--work-tree=/etc/puppet/',
483
- 'checkout',
484
- "pr_#{puppet_git_pr}"
485
- ].join(' ')
486
- end
487
-
488
- if puppet_config
489
- commands << [
490
- sudo('cp'),
491
- File.join(config[:root_path], 'puppet.conf'),
492
- puppet_dir
493
- ].join(' ')
494
- end
495
-
496
- if hiera_config
497
- commands << [
498
- sudo('cp'), File.join(config[:root_path], 'hiera.yaml'), '/etc/'
499
- ].join(' ')
500
-
501
- commands << [
502
- sudo('cp'), File.join(config[:root_path], 'hiera.yaml'), hiera_config_dir
503
- ].join(' ')
504
- end
505
-
506
- if fileserver_config
507
- commands << [
508
- sudo('cp'),
509
- File.join(config[:root_path], 'fileserver.conf'),
510
- puppet_dir
511
- ].join(' ')
512
- end
513
-
514
- if hiera_data && hiera_data_remote_path == '/var/lib/hiera'
515
- commands << [
516
- sudo('cp -r'), File.join(config[:root_path], 'hiera'), '/var/lib/'
517
- ].join(' ')
518
- end
519
-
520
- if hiera_data && hiera_data_remote_path != '/var/lib/hiera'
521
- commands << [
522
- sudo('mkdir -p'), hiera_data_remote_path
523
- ].join(' ')
524
- commands << [
525
- sudo('cp -r'), File.join(config[:root_path], 'hiera/*'), hiera_data_remote_path
526
- ].join(' ')
527
- end
528
-
529
- if hiera_eyaml
530
- commands << [
531
- sudo('mkdir -p'), hiera_eyaml_key_remote_path
532
- ].join(' ')
533
- commands << [
534
- sudo('cp -r'), File.join(config[:root_path], 'hiera_keys/*'), hiera_eyaml_key_remote_path
535
- ].join(' ')
536
- end
537
-
538
- if puppet_environment
539
- commands << [
540
- sudo('ln -s '), config[:root_path], File.join(puppet_dir, config[:puppet_environment])
541
- ].join(' ')
542
- end
543
-
544
- if spec_files_path && spec_files_remote_path
545
- commands << [
546
- sudo('mkdir -p'), spec_files_remote_path
547
- ].join(' ')
548
- commands << [
549
- sudo('cp -r'), File.join(config[:root_path], 'spec/*'), spec_files_remote_path
550
- ].join(' ')
551
- end
552
-
553
- if config[:puppet_enc]
554
- commands << [
555
- sudo('chmod 755'), File.join("#{config[:root_path]}/enc", File.basename(config[:puppet_enc]))
556
- ].join(' ')
557
- end
558
-
559
- command = commands.join(' && ')
560
- debug(command)
561
- command
562
- end
563
-
564
- def run_command
565
- if !config[:puppet_apply_command].nil?
566
- return config[:puppet_apply_command]
567
- else
568
- result = [
569
- facterlib,
570
- custom_facts,
571
- puppet_manifestdir,
572
- puppet_cmd,
573
- 'apply',
574
- File.join(config[:root_path], 'manifests', manifest),
575
- "--modulepath=#{File.join(config[:root_path], 'modules')}",
576
- "--fileserverconfig=#{File.join(config[:root_path], 'fileserver.conf')}",
577
- custom_options,
578
- puppet_environment_flag,
579
- puppet_noop_flag,
580
- puppet_enc_flag,
581
- puppet_detailed_exitcodes_flag,
582
- puppet_verbose_flag,
583
- puppet_debug_flag,
584
- puppet_logdest_flag,
585
- puppet_whitelist_exit_code
586
- ].join(' ')
587
- info("Going to invoke puppet apply with: #{result}")
588
- result
589
- end
590
- end
591
-
592
- protected
593
-
594
- def load_needed_dependencies!
595
- return unless File.exist?(puppetfile)
596
- return unless config[:resolve_with_librarian_puppet]
597
- debug("Puppetfile found at #{puppetfile}, loading Librarian-Puppet")
598
- Puppet::Librarian.load!(logger)
599
- end
600
-
601
- def tmpmodules_dir
602
- File.join(sandbox_path, 'modules')
603
- end
604
-
605
- def puppetfile
606
- config[:puppetfile_path] || ''
607
- end
608
-
609
- def modulefile
610
- config[:modulefile_path] || ''
611
- end
612
-
613
- def metadata_json
614
- config[:metadata_json_path] || ''
615
- end
616
-
617
- def manifest
618
- config[:manifest]
619
- end
620
-
621
- def manifests
622
- config[:manifests_path]
623
- end
624
-
625
- def modules
626
- config[:modules_path]
627
- end
628
-
629
- def files
630
- config[:files_path] || 'files'
631
- end
632
-
633
- def puppet_config
634
- config[:puppet_config_path]
635
- end
636
-
637
- def puppet_environment
638
- config[:puppet_environment]
639
- end
640
-
641
- def puppet_git_init
642
- config[:puppet_git_init]
643
- end
644
-
645
- def puppet_git_pr
646
- config[:puppet_git_pr]
647
- end
648
-
649
- def hiera_config
650
- config[:hiera_config_path]
651
- end
652
-
653
- def fileserver_config
654
- config[:fileserver_config_path]
655
- end
656
-
657
- def hiera_data
658
- config[:hiera_data_path]
659
- end
660
-
661
- def hiera_data_remote_path
662
- config[:hiera_data_remote_path]
663
- end
664
-
665
- def hiera_eyaml
666
- config[:hiera_eyaml]
667
- end
668
-
669
- def hiera_eyaml_key_path
670
- config[:hiera_eyaml_key_path]
671
- end
672
-
673
- def hiera_eyaml_key_remote_path
674
- config[:hiera_eyaml_key_remote_path]
675
- end
676
-
677
- def hiera_deep_merge
678
- config[:hiera_deep_merge]
679
- end
680
-
681
- def librarian_puppet_ssl_file
682
- config[:librarian_puppet_ssl_file]
683
- end
684
-
685
- def puppet_cmd
686
- puppet_bin = 'puppet'
687
- if config[:require_puppet_collections]
688
- puppet_bin = "#{config[:puppet_coll_remote_path]}/bin/puppet"
689
- end
690
-
691
- if config[:puppet_no_sudo]
692
- puppet_bin
693
- else
694
- sudo_env(puppet_bin)
695
- end
696
- end
697
-
698
- def puppet_dir
699
- if config[:require_puppet_collections]
700
- '/etc/puppetlabs/puppet'
701
- else
702
- '/etc/puppet'
703
- end
704
- end
705
-
706
- def hiera_config_dir
707
- if config[:require_puppet_collections]
708
- '/etc/puppetlabs/code'
709
- else
710
- '/etc/puppet'
711
- end
712
- end
713
-
714
- def puppet_debian_version
715
- config[:puppet_version] ? "=#{config[:puppet_version]}" : nil
716
- end
717
-
718
- def facter_debian_version
719
- config[:facter_version] ? "=#{config[:facter_version]}" : nil
720
- end
721
-
722
- def puppet_hiera_debian_version
723
- config[:hiera_version] ? "=#{config[:hiera_version]}" : nil
724
- end
725
-
726
- def puppet_redhat_version
727
- if puppet_platform == 'amazon'
728
- config[:puppet_version]
729
- else
730
- config[:puppet_version] ? "-#{config[:puppet_version]}" : nil
731
- end
732
- end
733
-
734
- def puppet_environment_flag
735
- if config[:puppet_version] =~ /^2/
736
- config[:puppet_environment] ? "--environment=#{config[:puppet_environment]}" : nil
737
- else
738
- config[:puppet_environment] ? "--environment=#{config[:puppet_environment]} --environmentpath=#{puppet_dir}" : nil
739
- end
740
- end
741
-
742
- def puppet_manifestdir
743
- return nil if config[:require_puppet_collections]
744
- return nil if config[:puppet_environment]
745
- bash_vars = "export MANIFESTDIR='#{File.join(config[:root_path], 'manifests')}';"
746
- debug(bash_vars)
747
- bash_vars
748
- end
749
-
750
- def custom_options
751
- config[:custom_options] || ''
752
- end
753
-
754
- def puppet_noop_flag
755
- config[:puppet_noop] ? '--noop' : nil
756
- end
757
-
758
- def puppet_debug_flag
759
- config[:puppet_debug] ? '-d' : nil
760
- end
761
-
762
- def puppet_verbose_flag
763
- config[:puppet_verbose] ? '-v' : nil
764
- end
765
-
766
- def puppet_logdest_flag
767
- return nil unless config[:puppet_logdest]
768
- destinations = ''
769
- config[:puppet_logdest].each do |dest|
770
- destinations << "--logdest #{dest} "
771
- end
772
- destinations
773
- end
774
-
775
- def puppet_platform
776
- config[:platform].gsub(/-.*/, '')
777
- end
778
-
779
- def update_packages_debian_cmd
780
- config[:update_package_repos] ? "#{sudo_env('apt-get')} update" : nil
781
- end
782
-
783
- def update_packages_redhat_cmd
784
- # #{sudo('yum')}
785
- config[:update_package_repos] ? "#{sudo_env('yum')} makecache" : nil
786
- end
787
-
788
- def sudo_env(pm)
789
- s = https_proxy ? "https_proxy=#{https_proxy}" : nil
790
- p = http_proxy ? "http_proxy=#{http_proxy}" : nil
791
- p || s ? "#{sudo('env')} #{p} #{s} #{pm}" : sudo(pm).to_s
792
- end
793
-
794
- def remove_puppet_repo
795
- config[:remove_puppet_repo]
796
- end
797
-
798
- def spec_files_path
799
- config[:spec_files_path]
800
- end
801
-
802
- def spec_files_remote_path
803
- config[:spec_files_remote_path]
804
- end
805
-
806
- def facterlib
807
- factpath = nil
808
- factpath = File.join(config[:root_path], 'facter').to_s if config[:install_custom_facts] && !config[:custom_facts].none?
809
- factpath = File.join(config[:root_path], 'facter').to_s if config[:facter_file]
810
- factpath = "#{factpath}:" if config[:facterlib] && !factpath.nil?
811
- factpath = "#{factpath}#{config[:facterlib]}" if config[:facterlib]
812
- return nil if factpath.nil?
813
- bash_vars = "export FACTERLIB='#{factpath}';"
814
- debug(bash_vars)
815
- bash_vars
816
- end
817
-
818
- def custom_facts
819
- return nil if config[:custom_facts].none?
820
- return nil if config[:install_custom_facts]
821
- bash_vars = config[:custom_facts].map { |k, v| "FACTER_#{k}=#{v}" }.join(' ')
822
- bash_vars = "export #{bash_vars};"
823
- debug(bash_vars)
824
- bash_vars
825
- end
826
-
827
- def puppet_enc_flag
828
- config[:puppet_enc] ? "--node_terminus=exec --external_nodes=#{config[:root_path]}/enc/#{File.basename(config[:puppet_enc])}" : nil
829
- end
830
-
831
- def puppet_detailed_exitcodes_flag
832
- config[:puppet_detailed_exitcodes] ? '--detailed-exitcodes' : nil
833
- end
834
-
835
- def remove_repo
836
- remove_puppet_repo ? "#{sudo('rm')} -rf /tmp/kitchen #{hiera_data_remote_path} #{hiera_eyaml_key_remote_path} #{puppet_dir}/* " : nil
837
- end
838
-
839
- def puppet_whitelist_exit_code
840
- config[:puppet_whitelist_exit_code] ? "; [ $? -eq #{config[:puppet_whitelist_exit_code]} ] && exit 0" : nil
841
- end
842
-
843
- def puppet_apt_repo
844
- platform_version = config[:platform].partition('-')[2]
845
- case puppet_platform
846
- when 'ubuntu'
847
- case platform_version
848
- when '14.10'
849
- # Utopic Repo
850
- 'https://apt.puppetlabs.com/puppetlabs-release-utopic.deb'
851
- when '14.04'
852
- # Trusty Repo
853
- 'https://apt.puppetlabs.com/puppetlabs-release-trusty.deb'
854
- when '12.04'
855
- # Precise Repo
856
- 'https://apt.puppetlabs.com/puppetlabs-release-precise.deb'
857
- else
858
- # Configured Repo
859
- config[:puppet_apt_repo]
860
- end
861
- when 'debian'
862
- case platform_version.gsub(/\..*/, '')
863
- when '8'
864
- # Debian Jessie
865
- 'https://apt.puppetlabs.com/puppetlabs-release-jessie.deb'
866
- when '7'
867
- # Debian Wheezy
868
- 'https://apt.puppetlabs.com/puppetlabs-release-wheezy.deb'
869
- when '6'
870
- # Debian Squeeze
871
- 'https://apt.puppetlabs.com/puppetlabs-release-squeeze.deb'
872
- else
873
- # Configured Repo
874
- config[:puppet_apt_repo]
875
- end
876
- else
877
- debug("Apt repo detection failed with platform - #{config[:platform]}")
878
- false
879
- end
880
- end
881
-
882
- def puppet_apt_repo_file
883
- puppet_apt_repo.split('/').last if puppet_apt_repo
884
- end
885
-
886
- def puppet_apt_coll_repo_file
887
- config[:puppet_apt_collections_repo].split('/').last
888
- end
889
-
890
- def puppet_yum_repo
891
- config[:puppet_yum_repo]
892
- end
893
-
894
- def proxy_parm
895
- http_proxy ? "--httpproxy #{URI.parse(http_proxy).host.downcase} --httpport #{URI.parse(http_proxy).port} " : nil
896
- end
897
-
898
- def gem_proxy_parm
899
- http_proxy ? "--http-proxy #{http_proxy}" : nil
900
- end
901
-
902
- def wget_proxy_parm
903
- p = http_proxy ? "-e http_proxy=#{http_proxy}" : nil
904
- s = https_proxy ? "-e https_proxy=#{https_proxy}" : nil
905
- p || s ? "-e use_proxy=yes #{p} #{s}" : nil
906
- end
907
-
908
- def export_http_proxy_parm
909
- http_proxy ? "export http_proxy=#{http_proxy}" : nil
910
- end
911
-
912
- def export_https_proxy_parm
913
- http_proxy ? "export https_proxy=#{http_proxy}" : nil
914
- end
915
-
916
- def http_proxy
917
- config[:http_proxy]
918
- end
919
-
920
- def https_proxy
921
- config[:https_proxy]
922
- end
923
-
924
- def chef_url
925
- config[:chef_bootstrap_url]
926
- end
927
-
928
- def prepare_manifests
929
- info('Preparing manifests')
930
- debug("Using manifests from #{manifests}")
931
-
932
- tmp_manifests_dir = File.join(sandbox_path, 'manifests')
933
- FileUtils.mkdir_p(tmp_manifests_dir)
934
- FileUtils.cp_r(Dir.glob("#{manifests}/*"), tmp_manifests_dir)
935
- end
936
-
937
- def prepare_files
938
- info('Preparing files')
939
- unless File.directory?(files)
940
- info 'nothing to do for files'
941
- return
942
- end
943
-
944
- debug("Using files from #{files}")
945
-
946
- tmp_files_dir = File.join(sandbox_path, 'files')
947
- FileUtils.mkdir_p(tmp_files_dir)
948
- FileUtils.cp_r(Dir.glob("#{files}/*"), tmp_files_dir)
949
- end
950
-
951
- def prepare_facter_file
952
- return unless config[:facter_file]
953
- info 'Copying facter file'
954
- facter_dir = File.join(sandbox_path, 'facter')
955
- FileUtils.mkdir_p(facter_dir)
956
- FileUtils.cp_r(config[:facter_file], facter_dir)
957
- end
958
-
959
- def prepare_facts
960
- return unless config[:install_custom_facts]
961
- return unless config[:custom_facts]
962
- info 'Installing custom facts'
963
- facter_dir = File.join(sandbox_path, 'facter')
964
- FileUtils.mkdir_p(facter_dir)
965
- tmp_facter_file = File.join(facter_dir, 'kitchen.rb')
966
- facter_facts = Hash[config[:custom_facts].map { |k, v| [k.to_s, v.to_s] }]
967
- File.open(tmp_facter_file, 'a') do |out|
968
- facter_facts.each do |k, v|
969
- out.write "\nFacter.add(:#{k}) do\n"
970
- out.write " setcode do\n"
971
- out.write " \"#{v}\"\n"
972
- out.write " end\n"
973
- out.write "end\n"
974
- end
975
- end
976
- end
977
-
978
- def prepare_modules
979
- info('Preparing modules')
980
-
981
- FileUtils.mkdir_p(tmpmodules_dir)
982
- resolve_with_librarian if File.exist?(puppetfile) && config[:resolve_with_librarian_puppet]
983
-
984
- if modules && modules.include?(':')
985
- debug('Found multiple directories in module path merging.....')
986
- modules_array = modules.split(':')
987
- modules_array.each do |m|
988
- if File.directory?(m)
989
- debug("Copying modules from #{m} to #{tmpmodules_dir}")
990
- FileUtils.cp_r(Dir.glob("#{m}/*"), tmpmodules_dir, remove_destination: true)
991
- end
992
- end
993
- elsif modules && File.directory?(modules)
994
- debug("Copying modules from #{modules} to #{tmpmodules_dir}")
995
- FileUtils.cp_r(Dir.glob("#{modules}/*"), tmpmodules_dir, remove_destination: true)
996
- else
997
- info 'nothing to do for modules'
998
- end
999
-
1000
- copy_self_as_module
1001
- end
1002
-
1003
- def copy_self_as_module
1004
- if File.exist?(modulefile)
1005
- warn('Modulefile found but this is depricated, ignoring it, see https://tickets.puppetlabs.com/browse/PUP-1188')
1006
- end
1007
-
1008
- return unless File.exist?(metadata_json)
1009
- module_name = nil
1010
- begin
1011
- module_name = JSON.parse(IO.read(metadata_json))['name'].split('-').last
1012
- rescue
1013
- error("not able to load or parse #{metadata_json_path} for the name of the module")
1014
- end
1015
-
1016
- return unless module_name
1017
- module_target_path = File.join(sandbox_path, 'modules', module_name)
1018
- FileUtils.mkdir_p(module_target_path)
1019
-
1020
- excluded_paths = %w(modules spec pkg) + config[:ignored_paths_from_root]
1021
-
1022
- FileUtils.cp_r(
1023
- Dir.glob(File.join(config[:kitchen_root], '*')).reject { |entry| entry =~ /#{excluded_paths.join('$|')}$/ },
1024
- module_target_path,
1025
- remove_destination: true
1026
- )
1027
- end
1028
-
1029
- def prepare_puppet_config
1030
- return unless puppet_config
1031
-
1032
- info('Preparing puppet.conf')
1033
- debug("Using puppet config from #{puppet_config}")
1034
-
1035
- FileUtils.cp_r(puppet_config, File.join(sandbox_path, 'puppet.conf'))
1036
- end
1037
-
1038
- def prepare_enc
1039
- return unless config[:puppet_enc]
1040
- info 'Copying enc file'
1041
- enc_dir = File.join(sandbox_path, 'enc')
1042
- FileUtils.mkdir_p(enc_dir)
1043
- FileUtils.cp_r(config[:puppet_enc], File.join(enc_dir, '/'))
1044
- end
1045
-
1046
- def prepare_hiera_config
1047
- return unless hiera_config
1048
-
1049
- info('Preparing hiera')
1050
- debug("Using hiera from #{hiera_config}")
1051
-
1052
- FileUtils.cp_r(hiera_config, File.join(sandbox_path, 'hiera.yaml'))
1053
- end
1054
-
1055
- def prepare_fileserver_config
1056
- return unless fileserver_config
1057
-
1058
- info('Preparing fileserver')
1059
- debug("Using fileserver config from #{fileserver_config}")
1060
-
1061
- FileUtils.cp_r(fileserver_config, File.join(sandbox_path, 'fileserver.conf'))
1062
- end
1063
-
1064
- def prepare_hiera_data
1065
- return unless hiera_data
1066
- info('Preparing hiera data')
1067
- tmp_hiera_dir = File.join(sandbox_path, 'hiera')
1068
- debug("Copying hiera data from #{hiera_data} to #{tmp_hiera_dir}")
1069
- FileUtils.mkdir_p(tmp_hiera_dir)
1070
- FileUtils.cp_r(Dir.glob("#{hiera_data}/*"), tmp_hiera_dir)
1071
- return unless hiera_eyaml_key_path
1072
- tmp_hiera_key_dir = File.join(sandbox_path, 'hiera_keys')
1073
- debug("Copying hiera eyaml keys from #{hiera_eyaml_key_path} to #{tmp_hiera_key_dir}")
1074
- FileUtils.mkdir_p(tmp_hiera_key_dir)
1075
- FileUtils.cp_r(Dir.glob("#{hiera_eyaml_key_path}/*"), tmp_hiera_key_dir)
1076
- end
1077
-
1078
- def prepare_spec_files
1079
- return unless spec_files_path
1080
- info('Preparing spec files')
1081
- tmp_spec_dir = File.join(sandbox_path, 'spec')
1082
- debug("Copying specs from #{spec_files_path} to #{tmp_spec_dir}")
1083
- FileUtils.mkdir_p(tmp_spec_dir)
1084
- FileUtils.cp_r(Dir.glob(File.join(spec_files_path, '*')).reject { |entry| entry =~ /fixtures$/ }, tmp_spec_dir) if config[:ignore_spec_fixtures]
1085
- FileUtils.cp_r(Dir.glob("#{spec_files_path}/*"), tmp_spec_dir) unless config[:ignore_spec_fixtures]
1086
- end
1087
-
1088
- def resolve_with_librarian
1089
- Kitchen.mutex.synchronize do
1090
- ENV['SSL_CERT_FILE'] = librarian_puppet_ssl_file if librarian_puppet_ssl_file
1091
- Puppet::Librarian.new(puppetfile, tmpmodules_dir, logger).resolve
1092
- ENV['SSL_CERT_FILE'] = '' if librarian_puppet_ssl_file
1093
- end
1094
- end
1095
- end
1096
- end
1097
- end
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Chris Lundquist (<chris.lundquist@github.com>) Neill Turner (<neillwturner@gmail.com>)
4
+ #
5
+ # Copyright (C) 2013,2014 Chris Lundquist, Neill Turner
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ # See https://github.com/neillturner/kitchen-puppet/blob/master/provisioner_options.md
20
+ # for documentation configuration parameters with puppet_apply provisioner.
21
+ #
22
+
23
+ require 'uri'
24
+ require 'json'
25
+ require 'kitchen'
26
+ require 'kitchen/provisioner/puppet/librarian'
27
+
28
+ module Kitchen
29
+ class Busser
30
+ def non_suite_dirs
31
+ %w(data data_bags environments nodes roles puppet)
32
+ end
33
+ end
34
+
35
+ module Configurable
36
+ def platform_name
37
+ instance.platform.name
38
+ end
39
+ end
40
+
41
+ module Provisioner
42
+ #
43
+ # Puppet Apply provisioner.
44
+ #
45
+ class PuppetApply < Base
46
+ attr_accessor :tmp_dir
47
+
48
+ default_config :require_puppet_collections, false
49
+ default_config :puppet_yum_collections_repo, 'http://yum.puppetlabs.com/puppetlabs-release-pc1-el-6.noarch.rpm'
50
+ default_config :puppet_apt_collections_repo, 'http://apt.puppetlabs.com/puppetlabs-release-pc1-wheezy.deb'
51
+ default_config :puppet_coll_remote_path, '/opt/puppetlabs'
52
+ default_config :puppet_version, nil
53
+ default_config :facter_version, nil
54
+ default_config :hiera_version, nil
55
+ default_config :install_hiera, false
56
+ default_config :hiera_package, 'hiera-puppet'
57
+ default_config :require_puppet_repo, true
58
+ default_config :require_chef_for_busser, true
59
+ default_config :resolve_with_librarian_puppet, true
60
+ default_config :puppet_environment, nil
61
+ default_config :puppet_apt_repo, 'http://apt.puppetlabs.com/puppetlabs-release-precise.deb'
62
+ default_config :puppet_yum_repo, 'https://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm'
63
+ default_config :chef_bootstrap_url, 'https://www.getchef.com/chef/install.sh'
64
+ default_config :puppet_logdest, nil
65
+ default_config :custom_install_command, nil
66
+ default_config :custom_pre_install_command, nil
67
+ default_config :puppet_whitelist_exit_code, nil
68
+ default_config :require_puppet_omnibus, false
69
+ default_config :puppet_omnibus_url, 'https://raw.githubusercontent.com/petems/puppet-install-shell/master/install_puppet.sh'
70
+ default_config :puppet_enc, nil
71
+ default_config :ignore_spec_fixtures, false
72
+
73
+ default_config :puppet_apply_command, nil
74
+
75
+ default_config :puppet_git_init, nil
76
+ default_config :puppet_git_pr, nil
77
+
78
+ default_config :http_proxy, nil
79
+ default_config :https_proxy, nil
80
+
81
+ default_config :ignored_paths_from_root, []
82
+ default_config :hiera_data_remote_path, '/var/lib/hiera'
83
+ default_config :manifest, 'site.pp'
84
+
85
+ default_config :manifests_path do |provisioner|
86
+ provisioner.calculate_path('manifests') ||
87
+ raise('No manifests_path detected. Please specify one in .kitchen.yml')
88
+ end
89
+
90
+ default_config :modules_path do |provisioner|
91
+ modules_path = provisioner.calculate_path('modules')
92
+ if modules_path.nil? && provisioner.calculate_path('Puppetfile', :file).nil?
93
+ raise('No modules_path detected. Please specify one in .kitchen.yml')
94
+ end
95
+ modules_path
96
+ end
97
+
98
+ default_config :files_path do |provisioner|
99
+ provisioner.calculate_path('files') || 'files'
100
+ end
101
+
102
+ default_config :hiera_data_path do |provisioner|
103
+ provisioner.calculate_path('hiera')
104
+ end
105
+
106
+ default_config :puppet_config_path do |provisioner|
107
+ provisioner.calculate_path('puppet.conf', :file)
108
+ end
109
+
110
+ default_config :hiera_config_path do |provisioner|
111
+ provisioner.calculate_path('hiera.yaml', :file)
112
+ end
113
+
114
+ default_config :fileserver_config_path do |provisioner|
115
+ provisioner.calculate_path('fileserver.conf', :file)
116
+ end
117
+ default_config :puppetfile_path do |provisioner|
118
+ provisioner.calculate_path('Puppetfile', :file)
119
+ end
120
+
121
+ default_config :modulefile_path do |provisioner|
122
+ provisioner.calculate_path('Modulefile', :file)
123
+ end
124
+
125
+ default_config :metadata_json_path do |provisioner|
126
+ provisioner.calculate_path('metadata.json', :file)
127
+ end
128
+
129
+ default_config :manifests_path do |provisioner|
130
+ provisioner.calculate_path('manifests', :directory)
131
+ end
132
+
133
+ default_config :spec_files_path do |provisioner|
134
+ provisioner.calculate_path('spec', :directory)
135
+ end
136
+
137
+ default_config :spec_files_remote_path, '/etc/puppet/spec'
138
+
139
+ default_config :puppet_debug, false
140
+ default_config :puppet_verbose, false
141
+ default_config :puppet_noop, false
142
+ default_config :platform, &:platform_name
143
+ default_config :update_package_repos, true
144
+ default_config :remove_puppet_repo, false
145
+ default_config :install_custom_facts, false
146
+ default_config :custom_facts, {}
147
+ default_config :facterlib, nil
148
+ default_config :puppet_detailed_exitcodes, nil
149
+ default_config :facter_file, nil
150
+ default_config :librarian_puppet_ssl_file, nil
151
+
152
+ default_config :hiera_eyaml, false
153
+ default_config :hiera_eyaml_key_remote_path, '/etc/puppet/secure/keys'
154
+
155
+ default_config :hiera_eyaml_key_path do |provisioner|
156
+ provisioner.calculate_path('hiera_keys')
157
+ end
158
+
159
+ default_config :hiera_deep_merge, false
160
+ default_config :puppet_no_sudo, false
161
+
162
+ def calculate_path(path, type = :directory)
163
+ base = config[:test_base_path]
164
+ candidates = []
165
+ candidates << File.join(base, instance.suite.name, 'puppet', path)
166
+ candidates << File.join(base, instance.suite.name, path)
167
+ candidates << File.join(base, path)
168
+ candidates << File.join(Dir.pwd, path)
169
+
170
+ candidates.find do |c|
171
+ type == :directory ? File.directory?(c) : File.file?(c)
172
+ end
173
+ end
174
+
175
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
176
+ def install_command
177
+ return unless config[:require_puppet_collections] || config[:require_puppet_repo] || config[:require_puppet_omnibus]
178
+ if config[:require_puppet_omnibus]
179
+ install_omnibus_command
180
+ elsif config[:require_puppet_collections]
181
+ install_command_collections
182
+ else
183
+ case puppet_platform
184
+ when 'debian', 'ubuntu'
185
+ info("Installing puppet on #{config[:platform]}")
186
+ # need to add a CR to avoid trouble with proxy settings concatenation
187
+ <<-INSTALL
188
+
189
+ #{custom_pre_install_command}
190
+ if [ ! $(which puppet) ]; then
191
+ #{sudo('apt-get')} -y install wget
192
+ #{sudo('wget')} #{wget_proxy_parm} #{puppet_apt_repo}
193
+ #{sudo('dpkg')} -i #{puppet_apt_repo_file}
194
+ #{update_packages_debian_cmd}
195
+ #{sudo_env('apt-get')} -y install facter#{facter_debian_version}
196
+ #{sudo_env('apt-get')} -y install puppet-common#{puppet_debian_version}
197
+ #{sudo_env('apt-get')} -y install puppet#{puppet_debian_version}
198
+ #{install_hiera}
199
+ fi
200
+ #{install_eyaml}
201
+ #{install_deep_merge}
202
+ #{install_busser}
203
+ #{custom_install_command}
204
+ INSTALL
205
+ when 'redhat', 'centos', 'fedora', 'oracle', 'amazon'
206
+ info("Installing puppet from yum on #{puppet_platform}")
207
+ # need to add a CR to avoid trouble with proxy settings concatenation
208
+ <<-INSTALL
209
+
210
+ #{custom_pre_install_command}
211
+ if [ ! $(which puppet) ]; then
212
+ #{install_puppet_yum_repo}
213
+ fi
214
+ #{install_eyaml}
215
+ #{install_deep_merge}
216
+ #{install_busser}
217
+ #{custom_install_command}
218
+ INSTALL
219
+ else
220
+ info('Installing puppet, will try to determine platform os')
221
+ # need to add a CR to avoid trouble with proxy settings concatenation
222
+ <<-INSTALL
223
+
224
+ #{custom_pre_install_command}
225
+ if [ ! $(which puppet) ]; then
226
+ if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ] || [ -f /etc/oracle-release ]; then
227
+ #{install_puppet_yum_repo}
228
+ else
229
+ if [ -f /etc/system-release ] || [ grep -q 'Amazon Linux' /etc/system-release ]; then
230
+ #{install_puppet_yum_repo}
231
+ else
232
+ #{sudo('apt-get')} -y install wget
233
+ #{sudo('wget')} #{wget_proxy_parm} #{puppet_apt_repo}
234
+ #{sudo('dpkg')} -i #{puppet_apt_repo_file}
235
+ #{update_packages_debian_cmd}
236
+ #{sudo_env('apt-get')} -y install facter#{facter_debian_version}
237
+ #{sudo_env('apt-get')} -y install puppet-common#{puppet_debian_version}
238
+ #{sudo_env('apt-get')} -y install puppet#{puppet_debian_version}
239
+ #{install_hiera}
240
+ fi
241
+ fi
242
+ fi
243
+ #{install_eyaml}
244
+ #{install_deep_merge}
245
+ #{install_busser}
246
+ #{custom_install_command}
247
+ INSTALL
248
+ end
249
+ end
250
+ end
251
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
252
+
253
+ def install_command_collections
254
+ case puppet_platform
255
+ when 'debian', 'ubuntu'
256
+ info("Installing Puppet Collections on #{puppet_platform}")
257
+ <<-INSTALL
258
+
259
+ #{Util.shell_helpers}
260
+ #{custom_pre_install_command}
261
+ if [ ! -d "#{config[:puppet_coll_remote_path]}" ]; then
262
+ if [ ! -f "#{config[:puppet_apt_collections_repo]}" ]; then
263
+ #{sudo('apt-get')} -y install wget
264
+ #{sudo('wget')} #{wget_proxy_parm} #{config[:puppet_apt_collections_repo]}
265
+ fi
266
+ #{sudo('dpkg')} -i #{puppet_apt_coll_repo_file}
267
+ #{sudo('apt-get')} update
268
+ #{sudo_env('apt-get')} -y install puppet-agent#{puppet_debian_version}
269
+ fi
270
+ #{install_eyaml("#{config[:puppet_coll_remote_path]}/puppet/bin/gem")}
271
+ #{install_deep_merge}
272
+ #{install_busser}
273
+ #{custom_install_command}
274
+ INSTALL
275
+ when 'redhat', 'centos', 'fedora', 'oracle', 'amazon'
276
+ info("Installing Puppet Collections on #{puppet_platform}")
277
+ <<-INSTALL
278
+
279
+ #{Util.shell_helpers}
280
+ if [ ! -d "#{config[:puppet_coll_remote_path]}" ]; then
281
+ echo "-----> #{sudo_env('yum')} -y localinstall #{config[:puppet_yum_collections_repo]}"
282
+ #{sudo_env('yum')} -y localinstall #{config[:puppet_yum_collections_repo]}
283
+ #{sudo_env('yum')} -y install puppet-agent#{puppet_redhat_version}
284
+ fi
285
+ #{install_eyaml("#{config[:puppet_coll_remote_path]}/puppet/bin/gem")}
286
+ #{install_deep_merge}
287
+ #{install_busser}
288
+ #{custom_install_command}
289
+ INSTALL
290
+ else
291
+ info('Installing Puppet Collections, will try to determine platform os')
292
+ <<-INSTALL
293
+
294
+ #{Util.shell_helpers}
295
+ #{custom_pre_install_command}
296
+ if [ ! -d "#{config[:puppet_coll_remote_path]}" ]; then
297
+ if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ] || [ -f /etc/oracle-release ] || \
298
+ [ -f /etc/system-release ] || [ grep -q 'Amazon Linux' /etc/system-release ]; then
299
+ echo "-----> #{sudo_env('yum')} -y localinstall #{config[:puppet_yum_collections_repo]}"
300
+ #{sudo_env('yum')} -y localinstall #{config[:puppet_yum_collections_repo]}
301
+ #{sudo_env('yum')} -y install puppet-agent#{puppet_redhat_version}
302
+ else
303
+ #{sudo('apt-get')} -y install wget
304
+ #{sudo('wget')} #{wget_proxy_parm} #{config[:puppet_apt_collections_repo]}
305
+ #{sudo('dpkg')} -i #{puppet_apt_coll_repo_file}
306
+ #{sudo('apt-get')} update
307
+ #{sudo_env('apt-get')} -y install puppet-agent#{puppet_debian_version}
308
+ fi
309
+ fi
310
+ #{install_eyaml("#{config[:puppet_coll_remote_path]}/puppet/bin/gem")}
311
+ #{install_deep_merge}
312
+ #{install_busser}
313
+ #{custom_install_command}
314
+ INSTALL
315
+ end
316
+ end
317
+
318
+ def install_deep_merge
319
+ return unless config[:hiera_deep_merge]
320
+ <<-INSTALL
321
+ # Support for hash merge lookups to recursively merge hash keys
322
+ if [[ $(#{sudo('gem')} list deep_merge -i) == 'false' ]]; then
323
+ echo '-----> Installing deep_merge to provide deep_merge of hiera hashes'
324
+ #{sudo('gem')} install #{gem_proxy_parm} --no-ri --no-rdoc deep_merge
325
+ fi
326
+ INSTALL
327
+ end
328
+
329
+ def install_eyaml(gem_cmd = 'gem')
330
+ return unless config[:hiera_eyaml]
331
+ <<-INSTALL
332
+ # A backend for Hiera that provides per-value asymmetric encryption of sensitive data
333
+ if [[ $(#{sudo(gem_cmd)} list hiera-eyaml -i) == 'false' ]]; then
334
+ echo '-----> Installing hiera-eyaml to provide encryption of hiera data'
335
+ #{sudo(gem_cmd)} install #{gem_proxy_parm} --no-ri --no-rdoc highline -v 1.6.21
336
+ #{sudo(gem_cmd)} install #{gem_proxy_parm} --no-ri --no-rdoc hiera-eyaml
337
+ fi
338
+ INSTALL
339
+ end
340
+
341
+ def install_busser
342
+ return unless config[:require_chef_for_busser]
343
+ <<-INSTALL
344
+ #{Util.shell_helpers}
345
+ # install chef omnibus so that busser works as this is needed to run tests :(
346
+ # TODO: work out how to install enough ruby
347
+ # and set busser: { :ruby_bindir => '/usr/bin/ruby' } so that we dont need the
348
+ # whole chef client
349
+ if [ ! -d "/opt/chef" ]
350
+ then
351
+ echo '-----> Installing Chef Omnibus to install busser to run tests'
352
+ #{export_http_proxy_parm}
353
+ #{export_https_proxy_parm}
354
+ do_download #{chef_url} /tmp/install.sh
355
+ #{sudo('sh')} /tmp/install.sh
356
+ fi
357
+ INSTALL
358
+ end
359
+
360
+ def install_omnibus_command
361
+ info('Installing puppet using puppet omnibus')
362
+
363
+ version = ''
364
+ version = "-v #{config[:puppet_version]}" unless config[:puppet_version].nil?
365
+
366
+ <<-INSTALL
367
+ #{Util.shell_helpers}
368
+ if [ ! $(which puppet) ]; then
369
+ echo "-----> Installing Puppet Omnibus"
370
+ #{export_http_proxy_parm}
371
+ #{export_https_proxy_parm}
372
+ do_download #{config[:puppet_omnibus_url]} /tmp/install_puppet.sh
373
+ #{sudo_env('sh')} /tmp/install_puppet.sh #{version}
374
+ fi
375
+ INSTALL
376
+ end
377
+
378
+ def install_hiera
379
+ return unless config[:install_hiera]
380
+ <<-INSTALL
381
+ #{sudo_env('apt-get')} -y install #{hiera_package}
382
+ INSTALL
383
+ end
384
+
385
+ def hiera_package
386
+ "#{config[:hiera_package]}#{puppet_hiera_debian_version}"
387
+ end
388
+
389
+ # /bin/wget -P /etc/pki/rpm-gpg/ http://yum.puppetlabs.com/RPM-GPG-KEY-puppetlabs
390
+ # changed to curl
391
+
392
+ def install_puppet_yum_repo
393
+ <<-INSTALL
394
+ rhelversion=$(cat /etc/redhat-release | grep 'release 7')
395
+ # For CentOS7/RHEL7 the rdo release contains puppetlabs repo, creating conflict. Create temp-repo
396
+ #{sudo_env('curl')} -o /etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs http://yum.puppetlabs.com/RPM-GPG-KEY-puppetlabs
397
+ if [ -n "$rhelversion" ]; then
398
+ echo '[puppettemp-products]
399
+ name=Puppet Labs Products - \$basearch
400
+ baseurl=http://yum.puppetlabs.com/el/7/products/\$basearch
401
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
402
+ enabled=0
403
+ gpgcheck=1
404
+ [puppettemp-deps]
405
+ name=Puppet Labs Dependencies - \$basearch
406
+ baseurl=http://yum.puppetlabs.com/el/7/dependencies/\$basearch
407
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
408
+ enabled=0
409
+ gpgcheck=1' | sudo tee /etc/yum.repos.d/puppettemp.repo > /dev/null
410
+ sudo sed -i 's/^[ \t]*//' /etc/yum.repos.d/puppettemp.repo
411
+ #{update_packages_redhat_cmd}
412
+ #{sudo_env('yum')} -y --enablerepo=puppettemp-products --enablerepo=puppettemp-deps install puppet#{puppet_redhat_version}
413
+ # Clean up temporary puppet repo
414
+ sudo rm -rf /etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
415
+ sudo rm -rf /etc/yum.repos.d/puppettemp.repo
416
+ else
417
+ #{sudo('rpm')} -ivh #{proxy_parm} #{puppet_yum_repo}
418
+ #{update_packages_redhat_cmd}
419
+ #{sudo_env('yum')} -y install puppet#{puppet_redhat_version}
420
+ fi
421
+ INSTALL
422
+ end
423
+
424
+ def custom_pre_install_command
425
+ <<-INSTALL
426
+ #{config[:custom_pre_install_command]}
427
+ INSTALL
428
+ end
429
+
430
+ def custom_install_command
431
+ <<-INSTALL
432
+ #{config[:custom_install_command]}
433
+ INSTALL
434
+ end
435
+
436
+ def init_command
437
+ dirs = %w(modules manifests files hiera hiera.yaml facter spec enc)
438
+ .map { |dir| File.join(config[:root_path], dir) }.join(' ')
439
+ cmd = "#{sudo('rm')} -rf #{dirs} #{hiera_data_remote_path} \
440
+ /etc/hiera.yaml #{puppet_dir}/hiera.yaml \
441
+ #{spec_files_remote_path} \
442
+ #{puppet_dir}/fileserver.conf;"
443
+ cmd += config[:puppet_environment] ? "#{sudo('rm')} -f #{File.join(puppet_dir, config[:puppet_environment])};" : ''
444
+ cmd += " mkdir -p #{config[:root_path]}; #{sudo('mkdir')} -p #{puppet_dir}"
445
+ debug(cmd)
446
+ cmd
447
+ end
448
+
449
+ def create_sandbox
450
+ super
451
+ debug("Creating local sandbox in #{sandbox_path}")
452
+ yield if block_given?
453
+ prepare_modules
454
+ prepare_manifests
455
+ prepare_files
456
+ prepare_facter_file
457
+ prepare_facts
458
+ prepare_puppet_config
459
+ prepare_hiera_config
460
+ prepare_fileserver_config
461
+ prepare_hiera_data
462
+ prepare_enc
463
+ prepare_spec_files
464
+ info('Finished Preparing files for transfer')
465
+ end
466
+
467
+ def cleanup_sandbox
468
+ return if sandbox_path.nil?
469
+ debug("Cleaning up local sandbox in #{sandbox_path}")
470
+ FileUtils.rmtree(sandbox_path)
471
+ return if remove_repo.nil?
472
+ debug("Cleaning up remote sandbox: #{remove_repo}")
473
+ instance.remote_exec remove_repo
474
+ end
475
+
476
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
477
+ def prepare_command
478
+ commands = []
479
+ if puppet_git_init
480
+ commands << [
481
+ sudo('rm -rf'), '/etc/puppet'
482
+ ].join(' ')
483
+
484
+ commands << [
485
+ sudo('git clone'), puppet_git_init, '/etc/puppet'
486
+ ].join(' ')
487
+ end
488
+
489
+ if puppet_git_pr
490
+ commands << [
491
+ sudo('git'),
492
+ '--git-dir=/etc/puppet/.git/',
493
+ 'fetch -f',
494
+ 'origin',
495
+ "pull/#{puppet_git_pr}/head:pr_#{puppet_git_pr}"
496
+ ].join(' ')
497
+
498
+ commands << [
499
+ sudo('git'),
500
+ '--git-dir=/etc/puppet/.git/',
501
+ '--work-tree=/etc/puppet/',
502
+ 'checkout',
503
+ "pr_#{puppet_git_pr}"
504
+ ].join(' ')
505
+ end
506
+
507
+ if puppet_config
508
+ commands << [
509
+ sudo('cp'),
510
+ File.join(config[:root_path], 'puppet.conf'),
511
+ puppet_dir
512
+ ].join(' ')
513
+ end
514
+
515
+ if hiera_config
516
+ commands << [
517
+ sudo('cp'), File.join(config[:root_path], 'hiera.yaml'), '/etc/'
518
+ ].join(' ')
519
+
520
+ commands << [
521
+ sudo('cp'), File.join(config[:root_path], 'hiera.yaml'), hiera_config_dir
522
+ ].join(' ')
523
+ end
524
+
525
+ if fileserver_config
526
+ commands << [
527
+ sudo('cp'),
528
+ File.join(config[:root_path], 'fileserver.conf'),
529
+ puppet_dir
530
+ ].join(' ')
531
+ end
532
+
533
+ if hiera_data && hiera_data_remote_path == '/var/lib/hiera'
534
+ commands << [
535
+ sudo('cp -r'), File.join(config[:root_path], 'hiera'), '/var/lib/'
536
+ ].join(' ')
537
+ end
538
+
539
+ if hiera_data && hiera_data_remote_path != '/var/lib/hiera'
540
+ commands << [
541
+ sudo('mkdir -p'), hiera_data_remote_path
542
+ ].join(' ')
543
+ commands << [
544
+ sudo('cp -r'), File.join(config[:root_path], 'hiera/*'), hiera_data_remote_path
545
+ ].join(' ')
546
+ end
547
+
548
+ if hiera_eyaml
549
+ commands << [
550
+ sudo('mkdir -p'), hiera_eyaml_key_remote_path
551
+ ].join(' ')
552
+ commands << [
553
+ sudo('cp -r'), File.join(config[:root_path], 'hiera_keys/*'), hiera_eyaml_key_remote_path
554
+ ].join(' ')
555
+ end
556
+
557
+ if puppet_environment
558
+ commands << [
559
+ sudo('ln -s '), config[:root_path], File.join(puppet_dir, config[:puppet_environment])
560
+ ].join(' ')
561
+ end
562
+
563
+ if spec_files_path && spec_files_remote_path
564
+ commands << [
565
+ sudo('mkdir -p'), spec_files_remote_path
566
+ ].join(' ')
567
+ commands << [
568
+ sudo('cp -r'), File.join(config[:root_path], 'spec/*'), spec_files_remote_path
569
+ ].join(' ')
570
+ end
571
+
572
+ if config[:puppet_enc]
573
+ commands << [
574
+ sudo('chmod 755'), File.join("#{config[:root_path]}/enc", File.basename(config[:puppet_enc]))
575
+ ].join(' ')
576
+ end
577
+
578
+ command = commands.join(' && ')
579
+ debug(command)
580
+ command
581
+ end
582
+
583
+ def run_command
584
+ if !config[:puppet_apply_command].nil?
585
+ return config[:puppet_apply_command]
586
+ else
587
+ result = [
588
+ facterlib,
589
+ custom_facts,
590
+ puppet_manifestdir,
591
+ puppet_cmd,
592
+ 'apply',
593
+ File.join(config[:root_path], 'manifests', manifest),
594
+ "--modulepath=#{File.join(config[:root_path], 'modules')}",
595
+ "--fileserverconfig=#{File.join(config[:root_path], 'fileserver.conf')}",
596
+ custom_options,
597
+ puppet_environment_flag,
598
+ puppet_noop_flag,
599
+ puppet_enc_flag,
600
+ puppet_detailed_exitcodes_flag,
601
+ puppet_verbose_flag,
602
+ puppet_debug_flag,
603
+ puppet_logdest_flag,
604
+ puppet_whitelist_exit_code
605
+ ].join(' ')
606
+ info("Going to invoke puppet apply with: #{result}")
607
+ result
608
+ end
609
+ end
610
+
611
+ protected
612
+
613
+ def load_needed_dependencies!
614
+ return unless File.exist?(puppetfile)
615
+ return unless config[:resolve_with_librarian_puppet]
616
+ debug("Puppetfile found at #{puppetfile}, loading Librarian-Puppet")
617
+ Puppet::Librarian.load!(logger)
618
+ end
619
+
620
+ def tmpmodules_dir
621
+ File.join(sandbox_path, 'modules')
622
+ end
623
+
624
+ def puppetfile
625
+ config[:puppetfile_path] || ''
626
+ end
627
+
628
+ def modulefile
629
+ config[:modulefile_path] || ''
630
+ end
631
+
632
+ def metadata_json
633
+ config[:metadata_json_path] || ''
634
+ end
635
+
636
+ def manifest
637
+ config[:manifest]
638
+ end
639
+
640
+ def manifests
641
+ config[:manifests_path]
642
+ end
643
+
644
+ def modules
645
+ config[:modules_path]
646
+ end
647
+
648
+ def files
649
+ config[:files_path] || 'files'
650
+ end
651
+
652
+ def puppet_config
653
+ config[:puppet_config_path]
654
+ end
655
+
656
+ def puppet_environment
657
+ config[:puppet_environment]
658
+ end
659
+
660
+ def puppet_git_init
661
+ config[:puppet_git_init]
662
+ end
663
+
664
+ def puppet_git_pr
665
+ config[:puppet_git_pr]
666
+ end
667
+
668
+ def hiera_config
669
+ config[:hiera_config_path]
670
+ end
671
+
672
+ def fileserver_config
673
+ config[:fileserver_config_path]
674
+ end
675
+
676
+ def hiera_data
677
+ config[:hiera_data_path]
678
+ end
679
+
680
+ def hiera_data_remote_path
681
+ config[:hiera_data_remote_path]
682
+ end
683
+
684
+ def hiera_eyaml
685
+ config[:hiera_eyaml]
686
+ end
687
+
688
+ def hiera_eyaml_key_path
689
+ config[:hiera_eyaml_key_path]
690
+ end
691
+
692
+ def hiera_eyaml_key_remote_path
693
+ config[:hiera_eyaml_key_remote_path]
694
+ end
695
+
696
+ def hiera_deep_merge
697
+ config[:hiera_deep_merge]
698
+ end
699
+
700
+ def librarian_puppet_ssl_file
701
+ config[:librarian_puppet_ssl_file]
702
+ end
703
+
704
+ def puppet_cmd
705
+ puppet_bin = 'puppet'
706
+ if config[:require_puppet_collections]
707
+ puppet_bin = "#{config[:puppet_coll_remote_path]}/bin/puppet"
708
+ end
709
+
710
+ if config[:puppet_no_sudo]
711
+ puppet_bin
712
+ else
713
+ sudo_env(puppet_bin)
714
+ end
715
+ end
716
+
717
+ def puppet_dir
718
+ if config[:require_puppet_collections]
719
+ '/etc/puppetlabs/puppet'
720
+ else
721
+ '/etc/puppet'
722
+ end
723
+ end
724
+
725
+ def hiera_config_dir
726
+ if config[:require_puppet_collections]
727
+ '/etc/puppetlabs/code'
728
+ else
729
+ '/etc/puppet'
730
+ end
731
+ end
732
+
733
+ def puppet_debian_version
734
+ config[:puppet_version] ? "=#{config[:puppet_version]}" : nil
735
+ end
736
+
737
+ def facter_debian_version
738
+ config[:facter_version] ? "=#{config[:facter_version]}" : nil
739
+ end
740
+
741
+ def puppet_hiera_debian_version
742
+ config[:hiera_version] ? "=#{config[:hiera_version]}" : nil
743
+ end
744
+
745
+ def puppet_redhat_version
746
+ if puppet_platform == 'amazon'
747
+ config[:puppet_version]
748
+ else
749
+ config[:puppet_version] ? "-#{config[:puppet_version]}" : nil
750
+ end
751
+ end
752
+
753
+ def puppet_environment_flag
754
+ if config[:puppet_version] =~ /^2/
755
+ config[:puppet_environment] ? "--environment=#{config[:puppet_environment]}" : nil
756
+ else
757
+ config[:puppet_environment] ? "--environment=#{config[:puppet_environment]} --environmentpath=#{puppet_dir}" : nil
758
+ end
759
+ end
760
+
761
+ def puppet_manifestdir
762
+ return nil if config[:require_puppet_collections]
763
+ return nil if config[:puppet_environment]
764
+ bash_vars = "export MANIFESTDIR='#{File.join(config[:root_path], 'manifests')}';"
765
+ debug(bash_vars)
766
+ bash_vars
767
+ end
768
+
769
+ def custom_options
770
+ config[:custom_options] || ''
771
+ end
772
+
773
+ def puppet_noop_flag
774
+ config[:puppet_noop] ? '--noop' : nil
775
+ end
776
+
777
+ def puppet_debug_flag
778
+ config[:puppet_debug] ? '-d' : nil
779
+ end
780
+
781
+ def puppet_verbose_flag
782
+ config[:puppet_verbose] ? '-v' : nil
783
+ end
784
+
785
+ def puppet_logdest_flag
786
+ return nil unless config[:puppet_logdest]
787
+ destinations = ''
788
+ config[:puppet_logdest].each do |dest|
789
+ destinations << "--logdest #{dest} "
790
+ end
791
+ destinations
792
+ end
793
+
794
+ def puppet_platform
795
+ config[:platform].gsub(/-.*/, '')
796
+ end
797
+
798
+ def update_packages_debian_cmd
799
+ config[:update_package_repos] ? "#{sudo_env('apt-get')} update" : nil
800
+ end
801
+
802
+ def update_packages_redhat_cmd
803
+ # #{sudo('yum')}
804
+ config[:update_package_repos] ? "#{sudo_env('yum')} makecache" : nil
805
+ end
806
+
807
+ def sudo_env(pm)
808
+ s = https_proxy ? "https_proxy=#{https_proxy}" : nil
809
+ p = http_proxy ? "http_proxy=#{http_proxy}" : nil
810
+ p || s ? "#{sudo('env')} #{p} #{s} #{pm}" : sudo(pm).to_s
811
+ end
812
+
813
+ def remove_puppet_repo
814
+ config[:remove_puppet_repo]
815
+ end
816
+
817
+ def spec_files_path
818
+ config[:spec_files_path]
819
+ end
820
+
821
+ def spec_files_remote_path
822
+ config[:spec_files_remote_path]
823
+ end
824
+
825
+ def facterlib
826
+ factpath = nil
827
+ factpath = File.join(config[:root_path], 'facter').to_s if config[:install_custom_facts] && !config[:custom_facts].none?
828
+ factpath = File.join(config[:root_path], 'facter').to_s if config[:facter_file]
829
+ factpath = "#{factpath}:" if config[:facterlib] && !factpath.nil?
830
+ factpath = "#{factpath}#{config[:facterlib]}" if config[:facterlib]
831
+ return nil if factpath.nil?
832
+ bash_vars = "export FACTERLIB='#{factpath}';"
833
+ debug(bash_vars)
834
+ bash_vars
835
+ end
836
+
837
+ def custom_facts
838
+ return nil if config[:custom_facts].none?
839
+ return nil if config[:install_custom_facts]
840
+ bash_vars = config[:custom_facts].map { |k, v| "FACTER_#{k}=#{v}" }.join(' ')
841
+ bash_vars = "export #{bash_vars};"
842
+ debug(bash_vars)
843
+ bash_vars
844
+ end
845
+
846
+ def puppet_enc_flag
847
+ config[:puppet_enc] ? "--node_terminus=exec --external_nodes=#{config[:root_path]}/enc/#{File.basename(config[:puppet_enc])}" : nil
848
+ end
849
+
850
+ def puppet_detailed_exitcodes_flag
851
+ config[:puppet_detailed_exitcodes] ? '--detailed-exitcodes' : nil
852
+ end
853
+
854
+ def remove_repo
855
+ remove_puppet_repo ? "#{sudo('rm')} -rf /tmp/kitchen #{hiera_data_remote_path} #{hiera_eyaml_key_remote_path} #{puppet_dir}/* " : nil
856
+ end
857
+
858
+ def puppet_whitelist_exit_code
859
+ config[:puppet_whitelist_exit_code] ? "; [ $? -eq #{config[:puppet_whitelist_exit_code]} ] && exit 0" : nil
860
+ end
861
+
862
+ def puppet_apt_repo
863
+ platform_version = config[:platform].partition('-')[2]
864
+ case puppet_platform
865
+ when 'ubuntu'
866
+ case platform_version
867
+ when '14.10'
868
+ # Utopic Repo
869
+ 'https://apt.puppetlabs.com/puppetlabs-release-utopic.deb'
870
+ when '14.04'
871
+ # Trusty Repo
872
+ 'https://apt.puppetlabs.com/puppetlabs-release-trusty.deb'
873
+ when '12.04'
874
+ # Precise Repo
875
+ 'https://apt.puppetlabs.com/puppetlabs-release-precise.deb'
876
+ else
877
+ # Configured Repo
878
+ config[:puppet_apt_repo]
879
+ end
880
+ when 'debian'
881
+ case platform_version.gsub(/\..*/, '')
882
+ when '8'
883
+ # Debian Jessie
884
+ 'https://apt.puppetlabs.com/puppetlabs-release-jessie.deb'
885
+ when '7'
886
+ # Debian Wheezy
887
+ 'https://apt.puppetlabs.com/puppetlabs-release-wheezy.deb'
888
+ when '6'
889
+ # Debian Squeeze
890
+ 'https://apt.puppetlabs.com/puppetlabs-release-squeeze.deb'
891
+ else
892
+ # Configured Repo
893
+ config[:puppet_apt_repo]
894
+ end
895
+ else
896
+ debug("Apt repo detection failed with platform - #{config[:platform]}")
897
+ false
898
+ end
899
+ end
900
+
901
+ def puppet_apt_repo_file
902
+ puppet_apt_repo.split('/').last if puppet_apt_repo
903
+ end
904
+
905
+ def puppet_apt_coll_repo_file
906
+ config[:puppet_apt_collections_repo].split('/').last
907
+ end
908
+
909
+ def puppet_yum_repo
910
+ config[:puppet_yum_repo]
911
+ end
912
+
913
+ def proxy_parm
914
+ http_proxy ? "--httpproxy #{URI.parse(http_proxy).host.downcase} --httpport #{URI.parse(http_proxy).port} " : nil
915
+ end
916
+
917
+ def gem_proxy_parm
918
+ http_proxy ? "--http-proxy #{http_proxy}" : nil
919
+ end
920
+
921
+ def wget_proxy_parm
922
+ p = http_proxy ? "-e http_proxy=#{http_proxy}" : nil
923
+ s = https_proxy ? "-e https_proxy=#{https_proxy}" : nil
924
+ p || s ? "-e use_proxy=yes #{p} #{s}" : nil
925
+ end
926
+
927
+ def export_http_proxy_parm
928
+ http_proxy ? "export http_proxy=#{http_proxy}" : nil
929
+ end
930
+
931
+ def export_https_proxy_parm
932
+ http_proxy ? "export https_proxy=#{http_proxy}" : nil
933
+ end
934
+
935
+ def http_proxy
936
+ config[:http_proxy]
937
+ end
938
+
939
+ def https_proxy
940
+ config[:https_proxy]
941
+ end
942
+
943
+ def chef_url
944
+ config[:chef_bootstrap_url]
945
+ end
946
+
947
+ def prepare_manifests
948
+ info('Preparing manifests')
949
+ debug("Using manifests from #{manifests}")
950
+
951
+ tmp_manifests_dir = File.join(sandbox_path, 'manifests')
952
+ FileUtils.mkdir_p(tmp_manifests_dir)
953
+ FileUtils.cp_r(Dir.glob("#{manifests}/*"), tmp_manifests_dir)
954
+ end
955
+
956
+ def prepare_files
957
+ info('Preparing files')
958
+ unless File.directory?(files)
959
+ info 'nothing to do for files'
960
+ return
961
+ end
962
+
963
+ debug("Using files from #{files}")
964
+
965
+ tmp_files_dir = File.join(sandbox_path, 'files')
966
+ FileUtils.mkdir_p(tmp_files_dir)
967
+ FileUtils.cp_r(Dir.glob("#{files}/*"), tmp_files_dir)
968
+ end
969
+
970
+ def prepare_facter_file
971
+ return unless config[:facter_file]
972
+ info 'Copying facter file'
973
+ facter_dir = File.join(sandbox_path, 'facter')
974
+ FileUtils.mkdir_p(facter_dir)
975
+ FileUtils.cp_r(config[:facter_file], facter_dir)
976
+ end
977
+
978
+ def prepare_facts
979
+ return unless config[:install_custom_facts]
980
+ return unless config[:custom_facts]
981
+ info 'Installing custom facts'
982
+ facter_dir = File.join(sandbox_path, 'facter')
983
+ FileUtils.mkdir_p(facter_dir)
984
+ tmp_facter_file = File.join(facter_dir, 'kitchen.rb')
985
+ facter_facts = Hash[config[:custom_facts].map { |k, v| [k.to_s, v.to_s] }]
986
+ File.open(tmp_facter_file, 'a') do |out|
987
+ facter_facts.each do |k, v|
988
+ out.write "\nFacter.add(:#{k}) do\n"
989
+ out.write " setcode do\n"
990
+ out.write " \"#{v}\"\n"
991
+ out.write " end\n"
992
+ out.write "end\n"
993
+ end
994
+ end
995
+ end
996
+
997
+ def prepare_modules
998
+ info('Preparing modules')
999
+
1000
+ FileUtils.mkdir_p(tmpmodules_dir)
1001
+ resolve_with_librarian if File.exist?(puppetfile) && config[:resolve_with_librarian_puppet]
1002
+
1003
+ if modules && modules.include?(':')
1004
+ debug('Found multiple directories in module path merging.....')
1005
+ modules_array = modules.split(':')
1006
+ modules_array.each do |m|
1007
+ if File.directory?(m)
1008
+ debug("Copying modules from #{m} to #{tmpmodules_dir}")
1009
+ FileUtils.cp_r(Dir.glob("#{m}/*"), tmpmodules_dir, remove_destination: true)
1010
+ end
1011
+ end
1012
+ elsif modules && File.directory?(modules)
1013
+ debug("Copying modules from #{modules} to #{tmpmodules_dir}")
1014
+ FileUtils.cp_r(Dir.glob("#{modules}/*"), tmpmodules_dir, remove_destination: true)
1015
+ else
1016
+ info 'nothing to do for modules'
1017
+ end
1018
+
1019
+ copy_self_as_module
1020
+ end
1021
+
1022
+ def copy_self_as_module
1023
+ if File.exist?(modulefile)
1024
+ warn('Modulefile found but this is depricated, ignoring it, see https://tickets.puppetlabs.com/browse/PUP-1188')
1025
+ end
1026
+
1027
+ return unless File.exist?(metadata_json)
1028
+ module_name = nil
1029
+ begin
1030
+ module_name = JSON.parse(IO.read(metadata_json))['name'].split('-').last
1031
+ rescue
1032
+ error("not able to load or parse #{metadata_json_path} for the name of the module")
1033
+ end
1034
+
1035
+ return unless module_name
1036
+ module_target_path = File.join(sandbox_path, 'modules', module_name)
1037
+ FileUtils.mkdir_p(module_target_path)
1038
+
1039
+ excluded_paths = %w(modules spec pkg) + config[:ignored_paths_from_root]
1040
+
1041
+ FileUtils.cp_r(
1042
+ Dir.glob(File.join(config[:kitchen_root], '*')).reject { |entry| entry =~ /#{excluded_paths.join('$|')}$/ },
1043
+ module_target_path,
1044
+ remove_destination: true
1045
+ )
1046
+ end
1047
+
1048
+ def prepare_puppet_config
1049
+ return unless puppet_config
1050
+
1051
+ info('Preparing puppet.conf')
1052
+ debug("Using puppet config from #{puppet_config}")
1053
+
1054
+ FileUtils.cp_r(puppet_config, File.join(sandbox_path, 'puppet.conf'))
1055
+ end
1056
+
1057
+ def prepare_enc
1058
+ return unless config[:puppet_enc]
1059
+ info 'Copying enc file'
1060
+ enc_dir = File.join(sandbox_path, 'enc')
1061
+ FileUtils.mkdir_p(enc_dir)
1062
+ FileUtils.cp_r(config[:puppet_enc], File.join(enc_dir, '/'))
1063
+ end
1064
+
1065
+ def prepare_hiera_config
1066
+ return unless hiera_config
1067
+
1068
+ info('Preparing hiera')
1069
+ debug("Using hiera from #{hiera_config}")
1070
+
1071
+ FileUtils.cp_r(hiera_config, File.join(sandbox_path, 'hiera.yaml'))
1072
+ end
1073
+
1074
+ def prepare_fileserver_config
1075
+ return unless fileserver_config
1076
+
1077
+ info('Preparing fileserver')
1078
+ debug("Using fileserver config from #{fileserver_config}")
1079
+
1080
+ FileUtils.cp_r(fileserver_config, File.join(sandbox_path, 'fileserver.conf'))
1081
+ end
1082
+
1083
+ def prepare_hiera_data
1084
+ return unless hiera_data
1085
+ info('Preparing hiera data')
1086
+ tmp_hiera_dir = File.join(sandbox_path, 'hiera')
1087
+ debug("Copying hiera data from #{hiera_data} to #{tmp_hiera_dir}")
1088
+ FileUtils.mkdir_p(tmp_hiera_dir)
1089
+ FileUtils.cp_r(Dir.glob("#{hiera_data}/*"), tmp_hiera_dir)
1090
+ return unless hiera_eyaml_key_path
1091
+ tmp_hiera_key_dir = File.join(sandbox_path, 'hiera_keys')
1092
+ debug("Copying hiera eyaml keys from #{hiera_eyaml_key_path} to #{tmp_hiera_key_dir}")
1093
+ FileUtils.mkdir_p(tmp_hiera_key_dir)
1094
+ FileUtils.cp_r(Dir.glob("#{hiera_eyaml_key_path}/*"), tmp_hiera_key_dir)
1095
+ end
1096
+
1097
+ def prepare_spec_files
1098
+ return unless spec_files_path
1099
+ info('Preparing spec files')
1100
+ tmp_spec_dir = File.join(sandbox_path, 'spec')
1101
+ debug("Copying specs from #{spec_files_path} to #{tmp_spec_dir}")
1102
+ FileUtils.mkdir_p(tmp_spec_dir)
1103
+ FileUtils.cp_r(Dir.glob(File.join(spec_files_path, '*')).reject { |entry| entry =~ /fixtures$/ }, tmp_spec_dir) if config[:ignore_spec_fixtures]
1104
+ FileUtils.cp_r(Dir.glob("#{spec_files_path}/*"), tmp_spec_dir) unless config[:ignore_spec_fixtures]
1105
+ end
1106
+
1107
+ def resolve_with_librarian
1108
+ Kitchen.mutex.synchronize do
1109
+ ENV['SSL_CERT_FILE'] = librarian_puppet_ssl_file if librarian_puppet_ssl_file
1110
+ Puppet::Librarian.new(puppetfile, tmpmodules_dir, logger).resolve
1111
+ ENV['SSL_CERT_FILE'] = '' if librarian_puppet_ssl_file
1112
+ end
1113
+ end
1114
+ end
1115
+ end
1116
+ end