puppet_litmus 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 33763c6946158b131037d7d28f96b7db4ae5b924
4
- data.tar.gz: f85aa0cd77c310d4e798f8676189839bb4276d2b
2
+ SHA256:
3
+ metadata.gz: 9a8186fb041ca1c958fb32f75389eceb29cbe6c107c0510b725fdc2bba18b900
4
+ data.tar.gz: 7ffe43266b6c14f59f1c306f86c018f44b312d9ee02e9253e3b3cbd38932f26e
5
5
  SHA512:
6
- metadata.gz: 345cfa379161bccf03db5945499114e6d322161891b66d85aac934e7cd8de8834cc73c465d65a19c482cf8320d22c1ae89b1afb8bcc9794dab2faf3a7460aeec
7
- data.tar.gz: bc6916ad37c08f73ab2594c9537e14212257583e37437c396ea1f716219edfdda2a9be430c9d55bc8b7b1f777ec27beac7c76f1a97fb6d676f72bb36327a3ccf
6
+ metadata.gz: 12e95c5b22a998f54833adf7edd459ace61a85cceabc1463c5d572110aa2241c7642c96ab943ff6c9a6b8e5be4e42ff925fbaa19a6b4752f14ca5b9b0f050cda
7
+ data.tar.gz: 0b7570f08589b2603390f89920cf689a4e4f5491ed279e0dc7498aa3b182b9aa586c96a81be13cb16297d5ab7f6e92ec7eb82e0c31a1eebb4c88552471a2ce74
@@ -109,4 +109,51 @@ module PuppetLitmus::InventoryManipulation
109
109
  end
110
110
  inventory_hash
111
111
  end
112
+
113
+ # Adds a feature to the group specified/
114
+ #
115
+ # @param inventory_hash [Hash] hash of the inventory.yaml file
116
+ # @param feature_name [String] feature to locate in the group
117
+ # group_name [String] group of nodes to limit the search for the group_name in
118
+ # @return inventory.yaml file with feature added to group.
119
+ # @return [Hash] inventory_hash with feature added to group if group_name exists in inventory hash.
120
+ def add_feature_to_group(inventory_hash, feature_name, group_name)
121
+ i = 0
122
+ inventory_hash['groups'].each do |group|
123
+ if group['name'] == group_name
124
+ if group['features'].nil? == true
125
+ group = group.merge('features' => [])
126
+ end
127
+ group['features'].push feature_name
128
+ inventory_hash['groups'][i] = group
129
+ end
130
+ i += 1
131
+ end
132
+ inventory_hash
133
+ end
134
+
135
+ # Removes a feature from the group specified/
136
+ #
137
+ # @param inventory_hash [Hash] hash of the inventory.yaml file
138
+ # @param feature_name [String] feature to locate in the group
139
+ # group_name [String] group of nodes to limit the search for the group_name in
140
+ # @return inventory.yaml file with feature removed from the group.
141
+ # @return [Hash] inventory_hash with feature added to group if group_name exists in inventory hash.
142
+ def remove_feature_from_group(inventory_hash, feature_name, group_name)
143
+ inventory_hash['groups'].each do |group|
144
+ if group['name'] == group_name && group['features'].nil? != true
145
+ group['features'].delete(feature_name)
146
+ end
147
+ end
148
+ inventory_hash
149
+ end
150
+
151
+ # Write inventory_hash to inventory_yaml file/
152
+ #
153
+ # @param inventory_full_path [String] path to the inventory.yaml file
154
+ # @param inventory_hash [Hash] hash of the inventory.yaml file
155
+ # @return inventory.yaml file with feature added to group.
156
+ def write_to_inventory_file(inventory_hash, inventory_full_path)
157
+ File.open(inventory_full_path, 'w+') { |f| f.write(inventory_hash.to_yaml) }
158
+ end
112
159
  end
@@ -107,6 +107,8 @@ namespace :litmus do
107
107
  task :provision_list, [:key] do |_task, args|
108
108
  provision_hash = YAML.load_file('./provision.yaml')
109
109
  provisioner = provision_hash[args[:key]]['provisioner']
110
+ # Splat the params into environment variables to pass to the provision task but only in this runspace
111
+ provision_hash[args[:key]]['params']&.each { |key, value| ENV["LITMUS_#{key.upcase}"] = value }
110
112
  failed_image_message = ''
111
113
  provision_hash[args[:key]]['images'].each do |image|
112
114
  # this is the only way to capture the stdout from the rake task, it will affect pry
@@ -358,22 +360,30 @@ namespace :litmus do
358
360
  end
359
361
  spinners = TTY::Spinner::Multi.new("Running against #{targets.size} targets.[:spinner]", frames: ['.'], interval: 0.1)
