choria-mcorpc-support 2.21.1 → 2.23.1
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/lib/mcollective.rb +1 -2
- data/lib/mcollective/agent/bolt_tasks.ddl +253 -0
- data/lib/mcollective/agent/bolt_tasks.json +365 -0
- data/lib/mcollective/agent/bolt_tasks.rb +178 -0
- data/lib/mcollective/agent/choria_util.ddl +152 -0
- data/lib/mcollective/agent/choria_util.json +244 -0
- data/lib/mcollective/agent/rpcutil.ddl +8 -4
- data/lib/mcollective/agent/rpcutil.json +333 -0
- data/lib/mcollective/agent/scout.ddl +169 -0
- data/lib/mcollective/agent/scout.json +224 -0
- data/lib/mcollective/agents.rb +7 -6
- data/lib/mcollective/aggregate.rb +4 -4
- data/lib/mcollective/aggregate/average.rb +2 -2
- data/lib/mcollective/aggregate/base.rb +2 -2
- data/lib/mcollective/aggregate/result.rb +3 -3
- data/lib/mcollective/aggregate/result/collection_result.rb +2 -2
- data/lib/mcollective/aggregate/result/numeric_result.rb +2 -2
- data/lib/mcollective/aggregate/sum.rb +2 -2
- data/lib/mcollective/aggregate/summary.rb +3 -4
- data/lib/mcollective/application.rb +57 -21
- data/lib/mcollective/application/choria.rb +189 -0
- data/lib/mcollective/application/completion.rb +6 -6
- data/lib/mcollective/application/facts.rb +11 -11
- data/lib/mcollective/application/federation.rb +237 -0
- data/lib/mcollective/application/find.rb +4 -4
- data/lib/mcollective/application/help.rb +3 -3
- data/lib/mcollective/application/inventory.rb +3 -341
- data/lib/mcollective/application/ping.rb +5 -51
- data/lib/mcollective/application/playbook.rb +207 -0
- data/lib/mcollective/application/plugin.rb +106 -106
- data/lib/mcollective/application/rpc.rb +3 -108
- data/lib/mcollective/application/tasks.rb +425 -0
- data/lib/mcollective/applications.rb +11 -10
- data/lib/mcollective/audit/choria.rb +33 -0
- data/lib/mcollective/cache.rb +2 -4
- data/lib/mcollective/client.rb +11 -10
- data/lib/mcollective/config.rb +21 -34
- data/lib/mcollective/connector/base.rb +2 -1
- data/lib/mcollective/connector/nats.ddl +9 -0
- data/lib/mcollective/connector/nats.rb +450 -0
- data/lib/mcollective/data.rb +8 -3
- data/lib/mcollective/data/agent_data.rb +1 -1
- data/lib/mcollective/data/base.rb +6 -5
- data/lib/mcollective/data/bolt_task_data.ddl +90 -0
- data/lib/mcollective/data/bolt_task_data.rb +32 -0
- data/lib/mcollective/data/collective_data.rb +1 -1
- data/lib/mcollective/data/fact_data.rb +6 -6
- data/lib/mcollective/data/fstat_data.rb +2 -4
- data/lib/mcollective/data/result.rb +7 -2
- data/lib/mcollective/ddl/agentddl.rb +5 -17
- data/lib/mcollective/ddl/base.rb +10 -13
- data/lib/mcollective/discovery.rb +24 -39
- data/lib/mcollective/discovery/choria.ddl +11 -0
- data/lib/mcollective/discovery/choria.rb +223 -0
- data/lib/mcollective/discovery/flatfile.rb +7 -8
- data/lib/mcollective/discovery/mc.rb +2 -2
- data/lib/mcollective/discovery/stdin.rb +17 -18
- data/lib/mcollective/exceptions.rb +13 -0
- data/lib/mcollective/facts/base.rb +9 -9
- data/lib/mcollective/facts/yaml_facts.rb +12 -12
- data/lib/mcollective/generators.rb +3 -3
- data/lib/mcollective/generators/agent_generator.rb +3 -4
- data/lib/mcollective/generators/base.rb +14 -15
- data/lib/mcollective/generators/data_generator.rb +5 -6
- data/lib/mcollective/log.rb +2 -2
- data/lib/mcollective/logger/base.rb +3 -2
- data/lib/mcollective/logger/console_logger.rb +10 -10
- data/lib/mcollective/logger/file_logger.rb +7 -7
- data/lib/mcollective/logger/syslog_logger.rb +11 -15
- data/lib/mcollective/message.rb +8 -39
- data/lib/mcollective/monkey_patches.rb +2 -4
- data/lib/mcollective/optionparser.rb +2 -1
- data/lib/mcollective/pluginmanager.rb +3 -5
- data/lib/mcollective/pluginpackager.rb +1 -3
- data/lib/mcollective/pluginpackager/agent_definition.rb +3 -8
- data/lib/mcollective/pluginpackager/forge_packager.rb +7 -9
- data/lib/mcollective/pluginpackager/standard_definition.rb +1 -2
- data/lib/mcollective/registration/base.rb +18 -16
- data/lib/mcollective/rpc.rb +2 -4
- data/lib/mcollective/rpc/actionrunner.rb +16 -18
- data/lib/mcollective/rpc/agent.rb +26 -43
- data/lib/mcollective/rpc/audit.rb +1 -0
- data/lib/mcollective/rpc/client.rb +67 -85
- data/lib/mcollective/rpc/helpers.rb +55 -62
- data/lib/mcollective/rpc/progress.rb +2 -2
- data/lib/mcollective/rpc/reply.rb +17 -19
- data/lib/mcollective/rpc/request.rb +7 -5
- data/lib/mcollective/rpc/result.rb +6 -8
- data/lib/mcollective/rpc/stats.rb +49 -58
- data/lib/mcollective/security/base.rb +13 -56
- data/lib/mcollective/security/choria.rb +765 -0
- data/lib/mcollective/shell.rb +9 -4
- data/lib/mcollective/signer/base.rb +28 -0
- data/lib/mcollective/signer/choria.rb +185 -0
- data/lib/mcollective/ssl.rb +8 -6
- data/lib/mcollective/util.rb +58 -55
- data/lib/mcollective/util/bolt_support.rb +176 -0
- data/lib/mcollective/util/bolt_support/plan_runner.rb +167 -0
- data/lib/mcollective/util/bolt_support/task_result.rb +94 -0
- data/lib/mcollective/util/bolt_support/task_results.rb +128 -0
- data/lib/mcollective/util/choria.rb +946 -0
- data/lib/mcollective/util/indifferent_hash.rb +12 -0
- data/lib/mcollective/util/natswrapper.rb +242 -0
- data/lib/mcollective/util/playbook.rb +435 -0
- data/lib/mcollective/util/playbook/data_stores.rb +201 -0
- data/lib/mcollective/util/playbook/data_stores/base.rb +99 -0
- data/lib/mcollective/util/playbook/data_stores/consul_data_store.rb +88 -0
- data/lib/mcollective/util/playbook/data_stores/environment_data_store.rb +33 -0
- data/lib/mcollective/util/playbook/data_stores/etcd_data_store.rb +42 -0
- data/lib/mcollective/util/playbook/data_stores/file_data_store.rb +106 -0
- data/lib/mcollective/util/playbook/data_stores/shell_data_store.rb +103 -0
- data/lib/mcollective/util/playbook/inputs.rb +265 -0
- data/lib/mcollective/util/playbook/nodes.rb +207 -0
- data/lib/mcollective/util/playbook/nodes/mcollective_nodes.rb +86 -0
- data/lib/mcollective/util/playbook/nodes/pql_nodes.rb +40 -0
- data/lib/mcollective/util/playbook/nodes/shell_nodes.rb +55 -0
- data/lib/mcollective/util/playbook/nodes/terraform_nodes.rb +65 -0
- data/lib/mcollective/util/playbook/nodes/yaml_nodes.rb +47 -0
- data/lib/mcollective/util/playbook/playbook_logger.rb +47 -0
- data/lib/mcollective/util/playbook/puppet_logger.rb +51 -0
- data/lib/mcollective/util/playbook/report.rb +152 -0
- data/lib/mcollective/util/playbook/task_result.rb +55 -0
- data/lib/mcollective/util/playbook/tasks.rb +196 -0
- data/lib/mcollective/util/playbook/tasks/base.rb +45 -0
- data/lib/mcollective/util/playbook/tasks/graphite_event_task.rb +64 -0
- data/lib/mcollective/util/playbook/tasks/mcollective_task.rb +356 -0
- data/lib/mcollective/util/playbook/tasks/shell_task.rb +93 -0
- data/lib/mcollective/util/playbook/tasks/slack_task.rb +105 -0
- data/lib/mcollective/util/playbook/tasks/webhook_task.rb +136 -0
- data/lib/mcollective/util/playbook/template_util.rb +98 -0
- data/lib/mcollective/util/playbook/uses.rb +169 -0
- data/lib/mcollective/util/tasks_support.rb +751 -0
- data/lib/mcollective/util/tasks_support/cli.rb +260 -0
- data/lib/mcollective/util/tasks_support/default_formatter.rb +138 -0
- data/lib/mcollective/util/tasks_support/json_formatter.rb +108 -0
- data/lib/mcollective/validator.rb +6 -1
- data/lib/mcollective/validator/bolt_task_name_validator.ddl +7 -0
- data/lib/mcollective/validator/bolt_task_name_validator.rb +11 -0
- data/lib/mcollective/validator/length_validator.rb +1 -3
- metadata +65 -6
- data/lib/mcollective/application/describe_filter.rb +0 -87
- data/lib/mcollective/matcher.rb +0 -220
- data/lib/mcollective/matcher/parser.rb +0 -128
- data/lib/mcollective/matcher/scanner.rb +0 -241
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require "yaml"
|
|
2
|
+
|
|
3
|
+
module MCollective
|
|
4
|
+
module Util
|
|
5
|
+
class Playbook
|
|
6
|
+
class Nodes
|
|
7
|
+
class YamlNodes
|
|
8
|
+
def initialize
|
|
9
|
+
@group = nil
|
|
10
|
+
@file = nil
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def prepare; end
|
|
14
|
+
|
|
15
|
+
def validate_configuration!
|
|
16
|
+
raise("No node group YAML source file specified") unless @file
|
|
17
|
+
raise("Node group YAML source file %s is not readable" % @file) unless File.readable?(@file)
|
|
18
|
+
raise("No node group name specified") unless @group
|
|
19
|
+
raise("No data group %s defined in the data file %s" % [@group, @file]) unless data.include?(@group)
|
|
20
|
+
raise("Data group %s is not an array" % @group) unless data[@group].is_a?(Array)
|
|
21
|
+
raise("Data group %s is empty" % @group) if data[@group].empty?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Initialize the nodes source from a hash
|
|
25
|
+
#
|
|
26
|
+
# @param data [Hash] input with `group` and `source` keys
|
|
27
|
+
# @return [PqlNodes]
|
|
28
|
+
def from_hash(data)
|
|
29
|
+
@group = data["group"]
|
|
30
|
+
@file = data["source"]
|
|
31
|
+
|
|
32
|
+
self
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def data
|
|
36
|
+
@_data ||= YAML.safe_load(File.read(@file))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Performs the PQL query and extracts certnames
|
|
40
|
+
def discover
|
|
41
|
+
data[@group]
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require "mcollective/logger/console_logger"
|
|
2
|
+
|
|
3
|
+
module MCollective
|
|
4
|
+
module Util
|
|
5
|
+
class Playbook
|
|
6
|
+
class Playbook_Logger < Logger::Console_logger
|
|
7
|
+
attr_writer :scope
|
|
8
|
+
|
|
9
|
+
def initialize(playbook)
|
|
10
|
+
@playbook = playbook
|
|
11
|
+
@report = playbook.report
|
|
12
|
+
|
|
13
|
+
super()
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def start
|
|
17
|
+
set_level(@playbook.loglevel.intern)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def log(level, from, msg, normal_output=$stderr, last_resort_output=$stderr)
|
|
21
|
+
if @playbook.loglevel != "debug"
|
|
22
|
+
if should_show?
|
|
23
|
+
console_from = "%s#%-25s" % [@playbook.name, @playbook.context]
|
|
24
|
+
else
|
|
25
|
+
level = :debug
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if @known_levels.index(level) >= @known_levels.index(@active_level)
|
|
30
|
+
r_time = Time.now
|
|
31
|
+
s_time = r_time.strftime("%H:%M:%S")
|
|
32
|
+
|
|
33
|
+
@report.append_log(r_time, level, from, msg)
|
|
34
|
+
|
|
35
|
+
normal_output.puts("%s %s: %s %s" % [colorize(level, level[0].capitalize), s_time, console_from, msg])
|
|
36
|
+
end
|
|
37
|
+
rescue
|
|
38
|
+
last_resort_output.puts("%s: %s" % [level, msg])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def should_show?
|
|
42
|
+
!caller(1..5).grep(/playbook/).empty?
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require "mcollective/logger/console_logger"
|
|
2
|
+
|
|
3
|
+
module MCollective
|
|
4
|
+
module Util
|
|
5
|
+
class Playbook
|
|
6
|
+
class Puppet_Logger < Logger::Console_logger
|
|
7
|
+
attr_writer :scope
|
|
8
|
+
|
|
9
|
+
def initialize(playbook)
|
|
10
|
+
@playbook = playbook
|
|
11
|
+
@report = playbook.report
|
|
12
|
+
|
|
13
|
+
super()
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def start
|
|
17
|
+
set_level(@playbook.loglevel.intern)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def log(level, from, msg, normal_output=$stderr, last_resort_output=$stderr)
|
|
21
|
+
return unless should_show?(level)
|
|
22
|
+
|
|
23
|
+
logmethod = case level
|
|
24
|
+
when :info
|
|
25
|
+
:notice
|
|
26
|
+
when :warn
|
|
27
|
+
:warning
|
|
28
|
+
when :error
|
|
29
|
+
:err
|
|
30
|
+
when :fatal
|
|
31
|
+
:crit
|
|
32
|
+
else
|
|
33
|
+
:debug
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if @scope
|
|
37
|
+
Puppet::Util::Log.log_func(@scope, logmethod, [msg])
|
|
38
|
+
else
|
|
39
|
+
Puppet.send(logmethod, msg)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def should_show?(level)
|
|
44
|
+
return true unless level == :info
|
|
45
|
+
|
|
46
|
+
!caller(2..5).grep(/playbook/).empty?
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
module MCollective
|
|
2
|
+
module Util
|
|
3
|
+
class Playbook
|
|
4
|
+
class Report
|
|
5
|
+
attr_reader :timestamp
|
|
6
|
+
|
|
7
|
+
def initialize(playbook)
|
|
8
|
+
@playbook = playbook
|
|
9
|
+
@logs = []
|
|
10
|
+
@timestamp = Time.now.utc
|
|
11
|
+
@version = 1
|
|
12
|
+
@nodes = {}
|
|
13
|
+
@tasks = []
|
|
14
|
+
@success = false
|
|
15
|
+
@final = false
|
|
16
|
+
|
|
17
|
+
@metrics = {
|
|
18
|
+
"start_time" => @timestamp,
|
|
19
|
+
"end_time" => @timestamp,
|
|
20
|
+
"run_time" => 0,
|
|
21
|
+
"task_count" => 0,
|
|
22
|
+
"task_types" => {}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@inputs = {
|
|
26
|
+
"static" => {},
|
|
27
|
+
"dynamic" => []
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def start!
|
|
32
|
+
@metrics["start_time"] = Time.now.utc
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def elapsed_time
|
|
36
|
+
Time.now.utc - @metrics["start_time"]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def finalize(success, fail_msg=nil)
|
|
40
|
+
return(to_report) if @final
|
|
41
|
+
|
|
42
|
+
@success = success
|
|
43
|
+
@fail_message = fail_msg
|
|
44
|
+
|
|
45
|
+
store_playbook_metadata
|
|
46
|
+
store_static_inputs
|
|
47
|
+
store_dynamic_inputs
|
|
48
|
+
store_node_groups
|
|
49
|
+
store_task_results
|
|
50
|
+
calculate_metrics
|
|
51
|
+
|
|
52
|
+
@final = true
|
|
53
|
+
|
|
54
|
+
to_report
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def to_report
|
|
58
|
+
{
|
|
59
|
+
"report" => {
|
|
60
|
+
"version" => @version,
|
|
61
|
+
"timestamp" => @timestamp,
|
|
62
|
+
"success" => @success,
|
|
63
|
+
"playbook_error" => @fail_message
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
"playbook" => {
|
|
67
|
+
"name" => @playbook_name,
|
|
68
|
+
"version" => @playbook_version
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
"inputs" => @inputs,
|
|
72
|
+
"nodes" => @nodes,
|
|
73
|
+
"tasks" => @tasks,
|
|
74
|
+
"metrics" => @metrics,
|
|
75
|
+
"logs" => @logs
|
|
76
|
+
}
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def calculate_metrics
|
|
80
|
+
@metrics["end_time"] = Time.now.utc
|
|
81
|
+
@metrics["run_time"] = @metrics["end_time"] - @metrics["start_time"]
|
|
82
|
+
@metrics["task_count"] = @tasks.size
|
|
83
|
+
|
|
84
|
+
@tasks.each do |task|
|
|
85
|
+
@metrics["task_types"][task["type"]] ||= {
|
|
86
|
+
"count" => 0,
|
|
87
|
+
"total_time" => 0,
|
|
88
|
+
"pass" => 0,
|
|
89
|
+
"fail" => 0
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
metrics = @metrics["task_types"][task["type"]]
|
|
93
|
+
|
|
94
|
+
metrics["count"] += 1
|
|
95
|
+
metrics["total_time"] += task["run_time"]
|
|
96
|
+
task["success"] ? metrics["pass"] += 1 : metrics["fail"] += 1
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
@metrics
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def store_task_results
|
|
103
|
+
@playbook.task_results.each do |result|
|
|
104
|
+
@tasks << {
|
|
105
|
+
"type" => result.task_type,
|
|
106
|
+
"set" => result.set,
|
|
107
|
+
"description" => result.description,
|
|
108
|
+
"start_time" => result.start_time.utc,
|
|
109
|
+
"end_time" => result.end_time.utc,
|
|
110
|
+
"run_time" => result.run_time,
|
|
111
|
+
"ran" => result.ran,
|
|
112
|
+
"msg" => result.msg,
|
|
113
|
+
"success" => result.success
|
|
114
|
+
}
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
@tasks
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def store_playbook_metadata
|
|
121
|
+
@playbook_name = @playbook.name
|
|
122
|
+
@playbook_version = @playbook.version
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def store_node_groups
|
|
126
|
+
@playbook.nodes.each do |key|
|
|
127
|
+
@nodes[key] = @playbook.discovered_nodes(key)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def store_dynamic_inputs
|
|
132
|
+
@inputs["dynamic"] = @playbook.dynamic_inputs
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def store_static_inputs
|
|
136
|
+
@playbook.static_inputs.each do |key|
|
|
137
|
+
@inputs["static"][key] = @playbook.input_value(key)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def append_log(time, level, from, msg)
|
|
142
|
+
@logs << {
|
|
143
|
+
"time" => time.utc,
|
|
144
|
+
"level" => level.to_s,
|
|
145
|
+
"from" => from.strip,
|
|
146
|
+
"msg" => msg
|
|
147
|
+
}
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module MCollective
|
|
2
|
+
module Util
|
|
3
|
+
class Playbook
|
|
4
|
+
class TaskResult
|
|
5
|
+
attr_accessor :success, :msg, :data, :ran, :task, :set, :start_time, :end_time, :description
|
|
6
|
+
|
|
7
|
+
def initialize(task)
|
|
8
|
+
@start_time = Time.now
|
|
9
|
+
@end_time = @start_time
|
|
10
|
+
@ran = false
|
|
11
|
+
@task = task
|
|
12
|
+
@description = task[:description]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def task_type
|
|
16
|
+
@task[:type]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run_time
|
|
20
|
+
@end_time - @start_time
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def success?
|
|
24
|
+
!!success
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def timed_run(set)
|
|
28
|
+
@start_time = Time.now
|
|
29
|
+
@set = set
|
|
30
|
+
|
|
31
|
+
begin
|
|
32
|
+
@success, @msg, @data = task[:runner].run
|
|
33
|
+
|
|
34
|
+
if !@success && task[:properties]["fail_ok"] && task[:properties]["tries"] == 1
|
|
35
|
+
Log.warn("Task failed but fail_ok is true, treating as success")
|
|
36
|
+
@success = true
|
|
37
|
+
end
|
|
38
|
+
rescue
|
|
39
|
+
@success = false
|
|
40
|
+
@data = [$!]
|
|
41
|
+
@msg = "Running task %s failed unexpectedly: %s: %s" % [task.to_s, $!.class, $!.to_s]
|
|
42
|
+
|
|
43
|
+
Log.warn(@msg)
|
|
44
|
+
Log.debug($!.backtrace.join("\n\t"))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
@end_time = Time.now
|
|
48
|
+
@ran = true
|
|
49
|
+
|
|
50
|
+
self
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
require_relative "task_result"
|
|
2
|
+
require_relative "tasks/base"
|
|
3
|
+
require_relative "tasks/graphite_event_task"
|
|
4
|
+
require_relative "tasks/mcollective_task"
|
|
5
|
+
require_relative "tasks/shell_task"
|
|
6
|
+
require_relative "tasks/slack_task"
|
|
7
|
+
require_relative "tasks/webhook_task"
|
|
8
|
+
|
|
9
|
+
module MCollective
|
|
10
|
+
module Util
|
|
11
|
+
class Playbook
|
|
12
|
+
class Tasks
|
|
13
|
+
include TemplateUtil
|
|
14
|
+
|
|
15
|
+
attr_reader :tasks, :results
|
|
16
|
+
|
|
17
|
+
def initialize(playbook)
|
|
18
|
+
@playbook = playbook
|
|
19
|
+
|
|
20
|
+
reset
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def reset
|
|
24
|
+
@results = []
|
|
25
|
+
@tasks = {
|
|
26
|
+
"tasks" => [],
|
|
27
|
+
"pre_task" => [],
|
|
28
|
+
"post_task" => [],
|
|
29
|
+
"on_fail" => [],
|
|
30
|
+
"on_success" => [],
|
|
31
|
+
"pre_book" => [],
|
|
32
|
+
"post_book" => []
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def prepare; end
|
|
37
|
+
|
|
38
|
+
# @todo support types of runner
|
|
39
|
+
def runner_for(type)
|
|
40
|
+
klass_name = "%sTask" % type.capitalize
|
|
41
|
+
|
|
42
|
+
Tasks.const_get(klass_name).new(@playbook)
|
|
43
|
+
rescue NameError
|
|
44
|
+
raise("Cannot find a handler for Task type %s" % type)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Runs a specific task
|
|
48
|
+
#
|
|
49
|
+
# @param task [Hash] a task entry
|
|
50
|
+
# @param set [String] the set the task is running in
|
|
51
|
+
# @param hooks [Boolean] indicates if hooks should be run
|
|
52
|
+
# @return [Boolean] indicating task success
|
|
53
|
+
def run_task(task, set, hooks=true)
|
|
54
|
+
properties = task[:properties]
|
|
55
|
+
result = task[:result]
|
|
56
|
+
task_runner = task[:runner]
|
|
57
|
+
|
|
58
|
+
Log.info("About to run task: %s" % t(task[:runner].description))
|
|
59
|
+
result.description = t(task[:runner].description)
|
|
60
|
+
|
|
61
|
+
if hooks && !run_set("pre_task")
|
|
62
|
+
Log.warn("Failing task because a critical pre_task hook failed")
|
|
63
|
+
return false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if properties["pre_sleep"]
|
|
67
|
+
Log.info("Sleeping %d seconds before check" % [properties["pre_sleep"]])
|
|
68
|
+
sleep(Integer(properties["pre_sleep"]))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
(1..properties["tries"]).each do |try|
|
|
72
|
+
task_runner.from_hash(t(properties))
|
|
73
|
+
task_runner.validate_configuration!
|
|
74
|
+
|
|
75
|
+
@results << result.timed_run(set)
|
|
76
|
+
|
|
77
|
+
if result.success?
|
|
78
|
+
Log.info(result.msg)
|
|
79
|
+
else
|
|
80
|
+
Log.error(result.msg)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
if try != properties["tries"] && !result.success
|
|
84
|
+
Log.warn("Task failed on try %d/%d, sleeping %ds: %s" % [try, properties["tries"], properties["try_sleep"], result.msg])
|
|
85
|
+
sleep(Integer(properties["try_sleep"]))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
break if result.success
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
if hooks && !run_set("post_task")
|
|
92
|
+
Log.warn("Failing task because a critical post_task hook failed")
|
|
93
|
+
return false
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
result.success
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Runs a specific task set
|
|
100
|
+
#
|
|
101
|
+
# @param set [String] one of the known task sets
|
|
102
|
+
# @return [Boolean] true if all tasks and all their hooks passed
|
|
103
|
+
def run_set(set)
|
|
104
|
+
set_tasks = @tasks[set]
|
|
105
|
+
|
|
106
|
+
return true if set_tasks.empty?
|
|
107
|
+
|
|
108
|
+
@playbook.in_context(set) do
|
|
109
|
+
Log.info("About to run task set %s with %d task(s)" % [set, set_tasks.size])
|
|
110
|
+
|
|
111
|
+
# would typically use map here but you cant break out of a map and keep the thus far built up array
|
|
112
|
+
# so it's either this or a inject loop
|
|
113
|
+
passed = set_tasks.take_while do |task|
|
|
114
|
+
@playbook.in_context("%s.%s" % [set, task[:type]]) { run_task(task, set, set == "tasks") }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
set_success = passed.size == set_tasks.size
|
|
118
|
+
|
|
119
|
+
Log.info("Done running task set %s with %d task(s): success: %s" % [set, set_tasks.size, set_success])
|
|
120
|
+
|
|
121
|
+
set_success
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def run
|
|
126
|
+
@playbook.in_context("running") do
|
|
127
|
+
unless run_set("pre_book")
|
|
128
|
+
Log.warn("Playbook pre_book hook failed to run, failing entire playbook")
|
|
129
|
+
return false
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
success = run_set("tasks")
|
|
133
|
+
|
|
134
|
+
Log.info("Finished running main tasks in playbook: success: %s" % success)
|
|
135
|
+
|
|
136
|
+
if success
|
|
137
|
+
success = run_set("on_success")
|
|
138
|
+
else
|
|
139
|
+
run_set("on_fail")
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
unless run_set("post_book")
|
|
143
|
+
Log.warn("Playbook post_book hook failed to run, failing entire playbookbook")
|
|
144
|
+
return false
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
success
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def load_tasks(data, set)
|
|
152
|
+
data.each_with_index do |task, idx|
|
|
153
|
+
task.each do |type, props|
|
|
154
|
+
Log.debug("Loading task %d of type %s into %s" % [idx, type, set])
|
|
155
|
+
|
|
156
|
+
runner = runner_for(type)
|
|
157
|
+
runner.description = props.fetch("description", "%s task" % [type])
|
|
158
|
+
|
|
159
|
+
task_data = {
|
|
160
|
+
:description => runner.description,
|
|
161
|
+
:type => type,
|
|
162
|
+
:runner => runner,
|
|
163
|
+
:properties => {
|
|
164
|
+
"tries" => 1,
|
|
165
|
+
"try_sleep" => 10,
|
|
166
|
+
"fail_ok" => false
|
|
167
|
+
}.merge(props)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
runner.fail_ok = task_data[:properties]["fail_ok"]
|
|
171
|
+
|
|
172
|
+
task_data[:result] = TaskResult.new(task_data)
|
|
173
|
+
|
|
174
|
+
@tasks[set] << task_data
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
@tasks[set]
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def from_hash(data)
|
|
182
|
+
case data
|
|
183
|
+
when Array
|
|
184
|
+
load_tasks(data, "tasks")
|
|
185
|
+
when Hash
|
|
186
|
+
data.each do |set, tasks|
|
|
187
|
+
load_tasks(tasks, set)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
self
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|