puppet_litmus 0.5.0 → 0.6.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.
- checksums.yaml +5 -5
- data/lib/puppet_litmus/inventory_manipulation.rb +47 -0
- data/lib/puppet_litmus/rake_tasks.rb +17 -6
- data/lib/puppet_litmus/serverspec.rb +31 -0
- data/lib/puppet_litmus/version.rb +1 -1
- data/spec/data/inventory.yaml +16 -0
- data/spec/lib/puppet_litmus/inventory_manipulation_spec.rb +55 -0
- data/spec/lib/puppet_litmus/serverspec_spec.rb +29 -0
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9a8186fb041ca1c958fb32f75389eceb29cbe6c107c0510b725fdc2bba18b900
|
4
|
+
data.tar.gz: 7ffe43266b6c14f59f1c306f86c018f44b312d9ee02e9253e3b3cbd38932f26e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 =
|
365
|
+
test = 'bundle exec bundle exec rspec ./spec/acceptance --format progress'
|
363
366
|
title = "#{target}, #{facts_from_node(inventory_hash, target)['platform']}"
|
364
|
-
|
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
|
-
|
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.
|
@@ -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.
|
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-
|
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
|
-
|
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/
|
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
|