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,176 @@
|
|
|
1
|
+
require "mcollective"
|
|
2
|
+
require_relative "choria"
|
|
3
|
+
require_relative "playbook"
|
|
4
|
+
|
|
5
|
+
require_relative "bolt_support/task_result"
|
|
6
|
+
require_relative "bolt_support/task_results"
|
|
7
|
+
require_relative "bolt_support/plan_runner"
|
|
8
|
+
|
|
9
|
+
module MCollective
|
|
10
|
+
module Util
|
|
11
|
+
class BoltSupport
|
|
12
|
+
def choria
|
|
13
|
+
@_choria ||= Choria.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Converts the current Puppet loglevel to one we understand
|
|
17
|
+
#
|
|
18
|
+
# @return ["debug", "info", "warn", "error", "fatal"]
|
|
19
|
+
def self.loglevel
|
|
20
|
+
case Puppet::Util::Log.level
|
|
21
|
+
when :notice, :warning
|
|
22
|
+
"warn"
|
|
23
|
+
when :err
|
|
24
|
+
"error"
|
|
25
|
+
when :alert, :emerg, :crit
|
|
26
|
+
"fatal"
|
|
27
|
+
else
|
|
28
|
+
Puppet::Util::Log.level.to_s
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Configures MCollective and initialize the Bolt Support class
|
|
33
|
+
#
|
|
34
|
+
# @return [BoltSupport]
|
|
35
|
+
def self.init_choria
|
|
36
|
+
Config.instance.loadconfig(Util.config_file_for_user) unless Config.instance.configured
|
|
37
|
+
|
|
38
|
+
new
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Creates a configured instance of the Playbook
|
|
42
|
+
#
|
|
43
|
+
# @return [Playbook]
|
|
44
|
+
def playbook
|
|
45
|
+
@_playbook ||= begin
|
|
46
|
+
pb = Playbook.new(self.class.loglevel)
|
|
47
|
+
pb.logger = Playbook::Puppet_Logger
|
|
48
|
+
pb.set_logger_level
|
|
49
|
+
pb
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def nodes
|
|
54
|
+
@_nodes ||= Playbook::Nodes.new(playbook)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Discovers nodes using playbook node sets
|
|
58
|
+
#
|
|
59
|
+
# @param scope [Puppet::Parser::Scope] scope to log against
|
|
60
|
+
# @param type [String] a known node set type like `terraform`
|
|
61
|
+
# @param properties [Hash] properties valid for the node set type
|
|
62
|
+
def discover_nodes(scope, type, properties)
|
|
63
|
+
uses_properties = properties.delete("uses") || {}
|
|
64
|
+
playbook.logger.scope = scope
|
|
65
|
+
assign_playbook_name(scope)
|
|
66
|
+
playbook.uses.from_hash(uses_properties)
|
|
67
|
+
|
|
68
|
+
nodes.from_hash("task_nodes" => properties.merge(
|
|
69
|
+
"type" => type,
|
|
70
|
+
"uses" => uses_properties.keys
|
|
71
|
+
))
|
|
72
|
+
|
|
73
|
+
nodes.prepare
|
|
74
|
+
nodes["task_nodes"]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Retrieves a data item from a data store
|
|
78
|
+
#
|
|
79
|
+
# @param scope [Puppet::Parser::Scope] scope to log against
|
|
80
|
+
# @param item [String] the item to fetch
|
|
81
|
+
# @param properties [Hash] the data source properties
|
|
82
|
+
def data_read(scope, item, properties)
|
|
83
|
+
playbook.logger.scope = scope
|
|
84
|
+
assign_playbook_name(scope)
|
|
85
|
+
playbook.data_stores.from_hash("plan_store" => properties)
|
|
86
|
+
playbook.data_stores.prepare
|
|
87
|
+
playbook.data_stores.read("plan_store/%s" % item)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Writes a value to a data store
|
|
91
|
+
#
|
|
92
|
+
# @param scope [Puppet::Parser::Scope] scope to log against
|
|
93
|
+
# @param item [String] the item to fetch
|
|
94
|
+
# @param value [String] the item to fetch
|
|
95
|
+
# @param properties [Hash] the data source properties
|
|
96
|
+
# @return [String] the data that was written
|
|
97
|
+
def data_write(scope, item, value, properties)
|
|
98
|
+
config = {"plan_store" => properties}
|
|
99
|
+
|
|
100
|
+
playbook.logger.scope = scope
|
|
101
|
+
assign_playbook_name(scope)
|
|
102
|
+
playbook.data_stores.from_hash(config)
|
|
103
|
+
playbook.data_stores.prepare
|
|
104
|
+
playbook.data_stores.write("plan_store/%s" % item, value)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Performs a block within a lock in a data store
|
|
108
|
+
#
|
|
109
|
+
# @param scope [Puppet::Parser::Scope] scope to log against
|
|
110
|
+
# @param item [String] the lock key
|
|
111
|
+
# @param properties [Hash] the data source properties
|
|
112
|
+
def data_lock(scope, item, properties, &blk)
|
|
113
|
+
locked = false
|
|
114
|
+
lock_path = "plan_store/%s" % item
|
|
115
|
+
config = {"plan_store" => properties}
|
|
116
|
+
|
|
117
|
+
playbook.logger.scope = scope
|
|
118
|
+
assign_playbook_name(scope)
|
|
119
|
+
playbook.data_stores.from_hash(config)
|
|
120
|
+
playbook.data_stores.prepare
|
|
121
|
+
|
|
122
|
+
playbook.data_stores.lock(lock_path)
|
|
123
|
+
locked = true
|
|
124
|
+
|
|
125
|
+
yield
|
|
126
|
+
ensure
|
|
127
|
+
playbook.data_stores.release(lock_path) if locked
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Runs a playbook task and return execution results
|
|
131
|
+
#
|
|
132
|
+
# @param scope [Puppet::Parser::Scope] scope to log against
|
|
133
|
+
# @param type [String] the task type
|
|
134
|
+
# @param properties [Hash] properties passed to the task
|
|
135
|
+
# @return [BoltSupport::TaskResults]
|
|
136
|
+
def run_task(scope, type, properties)
|
|
137
|
+
task_properties = properties.reject {|k, _| k.start_with?("_") }
|
|
138
|
+
playbook.logger.scope = scope
|
|
139
|
+
assign_playbook_name(scope)
|
|
140
|
+
|
|
141
|
+
tasks = playbook.tasks.load_tasks([type => task_properties], "tasks")
|
|
142
|
+
|
|
143
|
+
playbook.tasks.run_task(tasks[0], "plan", false)
|
|
144
|
+
|
|
145
|
+
result = tasks[0][:result]
|
|
146
|
+
runner = tasks[0][:runner]
|
|
147
|
+
|
|
148
|
+
execution_result = runner.to_execution_result([result.success, result.msg, result.data])
|
|
149
|
+
|
|
150
|
+
results = execution_result.map do |node, result_properties|
|
|
151
|
+
TaskResult.new(node, JSON.parse(result_properties.to_json))
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
task_results = TaskResults.new(results, nil)
|
|
155
|
+
task_results.message = result.msg
|
|
156
|
+
|
|
157
|
+
return task_results if result.success
|
|
158
|
+
return task_results if properties.fetch("fail_ok", false)
|
|
159
|
+
return task_results if properties["_catch_errors"]
|
|
160
|
+
|
|
161
|
+
raise(result.msg)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Assigns the playbook name based on the fact choria.plan
|
|
165
|
+
#
|
|
166
|
+
# @see PlanRunner#in_environment
|
|
167
|
+
def assign_playbook_name(scope)
|
|
168
|
+
return unless scope
|
|
169
|
+
return unless scope["facts"]["choria"]
|
|
170
|
+
return unless scope["facts"]["choria"]["playbook"]
|
|
171
|
+
|
|
172
|
+
playbook.metadata["name"] = scope["facts"]["choria"]["playbook"]
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
require "puppet"
|
|
2
|
+
require "puppet_pal"
|
|
3
|
+
require "tmpdir"
|
|
4
|
+
|
|
5
|
+
module MCollective
|
|
6
|
+
module Util
|
|
7
|
+
class BoltSupport
|
|
8
|
+
class PlanRunner
|
|
9
|
+
def self.init_puppet
|
|
10
|
+
TaskResults.include_iterable
|
|
11
|
+
Puppet::Util::Log.newdestination(:console)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
init_puppet
|
|
15
|
+
|
|
16
|
+
attr_reader :modulepath
|
|
17
|
+
|
|
18
|
+
# @param plan [String] the name of the plan to use
|
|
19
|
+
# @param tmpdir [String] the path to an already existing temporary directory
|
|
20
|
+
# @param modulepath [String,nil] a : seperated list of locations to look for modules, uses puppet basemodulepath if nil
|
|
21
|
+
# @param loglevel [debug, info, warn, err]
|
|
22
|
+
def initialize(plan, tmpdir, modulepath, loglevel)
|
|
23
|
+
@plan = plan
|
|
24
|
+
@loglevel = loglevel
|
|
25
|
+
@tmpdir = tmpdir
|
|
26
|
+
|
|
27
|
+
raise("A temporary directory could not be created") unless @tmpdir
|
|
28
|
+
raise("A temporary directory could not be created") unless File.directory?(@tmpdir)
|
|
29
|
+
|
|
30
|
+
@modulepath = modulepath
|
|
31
|
+
|
|
32
|
+
unless @modulepath
|
|
33
|
+
initialize_settings
|
|
34
|
+
@modulepath = Puppet.settings[:basemodulepath]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
@modulepath = @modulepath.split(":")
|
|
38
|
+
|
|
39
|
+
Puppet[:log_level] = @loglevel
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Determines if the requested plan exist
|
|
43
|
+
#
|
|
44
|
+
# @return [Boolean]
|
|
45
|
+
def exist?
|
|
46
|
+
with_script_compiler do |compiler|
|
|
47
|
+
return !!compiler.plan_signature(@plan)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Initialize Puppet to use the configured tmp dir
|
|
52
|
+
def puppet_cli_options
|
|
53
|
+
Puppet::Settings::REQUIRED_APP_SETTINGS.map do |setting|
|
|
54
|
+
"--%s %s" % [setting, @tmpdir]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Retrieves the signature of a plan - its parameters and types
|
|
59
|
+
#
|
|
60
|
+
# NOTE: at present it's not possible to extract description or default values
|
|
61
|
+
#
|
|
62
|
+
# @return [Hash]
|
|
63
|
+
def plan_signature
|
|
64
|
+
with_script_compiler do |compiler|
|
|
65
|
+
sig = compiler.plan_signature(@plan)
|
|
66
|
+
|
|
67
|
+
raise("Cannot find playbook %s in %s" % [@plan, @modulepath.join(":")]) unless sig
|
|
68
|
+
|
|
69
|
+
sig.params_type.elements.map do |elem|
|
|
70
|
+
[elem.name, {
|
|
71
|
+
"type" => elem.value_type.to_s,
|
|
72
|
+
"required" => !elem.key_type.is_a?(Puppet::Pops::Types::POptionalType)
|
|
73
|
+
}]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Yields a PAL script compiler in the temporary environment
|
|
79
|
+
def with_script_compiler(&block)
|
|
80
|
+
in_environment do |env|
|
|
81
|
+
env.with_script_compiler(&block)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Facts to use in the environment
|
|
86
|
+
def facts
|
|
87
|
+
{
|
|
88
|
+
"choria" => {
|
|
89
|
+
"playbook" => @plan
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def initialize_settings
|
|
95
|
+
Puppet.initialize_settings(puppet_cli_options) unless Puppet.settings.global_defaults_initialized?
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Sets up a temporary environment
|
|
99
|
+
def in_environment(&block)
|
|
100
|
+
initialize_settings
|
|
101
|
+
|
|
102
|
+
Puppet::Pal.in_tmp_environment("choria", :modulepath => @modulepath, :facts => facts, &block)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Converts a Puppet type into something mcollective understands
|
|
106
|
+
#
|
|
107
|
+
# This is inevitably hacky by its nature, there is no way for me to
|
|
108
|
+
# parse the types. PAL might get some helpers for this but till then
|
|
109
|
+
# this is going to have to be best efforts.
|
|
110
|
+
#
|
|
111
|
+
# When there is a too complex situation users can always put in --input
|
|
112
|
+
# and some JSON to work around it until something better comes around
|
|
113
|
+
#
|
|
114
|
+
# @param type [String] a puppet type
|
|
115
|
+
# @return [Class, Boolean] The data type, if its an array input or not
|
|
116
|
+
def puppet_type_to_ruby(type)
|
|
117
|
+
array = false
|
|
118
|
+
|
|
119
|
+
type = $1 if type =~ /Optional\[(.+)/
|
|
120
|
+
|
|
121
|
+
if type =~ /Array\[(.+)/
|
|
122
|
+
type = $1
|
|
123
|
+
array = true
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
return [Numeric, array] if type =~ /Integer/
|
|
127
|
+
return [Numeric, array] if type =~ /Float/
|
|
128
|
+
return [Hash, array] if type =~ /Hash/
|
|
129
|
+
return [:boolean, array] if type =~ /Boolean/
|
|
130
|
+
|
|
131
|
+
[String, array]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def run!(params)
|
|
135
|
+
with_script_compiler do |compiler|
|
|
136
|
+
compiler.call_function("choria::run_playbook", @plan, params)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Adds the CLI options for an application based on the playbook inputs
|
|
141
|
+
#
|
|
142
|
+
# @param application [MCollective::Application]
|
|
143
|
+
# @param set_required [Boolean]
|
|
144
|
+
def add_cli_options(application, set_required=false)
|
|
145
|
+
sig = plan_signature
|
|
146
|
+
|
|
147
|
+
return if sig.nil? || sig.empty?
|
|
148
|
+
|
|
149
|
+
sig.each do |name, details|
|
|
150
|
+
type, array = puppet_type_to_ruby(details["type"])
|
|
151
|
+
|
|
152
|
+
properties = {
|
|
153
|
+
:description => "Plan input property (%s)" % details["type"],
|
|
154
|
+
:arguments => "--%s %s" % [name.downcase, name.upcase],
|
|
155
|
+
:type => array ? :array : type
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
properties[:required] = true if details["required"] && set_required
|
|
159
|
+
properties[:arguments] = "--[no-]%s" % name.downcase if type == :boolean
|
|
160
|
+
|
|
161
|
+
application.class.option(name, properties)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module MCollective
|
|
2
|
+
module Util
|
|
3
|
+
class BoltSupport
|
|
4
|
+
class TaskResult
|
|
5
|
+
attr_reader :host, :result
|
|
6
|
+
|
|
7
|
+
# Method used by Puppet to create the TaskResult from a hash
|
|
8
|
+
#
|
|
9
|
+
# @param hash [Hash] hash as prodused by various execution_result method
|
|
10
|
+
# @return [TaskResult]
|
|
11
|
+
def self.from_asserted_hash(hash)
|
|
12
|
+
new(hash.keys.first, hash.values.first)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @param host [String] node name
|
|
16
|
+
# @param result [Hash] result value as produced by execution_result methods
|
|
17
|
+
def initialize(host, result)
|
|
18
|
+
@host = host
|
|
19
|
+
@result = result
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_hash
|
|
23
|
+
{@host => @result}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_json(obj={})
|
|
27
|
+
to_hash.to_json(obj)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# A error object if this represents an error
|
|
31
|
+
#
|
|
32
|
+
# @return [Puppet::DataTypes::Error, nil]
|
|
33
|
+
def error
|
|
34
|
+
if @result["error"]
|
|
35
|
+
if defined?(Puppet::DataTypes::Error)
|
|
36
|
+
Puppet::DataTypes::Error.from_asserted_hash(@result["error"])
|
|
37
|
+
else
|
|
38
|
+
@result["error"]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# The type of task that created this result
|
|
44
|
+
#
|
|
45
|
+
# @return String examples like mcollective, data etc
|
|
46
|
+
def type
|
|
47
|
+
@result["type"]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# If this task result represents a succesful task
|
|
51
|
+
#
|
|
52
|
+
# This supposed fail_ok, any task with that set will be considered passed
|
|
53
|
+
#
|
|
54
|
+
# @return Boolean
|
|
55
|
+
def ok
|
|
56
|
+
return true if @result["fail_ok"]
|
|
57
|
+
|
|
58
|
+
!@result.include?("error")
|
|
59
|
+
end
|
|
60
|
+
alias :ok? :ok
|
|
61
|
+
|
|
62
|
+
def fail_ok
|
|
63
|
+
@result["fail_ok"]
|
|
64
|
+
end
|
|
65
|
+
alias :fail_ok? :fail_ok
|
|
66
|
+
|
|
67
|
+
# Access the value data embedded in the result
|
|
68
|
+
#
|
|
69
|
+
# @param key [String] data to access
|
|
70
|
+
# @return [Object] the specifiv item in the value hash or the raw value
|
|
71
|
+
def [](key)
|
|
72
|
+
return @result["value"] unless @result["value"].is_a?(Hash)
|
|
73
|
+
|
|
74
|
+
@result["value"][key]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Access the value data in raw form
|
|
78
|
+
#
|
|
79
|
+
# @return [Object] whatever value the task produced
|
|
80
|
+
def value
|
|
81
|
+
@result["value"]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def to_s
|
|
85
|
+
if Object.const_defined?(:Puppet)
|
|
86
|
+
Puppet::Pops::Types::StringConverter.convert(self, "%p")
|
|
87
|
+
else
|
|
88
|
+
super
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
module MCollective
|
|
2
|
+
module Util
|
|
3
|
+
class BoltSupport
|
|
4
|
+
class TaskResults
|
|
5
|
+
attr_reader :results, :exception
|
|
6
|
+
attr_writer :message
|
|
7
|
+
|
|
8
|
+
include Enumerable
|
|
9
|
+
|
|
10
|
+
def self.include_iterable
|
|
11
|
+
include(Puppet::Pops::Types::Iterable)
|
|
12
|
+
include(Puppet::Pops::Types::IteratorProducer)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Method used by Puppet to create the TaskResults from a array
|
|
16
|
+
#
|
|
17
|
+
# @param results [Array<TaskResult>] hash as prodused by various execution_result method
|
|
18
|
+
# @return [TaskResults]
|
|
19
|
+
def self.from_asserted_hash(results, exception=nil)
|
|
20
|
+
new(results, exception)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @param results [Array<TaskResult>]
|
|
24
|
+
def initialize(results, exception=nil)
|
|
25
|
+
@results = results
|
|
26
|
+
@exception = exception
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_json(obj={})
|
|
30
|
+
@results.to_json(obj)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Iterate over all results
|
|
34
|
+
#
|
|
35
|
+
# @yield [TaskResult]
|
|
36
|
+
def each(&block)
|
|
37
|
+
@results.each(&block)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Set of all the results that are errors regardless of fail_ok
|
|
41
|
+
#
|
|
42
|
+
# @return [TaskResults]
|
|
43
|
+
def error_set
|
|
44
|
+
TaskResults.new(@results.select(&:error))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Set of all the results that are ok regardless of fail_ok
|
|
48
|
+
#
|
|
49
|
+
# @return [TaskResults]
|
|
50
|
+
def ok_set
|
|
51
|
+
TaskResults.new(@results.reject(&:error))
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Determines if all results are ok, considers fail_ok
|
|
55
|
+
#
|
|
56
|
+
# @return [Boolean]
|
|
57
|
+
def ok
|
|
58
|
+
@results.all?(&:ok)
|
|
59
|
+
end
|
|
60
|
+
alias :ok? :ok
|
|
61
|
+
|
|
62
|
+
def fail_ok
|
|
63
|
+
@results.all?(&:fail_ok)
|
|
64
|
+
end
|
|
65
|
+
alias :fail_ok? :fail_ok
|
|
66
|
+
|
|
67
|
+
def message
|
|
68
|
+
return exception.to_s if exception
|
|
69
|
+
|
|
70
|
+
@message
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# List of node names for all results
|
|
74
|
+
#
|
|
75
|
+
# @return [Array<String>]
|
|
76
|
+
def hosts
|
|
77
|
+
@results.map(&:host)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# First result in the set
|
|
81
|
+
#
|
|
82
|
+
# @return [TaskResult]
|
|
83
|
+
def first
|
|
84
|
+
@results.first
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Finds a result by name
|
|
88
|
+
#
|
|
89
|
+
# @param host [String] node hostname
|
|
90
|
+
# @return [TaskResult,nil]
|
|
91
|
+
def find(host)
|
|
92
|
+
@results.find {|r| r.host == host}
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Determines if the resultset is empty
|
|
96
|
+
#
|
|
97
|
+
# @return [Boolean]
|
|
98
|
+
def empty
|
|
99
|
+
@results.empty?
|
|
100
|
+
end
|
|
101
|
+
alias :empty? :empty
|
|
102
|
+
|
|
103
|
+
# Determines the count of results in the set
|
|
104
|
+
#
|
|
105
|
+
# @return [Integer]
|
|
106
|
+
def count
|
|
107
|
+
@results.size
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def to_s
|
|
111
|
+
if Object.const_defined?(:Puppet)
|
|
112
|
+
Puppet::Pops::Types::StringConverter.convert(self, "%p")
|
|
113
|
+
else
|
|
114
|
+
super
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def iterator
|
|
119
|
+
if Object.const_defined?(:Puppet) && Puppet.const_defined?(:Pops) && self.class.included_modules.include?(Puppet::Pops::Types::Iterable)
|
|
120
|
+
return Puppet::Pops::Types::Iterable.on(@results, TaskResult)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
raise(NotImplementedError, "iterator requires puppet code to be loaded.")
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|