Skip to content
This repository has been archived by the owner on Jan 1, 2020. It is now read-only.

Updated client check attribute token substitution #1296

Merged
merged 3 commits into from May 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 20 additions & 23 deletions lib/sensu/client/process.rb
Expand Up @@ -99,43 +99,40 @@ def publish_check_result(check)
end
end

# Perform token-substitution for an object. Strings are passed
# to substitute_tokens(), arrays and sub-hashes are processed
# recursively. Numbers (and other types?) are skipped at the
# moment, because substitute_tokens() can not handle them
# anyway.
# Perform token substitution for an object. String values are
# passed to `substitute_tokens()`, arrays and sub-hashes are
# processed recursively. Numeric values are ignored.
#
# @param [Object]
# @return [Object] updated object of the same type as the argument
# plus accumulated list of unmatched tokens
def obj_substitute_tokens(obj)
case obj
# @param object [Object]
# @return [Array] containing the updated object with substituted
# values and an array of unmatched tokens.
def object_substitute_tokens(object)
unmatched_tokens = []
case object
when Hash
unmatched_tokens = []
obj.each do |key, value|
obj[key], unmatched = obj_substitute_tokens(value)
object.each do |key, value|
object[key], unmatched = object_substitute_tokens(value)
unmatched_tokens.push(*unmatched)
end
when Array
unmatched_tokens = []
obj.map! do |value|
value, unmatched = obj_substitute_tokens(value)
object.map! do |value|
value, unmatched = object_substitute_tokens(value)
unmatched_tokens.push(*unmatched)
value
end
when String
obj, unmatched_tokens = substitute_tokens(obj, @settings[:client])
object, unmatched_tokens = substitute_tokens(object, @settings[:client])
end
unmatched_tokens.uniq! if unmatched_tokens
[obj, unmatched_tokens]
[object, unmatched_tokens.uniq]
end

# Execute a check command, capturing its output (STDOUT/ERR),
# exit status code, execution duration, timestamp, and publish
# the result. This method guards against multiple executions for
# the same check. Check command tokens are substituted with the
# associated client attribute values. If there are unmatched
# check command tokens, the check command will not be executed,
# the same check. Check attribute value tokens are substituted
# with the associated client attribute values, via
# `object_substitute_tokens()`. If there are unmatched check
# attribute value tokens, the check will not be executed,
# instead a check result will be published reporting the
# unmatched tokens.
#
Expand All @@ -144,7 +141,7 @@ def execute_check_command(check)
@logger.debug("attempting to execute check command", :check => check)
unless @checks_in_progress.include?(check[:name])
@checks_in_progress << check[:name]
check, unmatched_tokens = obj_substitute_tokens(check)
check, unmatched_tokens = object_substitute_tokens(check)
if unmatched_tokens.empty?
started = Time.now.to_f
check[:executed] = started.to_i
Expand Down
27 changes: 27 additions & 0 deletions spec/client/process_spec.rb
Expand Up @@ -85,6 +85,33 @@
end
end

it "can substitute tokens in a check definition" do
check = check_template
check[:command] = "echo :::nested.attribute:::"
check[:foo] = [":::missing|foo:::"]
check[:bar] = {
:baz => ":::missing:::",
:qux => ":::missing|qux:::",
:quux => {
:corge => ":::missing:::",
:grault => ":::nonexistent:::",
:garply => ":::missing|garply:::",
:waldo => ":::name:::"
}
}
substituted, unmatched_tokens = @client.object_substitute_tokens(check)
expect(substituted[:name]).to eq("test")
expect(substituted[:command]).to eq("echo true")
expect(substituted[:foo].first).to eq("foo")
expect(substituted[:bar][:baz]).to eq("")
expect(substituted[:bar][:qux]).to eq("qux")
expect(substituted[:bar][:quux][:corge]).to eq("")
expect(substituted[:bar][:quux][:grault]).to eq("")
expect(substituted[:bar][:quux][:garply]).to eq("garply")
expect(substituted[:bar][:quux][:waldo]).to eq("i-424242")
expect(unmatched_tokens).to match_array(["missing", "nonexistent"])
end

it "can substitute check command tokens with attributes, default values, and execute it" do
async_wrapper do
result_queue do |payload|
Expand Down