bolt 2.11.1 → 2.12.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +61 -0
- data/lib/bolt/analytics.rb +21 -2
- data/lib/bolt/bolt_option_parser.rb +4 -3
- data/lib/bolt/cli.rb +11 -0
- data/lib/bolt/config.rb +11 -9
- data/lib/bolt/pal.rb +2 -0
- data/lib/bolt/project.rb +12 -1
- data/lib/bolt/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c36dc3edc9637ac83eab0734e6143961ff7c97f4cbc0866ce8e1b5a0b5d318c2
|
4
|
+
data.tar.gz: c52ea03e1354361836c6d76c108735e2f8525aa5e8132f87cf895b5a0f2d802d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ded5edab2a28a3a50d2eb9c9d2a1ccad43eae0272b09a609b219a78516bd32f8bff0e35751a95629d4d918cf3a22883d47a90c5c0f402c5aeedaffaab5dfc546
|
7
|
+
data.tar.gz: acde1204c706c49926a33b074da9b5262d1e6d11d27137bec55d7ea80a3ec7e009a1defc309e1f9a7fe824db9c0d4ce92963ddc6d3ae3d2619550fc5c4164ed3
|
@@ -109,6 +109,15 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
|
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
|
+
# Wrap Sensitive parameters for plans that are run from the CLI, as it's impossible to pass
|
113
|
+
# a Sensitive value that way. We don't do this for plans run from the run_plan function, as
|
114
|
+
# it can receive Sensitive values as arguments.
|
115
|
+
# This should only happen after expanding target params, otherwise things will blow up if
|
116
|
+
# the targets are wrapped as Sensitive. Hopefully nobody does that, though...
|
117
|
+
if options[:bolt_api_call]
|
118
|
+
params = wrap_sensitive_parameters(params, closure.parameters)
|
119
|
+
end
|
120
|
+
|
112
121
|
# wrap plan execution in logging messages
|
113
122
|
executor.log_plan(plan_name) do
|
114
123
|
result = nil
|
@@ -169,6 +178,58 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
|
|
169
178
|
end
|
170
179
|
end
|
171
180
|
|
181
|
+
# Wrap any Sensitive parameters in the Sensitive wrapper type, unless they are already
|
182
|
+
# wrapped as Sensitive. This will also raise a helpful warning if the type expression
|
183
|
+
# is a complex data type using Sensitive, as we don't handle those cases.
|
184
|
+
def wrap_sensitive_parameters(params, param_models)
|
185
|
+
models = param_models.each_with_object({}) { |param, acc| acc[param.name] = param }
|
186
|
+
|
187
|
+
params.each_with_object({}) do |(name, value), acc|
|
188
|
+
model = models[name]
|
189
|
+
|
190
|
+
if sensitive_type?(model.type_expr)
|
191
|
+
acc[name] = Puppet::Pops::Types::PSensitiveType::Sensitive.new(value)
|
192
|
+
else
|
193
|
+
if model.type_expr.to_s.include?('Sensitive')
|
194
|
+
# Include the location for regular plans. YAML plans don't have this info, so
|
195
|
+
# the location will be suppressed.
|
196
|
+
file = defined?(model.file) ? model.file : :default
|
197
|
+
line = defined?(model.line) ? model.line : :default
|
198
|
+
|
199
|
+
Puppet.warn_once(
|
200
|
+
'unsupported_sensitive_type',
|
201
|
+
name,
|
202
|
+
"Parameter '#{name}' is a complex type using Sensitive, unable to automatically wrap as Sensitive",
|
203
|
+
file,
|
204
|
+
line
|
205
|
+
)
|
206
|
+
end
|
207
|
+
|
208
|
+
acc[name] = value
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Whether the type is a supported Sensitive type. We only support wrapping parameterized
|
214
|
+
# and non-parameterized Sensitive types (e.g. Sensitive, Sensitive[String])
|
215
|
+
def sensitive_type?(type_expr)
|
216
|
+
# Parameterized Sensitive type (e.g. Sensitive[String])
|
217
|
+
# left_expr is defined whenever the type is parameterized. If this is a parameterized
|
218
|
+
# Sensitive type, then we check the cased_value, which is the stringified version of
|
219
|
+
# the left expression's type.
|
220
|
+
(defined?(type_expr.left_expr) && type_expr.left_expr.cased_value == 'Sensitive') ||
|
221
|
+
# Non-parameterized Sensitive type (Sensitive)
|
222
|
+
# cased_value is defined whenever the type is non-parameterized. If the type expression
|
223
|
+
# defines cased_value, then this is a simple type and we just need to check that it's
|
224
|
+
# Sensitive.
|
225
|
+
(defined?(type_expr.cased_value) && type_expr.cased_value == 'Sensitive') ||
|
226
|
+
# Sensitive type from YAML plans
|
227
|
+
# Type expressions from YAML plans are a different class than those from regular plans.
|
228
|
+
# As long as the type expression is PSensitiveType we can be sure that the type is
|
229
|
+
# either a parameterized or non-parameterized Sensitive type.
|
230
|
+
type_expr.instance_of?(Puppet::Pops::Types::PSensitiveType)
|
231
|
+
end
|
232
|
+
|
172
233
|
def targets_to_param(targets, params, param_types)
|
173
234
|
nodes_param = param_types.include?('nodes')
|
174
235
|
targets_param = param_types['targets']&.any? { |p| p.match?(/TargetSpec/) }
|
data/lib/bolt/analytics.rb
CHANGED
@@ -29,7 +29,7 @@ module Bolt
|
|
29
29
|
def self.build_client
|
30
30
|
logger = Logging.logger[self]
|
31
31
|
begin
|
32
|
-
config_file =
|
32
|
+
config_file = config_path(logger)
|
33
33
|
config = load_config(config_file, logger)
|
34
34
|
rescue ArgumentError
|
35
35
|
config = { 'disabled' => true }
|
@@ -51,6 +51,25 @@ module Bolt
|
|
51
51
|
NoopClient.new
|
52
52
|
end
|
53
53
|
|
54
|
+
def self.config_path(logger)
|
55
|
+
path = File.expand_path(File.join('~', '.puppetlabs', 'etc', 'bolt', 'analytics.yaml'))
|
56
|
+
old_path = File.expand_path(File.join('~', '.puppetlabs', 'bolt', 'analytics.yaml'))
|
57
|
+
|
58
|
+
if File.exist?(path)
|
59
|
+
if File.exist?(old_path)
|
60
|
+
message = "Detected analytics configuration files at '#{old_path}' and '#{path}'. Loading "\
|
61
|
+
"analytics configuration from '#{path}'."
|
62
|
+
logger.warn(message)
|
63
|
+
end
|
64
|
+
|
65
|
+
path
|
66
|
+
elsif File.exist?(old_path)
|
67
|
+
old_path
|
68
|
+
else
|
69
|
+
path
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
54
73
|
def self.load_config(filename, logger)
|
55
74
|
if File.exist?(filename)
|
56
75
|
YAML.load_file(filename)
|
@@ -59,7 +78,7 @@ module Bolt
|
|
59
78
|
logger.warn <<~ANALYTICS
|
60
79
|
Bolt collects data about how you use it. You can opt out of providing this data.
|
61
80
|
|
62
|
-
To disable analytics data collection, add this line to ~/.puppetlabs/bolt/analytics.yaml :
|
81
|
+
To disable analytics data collection, add this line to ~/.puppetlabs/etc/bolt/analytics.yaml :
|
63
82
|
disabled: true
|
64
83
|
|
65
84
|
Read more about what data Bolt collects and why here:
|
@@ -20,7 +20,7 @@ module Bolt
|
|
20
20
|
def get_help_text(subcommand, action = nil)
|
21
21
|
case subcommand
|
22
22
|
when 'apply'
|
23
|
-
{ flags: ACTION_OPTS + %w[noop execute compile-concurrency],
|
23
|
+
{ flags: ACTION_OPTS + %w[noop execute compile-concurrency hiera-config],
|
24
24
|
banner: APPLY_HELP }
|
25
25
|
when 'command'
|
26
26
|
case action
|
@@ -172,13 +172,14 @@ module Bolt
|
|
172
172
|
apply
|
173
173
|
|
174
174
|
USAGE
|
175
|
-
bolt apply
|
175
|
+
bolt apply [manifest.pp] [options]
|
176
176
|
|
177
177
|
DESCRIPTION
|
178
178
|
Apply Puppet manifest code on the specified targets.
|
179
179
|
|
180
180
|
EXAMPLES
|
181
|
-
bolt apply manifest.pp
|
181
|
+
bolt apply manifest.pp -t target
|
182
|
+
bolt apply -e "file { '/etc/puppetlabs': ensure => present }" -t target
|
182
183
|
HELP
|
183
184
|
|
184
185
|
COMMAND_HELP = <<~HELP
|
data/lib/bolt/cli.rb
CHANGED
@@ -537,6 +537,17 @@ module Bolt
|
|
537
537
|
Puppet[:tasks] = false
|
538
538
|
ast = pal.parse_manifest(code, filename)
|
539
539
|
|
540
|
+
if defined?(ast.body) &&
|
541
|
+
(ast.body.is_a?(Puppet::Pops::Model::HostClassDefinition) ||
|
542
|
+
ast.body.is_a?(Puppet::Pops::Model::ResourceTypeDefinition))
|
543
|
+
message = "Manifest only contains definitions and will result in no changes on the targets. "\
|
544
|
+
"Definitions must be declared for their resources to be applied. You can read more "\
|
545
|
+
"about defining and declaring classes and types in the Puppet documentation at "\
|
546
|
+
"https://puppet.com/docs/puppet/latest/lang_classes.html and "\
|
547
|
+
"https://puppet.com/docs/puppet/latest/lang_defined_types.html"
|
548
|
+
@logger.warn(message)
|
549
|
+
end
|
550
|
+
|
540
551
|
executor = Bolt::Executor.new(config.concurrency, analytics, noop)
|
541
552
|
executor.subscribe(outputter) if options.fetch(:format, 'human') == 'human'
|
542
553
|
executor.subscribe(log_outputter)
|
data/lib/bolt/config.rb
CHANGED
@@ -115,7 +115,7 @@ module Bolt
|
|
115
115
|
data: Bolt::Util.read_optional_yaml_hash(project.config_file, 'config')
|
116
116
|
}
|
117
117
|
|
118
|
-
data = load_defaults.push(data).select { |config| config[:data]&.any? }
|
118
|
+
data = load_defaults(project).push(data).select { |config| config[:data]&.any? }
|
119
119
|
|
120
120
|
new(project, data, overrides)
|
121
121
|
end
|
@@ -127,27 +127,29 @@ module Bolt
|
|
127
127
|
filepath: project.config_file,
|
128
128
|
data: Bolt::Util.read_yaml_hash(configfile, 'config')
|
129
129
|
}
|
130
|
-
data = load_defaults.push(data).select { |config| config[:data]&.any? }
|
130
|
+
data = load_defaults(project).push(data).select { |config| config[:data]&.any? }
|
131
131
|
|
132
132
|
new(project, data, overrides)
|
133
133
|
end
|
134
134
|
|
135
|
-
def self.load_defaults
|
135
|
+
def self.load_defaults(project)
|
136
136
|
# Lazy-load expensive gem code
|
137
137
|
require 'win32/dir' if Bolt::Util.windows?
|
138
138
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
139
|
+
# Don't load /etc/puppetlabs/bolt/bolt.yaml twice
|
140
|
+
confs = if project.path == Bolt::Project.system_path
|
141
|
+
[]
|
142
|
+
else
|
143
|
+
system_path = Pathname.new(File.join(Bolt::Project.system_path, 'bolt.yaml'))
|
144
|
+
[{ filepath: system_path, data: Bolt::Util.read_optional_yaml_hash(system_path, 'config') }]
|
145
|
+
end
|
146
|
+
|
144
147
|
user_path = begin
|
145
148
|
Pathname.new(File.expand_path(File.join('~', '.puppetlabs', 'etc', 'bolt', 'bolt.yaml')))
|
146
149
|
rescue ArgumentError
|
147
150
|
nil
|
148
151
|
end
|
149
152
|
|
150
|
-
confs = [{ filepath: system_path, data: Bolt::Util.read_optional_yaml_hash(system_path, 'config') }]
|
151
153
|
confs << { filepath: user_path, data: Bolt::Util.read_optional_yaml_hash(user_path, 'config') } if user_path
|
152
154
|
confs
|
153
155
|
end
|
data/lib/bolt/pal.rb
CHANGED
@@ -359,6 +359,7 @@ module Bolt
|
|
359
359
|
name = param.name
|
360
360
|
if signature_params.include?(name)
|
361
361
|
params[name] = { 'type' => param.types.first }
|
362
|
+
params[name]['sensitive'] = param.types.first =~ /\ASensitive(\[.*\])?\z/ ? true : false
|
362
363
|
params[name]['default_value'] = defaults[name] if defaults.key?(name)
|
363
364
|
params[name]['description'] = param.text unless param.text.empty?
|
364
365
|
else
|
@@ -390,6 +391,7 @@ module Bolt
|
|
390
391
|
param.type_expr
|
391
392
|
end
|
392
393
|
params[name] = { 'type' => type_str }
|
394
|
+
params[name]['sensitive'] = param.type_expr.instance_of?(Puppet::Pops::Types::PSensitiveType)
|
393
395
|
params[name]['default_value'] = param.value
|
394
396
|
params[name]['description'] = param.description if param.description
|
395
397
|
end
|
data/lib/bolt/project.rb
CHANGED
@@ -16,7 +16,18 @@ module Bolt
|
|
16
16
|
:puppetfile, :rerunfile, :type, :resource_types
|
17
17
|
|
18
18
|
def self.default_project
|
19
|
-
Project.new(File.join('~', '.puppetlabs', 'bolt'), 'user')
|
19
|
+
Project.new(File.expand_path(File.join('~', '.puppetlabs', 'bolt')), 'user')
|
20
|
+
# If homedir isn't defined use the system config path
|
21
|
+
rescue ArgumentError
|
22
|
+
Project.new(system_path, 'system')
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.system_path
|
26
|
+
if Bolt::Util.windows?
|
27
|
+
File.join(Dir::COMMON_APPDATA, 'PuppetLabs', 'bolt', 'etc')
|
28
|
+
else
|
29
|
+
File.join('/etc', 'puppetlabs', 'bolt')
|
30
|
+
end
|
20
31
|
end
|
21
32
|
|
22
33
|
# Search recursively up the directory hierarchy for the Project. Look for a
|
data/lib/bolt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bolt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|