puppetbox 0.1.0 → 0.3.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 +4 -4
- data/Gemfile +1 -0
- data/lib/puppetbox/driver/vagrant.rb +60 -13
- data/lib/puppetbox/logger.rb +5 -1
- data/lib/puppetbox/nodeset.rb +81 -0
- data/lib/puppetbox/puppetbox.rb +185 -0
- data/lib/puppetbox/report.rb +27 -0
- data/lib/puppetbox/result.rb +23 -5
- data/lib/puppetbox/result_set.rb +67 -0
- data/lib/puppetbox/version.rb +1 -1
- data/lib/puppetbox.rb +0 -9
- data/puppetbox.gemspec +1 -1
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0b4270e3681f985ebb627e7126987337345963f
|
4
|
+
data.tar.gz: aa5f16dd84a2f10e25abe4e23c73a03082316fb6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af4ca9d3108b2d81150d53ea25473f4a5ddb722e14a76814f37e433c698c073919d3fbcaf228044740040651342de8fcc7146a912dafa7e5387864c61d29df1e
|
7
|
+
data.tar.gz: fa61ab2481c0fb6d49681168eb44b9917c5320f244b0d130123a6a140d0e1916c795bd986f6e1e8fbc5cf23179b8f7f4ddbb97dfe8c785f7e5e5b1f2f72477b8
|
data/Gemfile
CHANGED
@@ -7,20 +7,47 @@ module PuppetBox
|
|
7
7
|
module Driver
|
8
8
|
class Vagrant
|
9
9
|
# fixme - seems abandoned, might need to make my own :(
|
10
|
-
DEFAULT_VAGRANT_BOX = "puppetlabs/centos-7.2-64-puppet"
|
10
|
+
# DEFAULT_VAGRANT_BOX = "puppetlabs/centos-7.2-64-puppet"
|
11
11
|
PUPPET_CODE_MOUNT = "/etc/puppetlabs/code/environments/production"
|
12
12
|
|
13
|
-
def
|
13
|
+
def node_name
|
14
|
+
@name
|
15
|
+
end
|
16
|
+
|
17
|
+
# def initialize(name, codedir, keep_vm:true, working_dir:nil, config:{'box'=> DEFAULT_VAGRANT_BOX}, logger: nil)
|
18
|
+
def initialize(name, codedir, config, keep_vm:false, working_dir:nil, logger: nil)
|
19
|
+
|
14
20
|
@name = name
|
15
21
|
@keep_vm = keep_vm
|
16
22
|
@working_dir = working_dir || File.join(Dir.home, '.puppetbox')
|
17
23
|
@config = config
|
18
|
-
@result =
|
19
|
-
@logger =
|
24
|
+
@result = Result.new
|
25
|
+
@logger = Logger.new(logger).logger
|
26
|
+
|
27
|
+
if ! @config.has_key?("box")
|
28
|
+
raise "Node #{node_name} must specify box"
|
29
|
+
end
|
20
30
|
|
21
31
|
# Add the code dir to the config has so that it will automatically become
|
22
32
|
# a shared folder when the VM boots
|
23
|
-
|
33
|
+
|
34
|
+
# can't use dig() might not be ruby 2.3
|
35
|
+
if @config.has_key?("folders")
|
36
|
+
@config["folders"] = Array(@config["folders"])
|
37
|
+
|
38
|
+
# all paths must be fully qualified. If we were asked to do a relative path, change
|
39
|
+
# it to the current directory since that's probably what the user wanted. Not right?
|
40
|
+
# user supply correct path!
|
41
|
+
@config["folders"] = @config["folders"].map { |folder|
|
42
|
+
if ! folder.start_with? '/'
|
43
|
+
folder = "#{Dir.pwd}/#{folder}"
|
44
|
+
end
|
45
|
+
folder
|
46
|
+
}
|
47
|
+
else
|
48
|
+
@config["folders"] = []
|
49
|
+
end
|
50
|
+
@config["folders"] << "#{codedir}:#{PUPPET_CODE_MOUNT}"
|
24
51
|
@logger.debug "instance #{name} initialised"
|
25
52
|
end
|
26
53
|
|
@@ -38,15 +65,19 @@ module PuppetBox
|
|
38
65
|
# 4: The run succeeded, and some resources failed.
|
39
66
|
# 6: The run succeeded, and included both changes and failures.
|
40
67
|
def run_puppet(puppet_class)
|
41
|
-
|
42
|
-
|
68
|
+
status_code, messages = @vm.run(
|
69
|
+
"sudo -i puppet apply --detailed-exitcodes -e 'include #{puppet_class}'"
|
70
|
+
)
|
71
|
+
@result.save(status_code, messages)
|
72
|
+
@result.passed?
|
43
73
|
end
|
44
74
|
|
45
75
|
# Open a connection to a box (eg start a vm, ssh to a host etc)
|
46
76
|
def open()
|
47
77
|
# make sure working dir exists...
|
48
78
|
FileUtils.mkdir_p(@working_dir)
|
49
|
-
|
79
|
+
|
80
|
+
vom = Vagrantomatic::Vagrantomatic.new(vagrant_vm_dir: @working_dir, logger: @logger)
|
50
81
|
|
51
82
|
@logger.debug("reading instance metadata for #{@name}")
|
52
83
|
@vm = vom.instance(@name)
|
@@ -56,26 +87,42 @@ module PuppetBox
|
|
56
87
|
@vm.config=(@config)
|
57
88
|
@vm.save
|
58
89
|
@logger.debug("Instance saved and ready for starting")
|
59
|
-
@vm.start
|
90
|
+
started = @vm.start
|
60
91
|
end
|
61
92
|
|
62
93
|
# Close a connection to a box (eg stop a vm, probaly doesn't need to do
|
63
94
|
# anything on SSH...)
|
64
95
|
def close()
|
65
96
|
if ! @keep_vm
|
97
|
+
@logger.info("Closing #{@node_name}")
|
66
98
|
@vm.purge
|
67
99
|
end
|
68
100
|
end
|
69
101
|
|
102
|
+
def reset()
|
103
|
+
@vm.reset
|
104
|
+
end
|
105
|
+
|
70
106
|
# Test that a VM is operational and able to run puppet
|
71
107
|
def self_test()
|
72
|
-
@vm.run("sudo -i puppet --version")
|
108
|
+
status_code, messages = @vm.run("sudo -i puppet --version")
|
109
|
+
self_test = (status_code == 0)
|
110
|
+
if self_test
|
111
|
+
@logger.info("Running under Puppet version: #{messages[0].strip}")
|
112
|
+
else
|
113
|
+
@logger.error("Error #{status_code} running puppet: #{messages}")
|
114
|
+
end
|
115
|
+
self_test
|
73
116
|
end
|
74
117
|
|
75
118
|
def run_puppet_x2(puppet_class)
|
76
|
-
#
|
77
|
-
|
78
|
-
|
119
|
+
# if you need to link a module into puppet's modulepath either do it
|
120
|
+
# before running puppet (yet to be supported) or use the @config hash
|
121
|
+
# for vagrant to mount what you need as a shared folder
|
122
|
+
if run_puppet(puppet_class)
|
123
|
+
# Only do the second run if the first run passes
|
124
|
+
run_puppet(puppet_class)
|
125
|
+
end
|
79
126
|
end
|
80
127
|
|
81
128
|
end
|
data/lib/puppetbox/logger.rb
CHANGED
@@ -10,7 +10,11 @@ module PuppetBox
|
|
10
10
|
else
|
11
11
|
@logger = ::Logger.new(STDOUT)
|
12
12
|
@logger.formatter = proc do |severity, datetime, progname, msg|
|
13
|
-
|
13
|
+
# depending on the source, some messages come in with new lines and
|
14
|
+
# some do not so strip off any exiting and then add our own for
|
15
|
+
# consistency
|
16
|
+
msg = msg.strip
|
17
|
+
"#{severity}: #{msg}\n"
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module PuppetBox
|
4
|
+
class NodeSet
|
5
|
+
NODESET_FILE = "spec/acceptance/nodesets/puppetbox.yaml"
|
6
|
+
VERSION_KEY = "puppetbox_nodeset"
|
7
|
+
UNDERSTANDS_VERSION = [1]
|
8
|
+
REQUIRED_KEYS = ["config", "driver"]
|
9
|
+
NODE_ELEMENT = "nodes"
|
10
|
+
|
11
|
+
def initialize(nodeset_file=nil)
|
12
|
+
@nodeset_file = nodeset_file || NODESET_FILE
|
13
|
+
|
14
|
+
# parse the yaml file and simplify to human readable errors
|
15
|
+
begin
|
16
|
+
@nodeset = YAML.load(IO.read(@nodeset_file))
|
17
|
+
rescue Errno::ENOENT
|
18
|
+
raise "File not found: #{@nodeset_file}"
|
19
|
+
rescue Psych::SyntaxError
|
20
|
+
raise "Syntax error reading #{@nodeset_file}"
|
21
|
+
end
|
22
|
+
if @nodeset.has_key?(VERSION_KEY)
|
23
|
+
if UNDERSTANDS_VERSION.include?(@nodeset[VERSION_KEY])
|
24
|
+
if @nodeset.has_key?(NODE_ELEMENT)
|
25
|
+
hosts = @nodeset[NODE_ELEMENT]
|
26
|
+
hosts.each { |node_name, data|
|
27
|
+
# check each node has required keys
|
28
|
+
REQUIRED_KEYS.each { |required_key|
|
29
|
+
if ! data.has_key?(required_key)
|
30
|
+
raise "Nodeset file #{@nodeset_file} missing required key #{required_key} for node #{node_name}"
|
31
|
+
end
|
32
|
+
}
|
33
|
+
}
|
34
|
+
else
|
35
|
+
raise "Nodeset file #{@nodeset_file} missing root element `nodes`"
|
36
|
+
end
|
37
|
+
else
|
38
|
+
raise "Nodeset file format is #{@nodeset[VERSION_KEY]} but PuppetBox only supports versions #{UNDERSTANDS_VERSION}"
|
39
|
+
end
|
40
|
+
else
|
41
|
+
raise "Nodeset file #{@nodeset_file} does not contain #{VERSION_KEY} - check syntax"
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
def has_node?(node_name)
|
47
|
+
@nodeset[NODE_ELEMENT].has_key?(node_name)
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_node(node_name)
|
51
|
+
if has_node?(node_name)
|
52
|
+
@nodeset[NODE_ELEMENT][node_name]
|
53
|
+
else
|
54
|
+
raise "Node #{node_name} is not defined in nodset file: #{@nodeset_file}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
#
|
60
|
+
# if nodeset["hosts"][node.name].has_key?('config') and nodeset_yaml["HOSTS"][node.name].has_key?('driver')
|
61
|
+
# test.classes.each { |puppet_class|
|
62
|
+
# logger.info "Acceptance testing #{node.name} #{puppet_class.name}"
|
63
|
+
# summary[node.name][puppet_class.name] = pb.provision_and_test(
|
64
|
+
# nodeset_yaml["HOSTS"][node.name]["driver"],
|
65
|
+
# node.name,
|
66
|
+
# puppet_class.name,
|
67
|
+
# nodeset_yaml["HOSTS"][node.name]['config'],
|
68
|
+
# @repo,
|
69
|
+
# )
|
70
|
+
#
|
71
|
+
# overall &= ! summary[node.name][puppet_class.name]
|
72
|
+
# }
|
73
|
+
# else
|
74
|
+
# message = "onceover-nodes.yaml missing `config` or `driver` element for #{node.name} (tests skipped)"
|
75
|
+
# summary[node.name] = message
|
76
|
+
# overall = false
|
77
|
+
# end
|
78
|
+
# end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require "puppetbox/result_set"
|
2
|
+
require "puppetbox/logger"
|
3
|
+
require "puppetbox/nodeset"
|
4
|
+
require "puppetbox/driver/vagrant"
|
5
|
+
|
6
|
+
module PuppetBox
|
7
|
+
class PuppetBox
|
8
|
+
|
9
|
+
def initialize(logger:nil, nodeset_file: nil)
|
10
|
+
# The results of all tests on all driver instances
|
11
|
+
@result_set = ResultSet.new
|
12
|
+
|
13
|
+
# A complete test suite of tests to run - includes driver instance, host
|
14
|
+
# and classes
|
15
|
+
@testsuite = {}
|
16
|
+
@logger = Logger.new(logger).logger
|
17
|
+
|
18
|
+
# the nodesets file contains a YAML representation of a hash containing
|
19
|
+
# the node name, config options, driver to use etc - so external tools can
|
20
|
+
# talk to use about nodes of particular name and puppetbox will sort out
|
21
|
+
# the how and why of what this exactly should involve
|
22
|
+
@nodeset = NodeSet.new(nodeset_file)
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# Enqueue a test into the `testsuite` for
|
27
|
+
def enqueue_test(node_name, run_from, puppet_class)
|
28
|
+
instantiate_driver(node_name, run_from)
|
29
|
+
@testsuite[node_name]["classes"] << puppet_class
|
30
|
+
# get_driver_instance(driver_name, host)
|
31
|
+
# node_name
|
32
|
+
# puppet_class.name,
|
33
|
+
# nodeset_yaml["HOSTS"][node.name]['config'],
|
34
|
+
# @repo,
|
35
|
+
end
|
36
|
+
|
37
|
+
def run_testsuite
|
38
|
+
@testsuite.each { |id, tests|
|
39
|
+
run_puppet(tests["instance"], tests["classes"], logger:@logger, reset_after_run:true)
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def instantiate_driver(node_name, run_from)
|
44
|
+
node = @nodeset.get_node(node_name)
|
45
|
+
config = node["config"]
|
46
|
+
driver = node["driver"]
|
47
|
+
if @testsuite.has_key?(node_name)
|
48
|
+
@logger.debug("#{node_name} already registered")
|
49
|
+
else
|
50
|
+
@logger.debug("Creating new driver instance for #{node_name}")
|
51
|
+
|
52
|
+
# for now just support the vagrant driver
|
53
|
+
case driver
|
54
|
+
when "vagrant"
|
55
|
+
|
56
|
+
# For the moment, just use the checked out production environment inside
|
57
|
+
# onceover's working directory. The full path resolves to something like
|
58
|
+
# .onceover/etc/puppetlabs/code/environments/production -- in the
|
59
|
+
# directory your running onceover from
|
60
|
+
#
|
61
|
+
# we pass in our pre-configured logger instance for separation and to
|
62
|
+
# reduce the amount of log output. We only print puppet apply output for
|
63
|
+
# failed runs, however, if user runs in onceover's --debug mode, then we
|
64
|
+
# will print the customary ton of messages, including those from vagrant
|
65
|
+
# itself.
|
66
|
+
puts config["box"]
|
67
|
+
di = Driver::Vagrant.new(
|
68
|
+
node_name,
|
69
|
+
run_from,
|
70
|
+
config,
|
71
|
+
# "#{repo.tempdir}/etc/puppetlabs/code/environments/production",
|
72
|
+
logger: @logger,
|
73
|
+
|
74
|
+
)
|
75
|
+
else
|
76
|
+
raise "PuppetBox only supports driver: 'vagrant' at the moment (requested: #{driver})"
|
77
|
+
end
|
78
|
+
|
79
|
+
@testsuite[node_name] = {
|
80
|
+
"instance" => di,
|
81
|
+
"classes" => [],
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
# di
|
86
|
+
# result = ::PuppetBox.run_puppet(di, puppet_class)
|
87
|
+
|
88
|
+
# indent = " "
|
89
|
+
# if result.passed
|
90
|
+
# logger.info("#{indent}#{host}:#{puppet_class} --> PASSED")
|
91
|
+
# else
|
92
|
+
# logger.error("#{indent}#{host}:#{puppet_class} --> FAILED")
|
93
|
+
# # since we stop running on failure, the error messages will be in the
|
94
|
+
# # last element of the result.messages array (tada!)
|
95
|
+
# messages = result.messages
|
96
|
+
# messages[-1].each { |line|
|
97
|
+
# # puts "XXXXXXX #{line}"
|
98
|
+
# logger.error "#{indent}#{host} - #{line}"
|
99
|
+
# }
|
100
|
+
# # puts "size of result messages #{result.messages.size}"
|
101
|
+
# # puts "size of result messages #{result.messages[0].size}"
|
102
|
+
# # run.each { |message_arr|
|
103
|
+
# # puts message_arr
|
104
|
+
# # #message_arr.each { |line|
|
105
|
+
# # # puts line
|
106
|
+
# # # }
|
107
|
+
# # # require 'pry'
|
108
|
+
# # # binding.pry
|
109
|
+
# # #puts "messages size"
|
110
|
+
# # #puts messages.size
|
111
|
+
# # # messages.each { |message|
|
112
|
+
# # # messages from the puppet run are avaiable in a nested array of run
|
113
|
+
# # # and then lines so lets print each one out indended from the host so
|
114
|
+
# # # we can see what's what
|
115
|
+
# # # logger.error("#{host} #{message}")
|
116
|
+
# # # }
|
117
|
+
# # }
|
118
|
+
# # }
|
119
|
+
# end
|
120
|
+
# result.passed
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# Print all results to STDOUT
|
125
|
+
def print_results
|
126
|
+
# print the report summary
|
127
|
+
indent = " "
|
128
|
+
puts "\n\n\nSummary\n======="
|
129
|
+
summary.each { |node, class_results|
|
130
|
+
puts node
|
131
|
+
if class_results.class == String
|
132
|
+
puts "#{indent}#{class_results}"
|
133
|
+
else
|
134
|
+
class_results.each { |puppet_class, passed|
|
135
|
+
line = "#{indent}#{puppet_class}: #{passed ? "OK": "FAILED"}"
|
136
|
+
if passed
|
137
|
+
puts line.green
|
138
|
+
else
|
139
|
+
puts line.red
|
140
|
+
end
|
141
|
+
}
|
142
|
+
end
|
143
|
+
}
|
144
|
+
|
145
|
+
puts "Overall acceptance testing result #{overall}"
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
# Run puppet using `driver_instance` to execute
|
151
|
+
def run_puppet(driver_instance, puppet_classes, logger:nil, reset_after_run:true)
|
152
|
+
# use supplied logger in preference to the default puppetbox logger instance
|
153
|
+
logger = logger || @logger
|
154
|
+
logger.debug("#{driver_instance.node_name} running test for #{puppet_classes}")
|
155
|
+
puppet_classes = Array(puppet_classes)
|
156
|
+
results = ResultSet.new
|
157
|
+
if driver_instance.open
|
158
|
+
logger.debug("#{driver_instance.node_name} started")
|
159
|
+
if driver_instance.self_test
|
160
|
+
logger.debug("#{driver_instance.node_name} self_test OK, running puppet")
|
161
|
+
puppet_classes.each{ |puppet_class|
|
162
|
+
if results.class_size(driver_instance.node_name) > 0 and reset_after_run
|
163
|
+
# purge and reboot the vm - this will save approximately 1 second
|
164
|
+
# per class on the self-test which we now know will succeed
|
165
|
+
driver_instance.reset
|
166
|
+
end
|
167
|
+
driver_instance.run_puppet_x2(puppet_class)
|
168
|
+
results.save(driver_instance.node_name, puppet_class, driver_instance.result)
|
169
|
+
}
|
170
|
+
logger.debug("#{driver_instance.node_name} test completed, closing instance")
|
171
|
+
driver_instance.close
|
172
|
+
else
|
173
|
+
driver_instance.close
|
174
|
+
raise "#{driver_instance.node_name} self test failed, unable to continue"
|
175
|
+
end
|
176
|
+
else
|
177
|
+
driver_instance.close
|
178
|
+
raise "#{driver_instance.node_name} failed to start, unable to continue"
|
179
|
+
end
|
180
|
+
|
181
|
+
results
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module PuppetBox
|
2
|
+
module Report
|
3
|
+
def self.printstuff(stream=$STDOUT)
|
4
|
+
# print the report summary
|
5
|
+
indent = " "
|
6
|
+
stream.puts "\n\n\nSummary\n======="
|
7
|
+
summary.each { |node, class_results|
|
8
|
+
puts node
|
9
|
+
if class_results.class == String
|
10
|
+
stream.puts "#{indent}#{class_results}"
|
11
|
+
else
|
12
|
+
class_results.each { |puppet_class, passed|
|
13
|
+
line = "#{indent}#{puppet_class}: #{passed ? "OK": "FAILED"}"
|
14
|
+
if passed
|
15
|
+
stream.puts line.green
|
16
|
+
else
|
17
|
+
stream.puts line.red
|
18
|
+
end
|
19
|
+
}
|
20
|
+
end
|
21
|
+
}
|
22
|
+
|
23
|
+
stream.puts "OVERALL STATUS #{overall}"
|
24
|
+
overall
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/puppetbox/result.rb
CHANGED
@@ -23,7 +23,7 @@ module PuppetBox
|
|
23
23
|
# 2: The run succeeded, and some resources were changed.
|
24
24
|
# 4: The run succeeded, and some resources failed.
|
25
25
|
# 6: The run succeeded, and included both changes and failures.
|
26
|
-
def
|
26
|
+
def save(status_code, messages)
|
27
27
|
status = PS_ERROR
|
28
28
|
if @report.empty?
|
29
29
|
# first run
|
@@ -40,19 +40,37 @@ module PuppetBox
|
|
40
40
|
@report.push({:status => status, :messages => messages})
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
|
-
|
43
|
+
# Test whether this set of results passed or not
|
44
|
+
# @return true if tests were executed and passed, nil if no tests were
|
45
|
+
# executed, false if tests were exectued and there were failures
|
46
|
+
def passed?
|
47
|
+
passed = nil
|
45
48
|
@report.each { |r|
|
46
|
-
|
49
|
+
puts "...REPORT"
|
50
|
+
if passed == nil
|
51
|
+
passed = (r[:status] == PS_OK)
|
52
|
+
else
|
53
|
+
passed &= (r[:status] == PS_OK)
|
54
|
+
end
|
47
55
|
}
|
48
56
|
|
49
57
|
passed
|
50
58
|
end
|
51
59
|
|
60
|
+
def report_count
|
61
|
+
@report.size
|
62
|
+
end
|
63
|
+
|
64
|
+
def report_message_count(report)
|
65
|
+
@report[report].messages.size
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
|
52
70
|
def messages(run=-1)
|
53
71
|
messages = []
|
54
72
|
if run < 0
|
55
|
-
# all
|
73
|
+
# all NESTED in order of report
|
56
74
|
@report.each { |r|
|
57
75
|
messages << r[:messages]
|
58
76
|
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module PuppetBox
|
2
|
+
class ResultSet
|
3
|
+
def initialize
|
4
|
+
@results = {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def save(node_name, class_name, result)
|
8
|
+
# check we didn't make a stupid programming error
|
9
|
+
if result.class != ::PuppetBox::Result
|
10
|
+
raise "result to save must be instance of PuppetBox::Result"
|
11
|
+
end
|
12
|
+
|
13
|
+
# if this is the first set of results for this node then we need to make
|
14
|
+
# a hash to contain the results
|
15
|
+
if ! @results.has_key?(node_name)
|
16
|
+
@results[node_name] = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
# We can only run the same class on each node once, if we attempt to do so
|
20
|
+
# again,
|
21
|
+
if @results[node_name].has_key?(class_name)
|
22
|
+
raise "Duplicate results for class #{class_name} detected, You can " \
|
23
|
+
"only test the same class once per node. Check your test configuration"
|
24
|
+
else
|
25
|
+
@results[node_name][class_name] = result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def passed?
|
30
|
+
@results.map { |node_name, class_results_hash|
|
31
|
+
class_results_hash.map { |class_name, class_results|
|
32
|
+
class_results.passed?
|
33
|
+
}.all?
|
34
|
+
}.all?
|
35
|
+
end
|
36
|
+
|
37
|
+
def data
|
38
|
+
@results
|
39
|
+
end
|
40
|
+
|
41
|
+
# The count of how many nodes we presently have saved
|
42
|
+
def node_size
|
43
|
+
@results.size
|
44
|
+
end
|
45
|
+
|
46
|
+
# The count of how many classes we presently have saved for a given node
|
47
|
+
def class_size(node_name)
|
48
|
+
if @results.has_key?(node_name)
|
49
|
+
size = @results[node_name].size
|
50
|
+
else
|
51
|
+
size = 0
|
52
|
+
end
|
53
|
+
|
54
|
+
size
|
55
|
+
end
|
56
|
+
|
57
|
+
# The count of how many tests this result_set contains for all nodes and
|
58
|
+
# classes
|
59
|
+
def test_size
|
60
|
+
@results.map {|node_name, classes|
|
61
|
+
classes.size
|
62
|
+
}.reduce(:+)
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
data/lib/puppetbox/version.rb
CHANGED
data/lib/puppetbox.rb
CHANGED
@@ -2,14 +2,5 @@ require "puppetbox/version"
|
|
2
2
|
|
3
3
|
module PuppetBox
|
4
4
|
|
5
|
-
def self.run_puppet(driver_instance, puppet_class)
|
6
|
-
if driver_instance.open
|
7
|
-
if driver_instance.self_test
|
8
|
-
driver_instance.run_puppet_x2(puppet_class)
|
9
|
-
driver_instance.close
|
10
|
-
end
|
11
|
-
end
|
12
|
-
driver_instance.result
|
13
|
-
end
|
14
5
|
|
15
6
|
end
|
data/puppetbox.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppetbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geoff Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -56,16 +56,16 @@ dependencies:
|
|
56
56
|
name: vagrantomatic
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 0.2.1
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 0.2.1
|
69
69
|
description:
|
70
70
|
email:
|
71
71
|
- geoff@geoffwilliams.me.uk
|
@@ -86,7 +86,11 @@ files:
|
|
86
86
|
- lib/puppetbox/driver.rb
|
87
87
|
- lib/puppetbox/driver/vagrant.rb
|
88
88
|
- lib/puppetbox/logger.rb
|
89
|
+
- lib/puppetbox/nodeset.rb
|
90
|
+
- lib/puppetbox/puppetbox.rb
|
91
|
+
- lib/puppetbox/report.rb
|
89
92
|
- lib/puppetbox/result.rb
|
93
|
+
- lib/puppetbox/result_set.rb
|
90
94
|
- lib/puppetbox/version.rb
|
91
95
|
- puppetbox.gemspec
|
92
96
|
homepage: https://github.com/GeoffWilliams/puppetbox
|