puppetbox 0.1.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|