360
362
  payloads = []
363
+ # Generate list of targets to provision
361
364
  targets.each do |target|
362
- test = "TARGET_HOST=#{target} bundle exec rspec ./spec/acceptance --format progress"
365
+ test = 'bundle exec bundle exec rspec ./spec/acceptance --format progress'
363
366
  title = "#{target}, #{facts_from_node(inventory_hash, target)['platform']}"
364
- payloads << [title, test]
367
+ options = {
368
+ env: {
369
+ 'TARGET_HOST' => target,
370
+ },
371
+ }
372
+ payloads << [title, test, options]
365
373
  end
366
374
 
367
375
  results = []
368
376
  success_list = []
369
377
  failure_list = []
378
+ # Provision targets depending on what environment we're in
370
379
  if (ENV['CI'] == 'true') || !ENV['DISTELLI_BUILDNUM'].nil?
371
380
  # CI systems are strange beasts, we only output a '.' every wee while to keep the terminal alive.
372
381
  puts "Running against #{targets.size} targets.\n"
373
382
  spinner = TTY::Spinner.new(':spinner', frames: ['.'], interval: 0.1)
374
383
  spinner.auto_spin
375
- results = Parallel.map(payloads) do |title, test|
376
- stdout, stderr, status = Open3.capture3(test)
384
+ results = Parallel.map(payloads) do |title, test, options|
385
+ env = options[:env].nil? ? {} : options[:env]
386
+ stdout, stderr, status = Open3.capture3(env, test)
377
387
  ["================\n#{title}\n", stdout, stderr, status]
378
388
  end
379
389
  # because we cannot modify variables inside of Parallel
@@ -387,9 +397,10 @@ namespace :litmus do
387
397
  spinner.success
388
398
  else
389
399
  spinners = TTY::Spinner::Multi.new("[:spinner] Running against #{targets.size} targets.")
390
- payloads.each do |title, test|
400
+ payloads.each do |title, test, options|
401
+ env = options[:env].nil? ? {} : options[:env]
391
402
  spinners.register("[:spinner] #{title}") do |sp|
392
- stdout, stderr, status = Open3.capture3(test)
403
+ stdout, stderr, status = Open3.capture3(env, test)
393
404
  if status.to_i.zero?
394
405
  sp.success
395
406
  success_list.push(title)
@@ -102,6 +102,37 @@ module PuppetLitmus::Serverspec
102
102
  result
103
103
  end
104
104
 
105
+ # Copies file to the target, using its respective transport
106
+ #
107
+ # @param source [String] place locally, to copy from.
108
+ # @param destination [String] place on the target, to copy to.
109
+ # @param opts [Hash] Alters the behaviour of the command. Valid options are :expect_failures [Boolean] doesnt return an exit code of non-zero if the command failed.
110
+ # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
111
+ # @return [Object] A result object from the command.
112
+ def bolt_upload_file(source, destination, options = {})
113
+ target_node_name = ENV['TARGET_HOST'] if target_node_name.nil?
114
+ inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
115
+ nil
116
+ else
117
+ inventory_hash_from_inventory_file
118
+ end
119
+
120
+ result = upload_file(source, destination, target_node_name, options: options, config: nil, inventory: inventory_hash)
121
+
122
+ raise "upload file failed\n======\n#{result}" if result.first['status'] != 'success'
123
+
124
+ exit_code = if result.first['status'] == 'success'
125
+ 0
126
+ else
127
+ 255
128
+ end
129
+ result = OpenStruct.new(exit_code: exit_code,
130
+ stdout: result.first['result']['status'],
131
+ stderr: result.first['result']['status'])
132
+ yield result if block_given?
133
+ result
134
+ end
135
+
105
136
  # Runs a task against the target system.
106
137
  #
107
138
  # @param task_name [String] The name of the task to run.
@@ -2,5 +2,5 @@
2
2
 
3
3
  # version of this gem
4
4
  module PuppetLitmus
5
- VERSION ||= '0.5.0'
5
+ VERSION ||= '0.6.0'
6
6
  end
@@ -0,0 +1,16 @@
1
+ ---
2
+ groups:
3
+ - name: ssh_nodes
4
+ nodes:
5
+ - name: test.delivery.puppetlabs.net
6
+ config:
7
+ transport: ssh
8
+ ssh:
9
+ user: root
10
+ password: Qu@lity!
11
+ host-key-check: false
12
+ facts:
13
+ provisioner: vmpooler
14
+ platform: centos-5-x86_64
15
+ - name: winrm_nodes
16
+ nodes: []
@@ -31,6 +31,40 @@ RSpec.describe PuppetLitmus::InventoryManipulation do
31
31
  { 'name' => 'winrm_nodes', 'nodes' => [] }] }
