choria-mcorpc-support 2.22.1 → 2.23.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mcollective.rb +1 -1
  3. data/lib/mcollective/agent/bolt_tasks.ddl +235 -0
  4. data/lib/mcollective/agent/bolt_tasks.json +347 -0
  5. data/lib/mcollective/agent/bolt_tasks.rb +176 -0
  6. data/lib/mcollective/agent/choria_util.ddl +152 -0
  7. data/lib/mcollective/agent/choria_util.json +244 -0
  8. data/lib/mcollective/agent/rpcutil.ddl +7 -3
  9. data/lib/mcollective/agent/rpcutil.json +333 -0
  10. data/lib/mcollective/agent/scout.ddl +169 -0
  11. data/lib/mcollective/agent/scout.json +224 -0
  12. data/lib/mcollective/agents.rb +7 -6
  13. data/lib/mcollective/aggregate.rb +4 -4
  14. data/lib/mcollective/aggregate/average.rb +2 -2
  15. data/lib/mcollective/aggregate/base.rb +2 -2
  16. data/lib/mcollective/aggregate/result.rb +3 -3
  17. data/lib/mcollective/aggregate/result/collection_result.rb +2 -2
  18. data/lib/mcollective/aggregate/result/numeric_result.rb +2 -2
  19. data/lib/mcollective/aggregate/sum.rb +2 -2
  20. data/lib/mcollective/aggregate/summary.rb +3 -4
  21. data/lib/mcollective/application.rb +57 -21
  22. data/lib/mcollective/application/choria.rb +249 -0
  23. data/lib/mcollective/application/completion.rb +6 -6
  24. data/lib/mcollective/application/describe_filter.rb +20 -20
  25. data/lib/mcollective/application/facts.rb +11 -11
  26. data/lib/mcollective/application/federation.rb +239 -0
  27. data/lib/mcollective/application/find.rb +4 -4
  28. data/lib/mcollective/application/help.rb +3 -3
  29. data/lib/mcollective/application/inventory.rb +3 -341
  30. data/lib/mcollective/application/ping.rb +3 -77
  31. data/lib/mcollective/application/playbook.rb +207 -0
  32. data/lib/mcollective/application/plugin.rb +106 -106
  33. data/lib/mcollective/application/rpc.rb +3 -108
  34. data/lib/mcollective/application/tasks.rb +416 -0
  35. data/lib/mcollective/applications.rb +11 -10
  36. data/lib/mcollective/audit/choria.rb +33 -0
  37. data/lib/mcollective/cache.rb +2 -4
  38. data/lib/mcollective/client.rb +11 -10
  39. data/lib/mcollective/config.rb +21 -26
  40. data/lib/mcollective/connector/base.rb +2 -1
  41. data/lib/mcollective/connector/nats.ddl +9 -0
  42. data/lib/mcollective/connector/nats.rb +450 -0
  43. data/lib/mcollective/data.rb +8 -3
  44. data/lib/mcollective/data/agent_data.rb +1 -1
  45. data/lib/mcollective/data/base.rb +6 -5
  46. data/lib/mcollective/data/bolt_task_data.ddl +90 -0
  47. data/lib/mcollective/data/bolt_task_data.rb +32 -0
  48. data/lib/mcollective/data/collective_data.rb +1 -1
  49. data/lib/mcollective/data/fact_data.rb +6 -6
  50. data/lib/mcollective/data/fstat_data.rb +2 -4
  51. data/lib/mcollective/data/result.rb +7 -2
  52. data/lib/mcollective/ddl/agentddl.rb +5 -17
  53. data/lib/mcollective/ddl/base.rb +10 -13
  54. data/lib/mcollective/discovery.rb +12 -26
  55. data/lib/mcollective/discovery/choria.ddl +11 -0
  56. data/lib/mcollective/discovery/choria.rb +223 -0
  57. data/lib/mcollective/discovery/flatfile.rb +7 -8
  58. data/lib/mcollective/discovery/mc.rb +2 -2
  59. data/lib/mcollective/discovery/stdin.rb +17 -18
  60. data/lib/mcollective/exceptions.rb +13 -0
  61. data/lib/mcollective/facts/base.rb +9 -9
  62. data/lib/mcollective/facts/yaml_facts.rb +12 -12
  63. data/lib/mcollective/generators.rb +3 -3
  64. data/lib/mcollective/generators/agent_generator.rb +3 -4
  65. data/lib/mcollective/generators/base.rb +14 -15
  66. data/lib/mcollective/generators/data_generator.rb +5 -6
  67. data/lib/mcollective/log.rb +2 -2
  68. data/lib/mcollective/logger/base.rb +3 -2
  69. data/lib/mcollective/logger/console_logger.rb +10 -10
  70. data/lib/mcollective/logger/file_logger.rb +7 -7
  71. data/lib/mcollective/logger/syslog_logger.rb +11 -15
  72. data/lib/mcollective/matcher.rb +14 -14
  73. data/lib/mcollective/matcher/parser.rb +31 -41
  74. data/lib/mcollective/matcher/scanner.rb +69 -74
  75. data/lib/mcollective/message.rb +10 -17
  76. data/lib/mcollective/monkey_patches.rb +2 -4
  77. data/lib/mcollective/optionparser.rb +1 -0
  78. data/lib/mcollective/pluginmanager.rb +3 -5
  79. data/lib/mcollective/pluginpackager.rb +1 -3
  80. data/lib/mcollective/pluginpackager/agent_definition.rb +3 -8
  81. data/lib/mcollective/pluginpackager/forge_packager.rb +7 -9
  82. data/lib/mcollective/pluginpackager/standard_definition.rb +1 -2
  83. data/lib/mcollective/registration/base.rb +18 -16
  84. data/lib/mcollective/rpc.rb +2 -4
  85. data/lib/mcollective/rpc/actionrunner.rb +16 -18
  86. data/lib/mcollective/rpc/agent.rb +26 -43
  87. data/lib/mcollective/rpc/audit.rb +1 -0
  88. data/lib/mcollective/rpc/client.rb +67 -85
  89. data/lib/mcollective/rpc/helpers.rb +55 -62
  90. data/lib/mcollective/rpc/progress.rb +2 -2
  91. data/lib/mcollective/rpc/reply.rb +17 -19
  92. data/lib/mcollective/rpc/request.rb +7 -5
  93. data/lib/mcollective/rpc/result.rb +6 -8
  94. data/lib/mcollective/rpc/stats.rb +49 -58
  95. data/lib/mcollective/security/base.rb +29 -36
  96. data/lib/mcollective/security/choria.rb +765 -0
  97. data/lib/mcollective/shell.rb +9 -4
  98. data/lib/mcollective/signer/base.rb +28 -0
  99. data/lib/mcollective/signer/choria.rb +185 -0
  100. data/lib/mcollective/ssl.rb +8 -6
  101. data/lib/mcollective/util.rb +52 -53
  102. data/lib/mcollective/util/bolt_support.rb +176 -0
  103. data/lib/mcollective/util/bolt_support/plan_runner.rb +167 -0
  104. data/lib/mcollective/util/bolt_support/task_result.rb +94 -0
  105. data/lib/mcollective/util/bolt_support/task_results.rb +128 -0
  106. data/lib/mcollective/util/choria.rb +1103 -0
  107. data/lib/mcollective/util/indifferent_hash.rb +12 -0
  108. data/lib/mcollective/util/natswrapper.rb +242 -0
  109. data/lib/mcollective/util/playbook.rb +435 -0
  110. data/lib/mcollective/util/playbook/data_stores.rb +201 -0
  111. data/lib/mcollective/util/playbook/data_stores/base.rb +99 -0
  112. data/lib/mcollective/util/playbook/data_stores/consul_data_store.rb +88 -0
  113. data/lib/mcollective/util/playbook/data_stores/environment_data_store.rb +33 -0
  114. data/lib/mcollective/util/playbook/data_stores/etcd_data_store.rb +42 -0
  115. data/lib/mcollective/util/playbook/data_stores/file_data_store.rb +106 -0
  116. data/lib/mcollective/util/playbook/data_stores/shell_data_store.rb +103 -0
  117. data/lib/mcollective/util/playbook/inputs.rb +265 -0
  118. data/lib/mcollective/util/playbook/nodes.rb +207 -0
  119. data/lib/mcollective/util/playbook/nodes/mcollective_nodes.rb +86 -0
  120. data/lib/mcollective/util/playbook/nodes/pql_nodes.rb +40 -0
  121. data/lib/mcollective/util/playbook/nodes/shell_nodes.rb +55 -0
  122. data/lib/mcollective/util/playbook/nodes/terraform_nodes.rb +65 -0
  123. data/lib/mcollective/util/playbook/nodes/yaml_nodes.rb +47 -0
  124. data/lib/mcollective/util/playbook/playbook_logger.rb +47 -0
  125. data/lib/mcollective/util/playbook/puppet_logger.rb +51 -0
  126. data/lib/mcollective/util/playbook/report.rb +152 -0
  127. data/lib/mcollective/util/playbook/task_result.rb +55 -0
  128. data/lib/mcollective/util/playbook/tasks.rb +196 -0
  129. data/lib/mcollective/util/playbook/tasks/base.rb +45 -0
  130. data/lib/mcollective/util/playbook/tasks/graphite_event_task.rb +64 -0
  131. data/lib/mcollective/util/playbook/tasks/mcollective_task.rb +356 -0
  132. data/lib/mcollective/util/playbook/tasks/shell_task.rb +93 -0
  133. data/lib/mcollective/util/playbook/tasks/slack_task.rb +105 -0
  134. data/lib/mcollective/util/playbook/tasks/webhook_task.rb +136 -0
  135. data/lib/mcollective/util/playbook/template_util.rb +98 -0
  136. data/lib/mcollective/util/playbook/uses.rb +169 -0
  137. data/lib/mcollective/util/tasks_support.rb +733 -0
  138. data/lib/mcollective/util/tasks_support/cli.rb +260 -0
  139. data/lib/mcollective/util/tasks_support/default_formatter.rb +138 -0
  140. data/lib/mcollective/util/tasks_support/json_formatter.rb +108 -0
  141. data/lib/mcollective/validator.rb +6 -1
  142. data/lib/mcollective/validator/bolt_task_name_validator.ddl +7 -0
  143. data/lib/mcollective/validator/bolt_task_name_validator.rb +11 -0
  144. data/lib/mcollective/validator/length_validator.rb +1 -3
  145. metadata +67 -4
@@ -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