32
32
  end
33
33
 
34
+ let(:inventory_full_path) { 'spec/data/inventory.yaml' }
35
+
36
+ let(:no_feature_hash) do
37
+ { 'groups' =>
38
+ [{ 'name' => 'ssh_nodes',
39
+ 'nodes' =>
40
+ [{ 'name' => 'test.delivery.puppetlabs.net',
41
+ 'config' => { 'transport' => 'ssh', 'ssh' => { 'user' => 'root', 'password' => 'Qu@lity!', 'host-key-check' => false } },
42
+ 'facts' => { 'provisioner' => 'vmpooler', 'platform' => 'centos-5-x86_64' } }] },
43
+ { 'name' => 'winrm_nodes', 'nodes' => [] }] }
44
+ end
45
+
46
+ let(:feature_hash) do
47
+ { 'groups' =>
48
+ [{ 'name' => 'ssh_nodes',
49
+ 'nodes' =>
50
+ [{ 'name' => 'test.delivery.puppetlabs.net',
51
+ 'config' => { 'transport' => 'ssh', 'ssh' => { 'user' => 'root', 'password' => 'Qu@lity!', 'host-key-check' => false } },
52
+ 'facts' => { 'provisioner' => 'vmpooler', 'platform' => 'centos-5-x86_64' } }],
53
+ 'features' => ['puppet-agent'] },
54
+ { 'name' => 'winrm_nodes', 'nodes' => [] }] }
55
+ end
56
+
57
+ let(:empty_feature_hash) do
58
+ { 'groups' =>
59
+ [{ 'name' => 'ssh_nodes',
60
+ 'nodes' =>
61
+ [{ 'name' => 'test.delivery.puppetlabs.net',
62
+ 'config' => { 'transport' => 'ssh', 'ssh' => { 'user' => 'root', 'password' => 'Qu@lity!', 'host-key-check' => false } },
63
+ 'facts' => { 'provisioner' => 'vmpooler', 'platform' => 'centos-5-x86_64' } }],
64
+ 'features' => [] },
65
+ { 'name' => 'winrm_nodes', 'nodes' => [] }] }
66
+ end
67
+
34
68
  it 'no matching node, raises' do
35
69
  expect { dummy_class.config_from_node(config_hash, 'not.here') }.to raise_error('No config was found for not.here')
36
70
  end
@@ -43,5 +77,26 @@ RSpec.describe PuppetLitmus::InventoryManipulation do
43
77
  expect(dummy_class.config_from_node(config_hash, 'test.delivery.puppetlabs.net')).to eq('transport' => 'ssh', 'ssh' =>
44
78
  { 'user' => 'root', 'password' => 'Qu@lity!', 'host-key-check' => false })
45
79
  end
80
+
81
+ it 'no feature exists, and returns hash with feature added' do
82
+ expect(dummy_class.add_feature_to_group(no_feature_hash, 'puppet-agent', 'ssh_nodes')).to eq('groups' => [{ 'features' => ['puppet-agent'], 'name' => 'ssh_nodes', 'nodes' => [{ 'config' => { 'ssh' => { 'host-key-check' => false, 'password' => 'Qu@lity!', 'user' => 'root' }, 'transport' => 'ssh' }, 'facts' => { 'platform' => 'centos-5-x86_64', 'provisioner' => 'vmpooler' }, 'name' => 'test.delivery.puppetlabs.net' }] }, { 'name' => 'winrm_nodes', 'nodes' => [] }]) # rubocop:disable Metrics/LineLength: Line is too long
83
+ end
84
+
85
+ it 'feature exists, and returns hash with feature removed' do
86
+ expect(dummy_class.remove_feature_from_group(feature_hash, 'puppet-agent', 'ssh_nodes')).to eq('groups' => [{ 'features' => [], 'name' => 'ssh_nodes', 'nodes' => [{ 'config' => { 'ssh' => { 'host-key-check' => false, 'password' => 'Qu@lity!', 'user' => 'root' }, 'transport' => 'ssh' }, 'facts' => { 'platform' => 'centos-5-x86_64', 'provisioner' => 'vmpooler' }, 'name' => 'test.delivery.puppetlabs.net' }] }, { 'name' => 'winrm_nodes', 'nodes' => [] }]) # rubocop:disable Metrics/LineLength: Line is too long
87
+ end
88
+
89
+ it 'write from inventory_hash to inventory_yaml file feature_hash' do
90
+ expect { dummy_class.write_to_inventory_file(feature_hash, inventory_full_path) }.not_to raise_error
91
+ end
92
+
93
+ it 'empty feature exists, and returns hash with feature added' do
94
+ expect(dummy_class.add_feature_to_group(empty_feature_hash, 'puppet-agent', 'ssh_nodes')).to eq('groups' => [{ 'features' => ['puppet-agent'], 'name' => 'ssh_nodes', 'nodes' => [{ 'config' => { 'ssh' => { 'host-key-check' => false, 'password' => 'Qu@lity!', 'user' => 'root' }, 'transport' => 'ssh' }, 'facts' => { 'platform' => 'centos-5-x86_64', 'provisioner' => 'vmpooler' }, 'name' => 'test.delivery.puppetlabs.net' }] }, { 'name' => 'winrm_nodes', 'nodes' => [] }]) # rubocop:disable Metrics/LineLength: Line is too long
95
+ end
96
+
97
+ it 'write from inventory_hash to inventory_yaml file no feature_hash' do
98
+ expect(File).to exist(inventory_full_path)
99
+ expect { dummy_class.write_to_inventory_file(no_feature_hash, inventory_full_path) }.not_to raise_error
100
+ end
46
101
  end
47
102
  end
@@ -50,4 +50,33 @@ RSpec.describe PuppetLitmus::Serverspec do
50
50
  end
51
51
  end
52
52
  end
53
+
54
+ describe '.bolt_upload_file' do
55
+ let(:local) { '/tmp' }
56
+ let(:remote) { '/remote_tmp' }
57
+ let(:result) { ['status' => 'success', 'result' => { 'exit_code' => 0, 'stdout' => nil, 'stderr' => nil }] }
58
+ let(:inventory_hash) { Hash.new(0) }
59
+
60
+ it 'responds to run_shell' do
61
+ expect(dummy_class).to respond_to(:bolt_upload_file).with(2..3).arguments
62
+ end
63
+
64
+ context 'when running against remote host' do
65
+ it 'does upload_file against remote host without error' do
66
+ allow(ENV).to receive(:[]).with('TARGET_HOST').and_return('some.host')
67
+ expect(dummy_class).to receive(:inventory_hash_from_inventory_file).and_return(inventory_hash)
68
+ expect(dummy_class).to receive(:upload_file).with(local, remote, 'some.host', options: {}, config: nil, inventory: inventory_hash).and_return(result)
69
+ expect { dummy_class.bolt_upload_file(local, remote) }.not_to raise_error
70
+ end
71
+ end
72
+
73
+ context 'when running against remote host' do
74
+ it 'does upload_file against localhost without error' do
75
+ allow(ENV).to receive(:[]).with('TARGET_HOST').and_return('localhost')
76
+ expect(dummy_class).not_to receive(:inventory_hash_from_inventory_file)
77
+ expect(dummy_class).to receive(:upload_file).with(local, remote, 'localhost', options: {}, config: nil, inventory: nil).and_return(result)
78
+ expect { dummy_class.bolt_upload_file(local, remote) }.not_to raise_error
79
+ end
80
+ end
81
+ end
53
82
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet_litmus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-13 00:00:00.000000000 Z
11
+ date: 2019-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bolt
@@ -85,6 +85,7 @@ files:
85
85
  - lib/puppet_litmus/rake_tasks.rb
86
86
  - lib/puppet_litmus/serverspec.rb
87
87
  - lib/puppet_litmus/version.rb
88
+ - spec/data/inventory.yaml
88
89
  - spec/lib/puppet_litmus/inventory_manipulation_spec.rb
89
90
  - spec/lib/puppet_litmus/rake_tasks_spec.rb
90
91
  - spec/lib/puppet_litmus/serverspec_spec.rb
@@ -109,15 +110,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
110
  - !ruby/object:Gem::Version
110
111
  version: '0'
111
112
  requirements: []
112
- rubyforge_project:
113
- rubygems_version: 2.6.14.1
113
+ rubygems_version: 3.0.4
114
114
  signing_key:
115
115
  specification_version: 4
116
116
  summary: Providing a simple command line tool for puppet content creators, to enable
117
117
  simple and complex test deployments.
118
118
  test_files:
119
- - spec/spec_helper.rb
120
- - spec/lib/puppet_litmus/rake_tasks_spec.rb
121
- - spec/lib/puppet_litmus/version_spec.rb
119
+ - spec/data/inventory.yaml
122
120
  - spec/lib/puppet_litmus/inventory_manipulation_spec.rb
121
+ - spec/lib/puppet_litmus/rake_tasks_spec.rb
123
122
  - spec/lib/puppet_litmus/serverspec_spec.rb
123
+ - spec/lib/puppet_litmus/version_spec.rb
124
+ - spec/spec_helper.rb