bolt 2.32.0 → 2.36.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/Puppetfile +6 -6
- data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +1 -3
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +17 -6
- data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +6 -0
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +56 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +2 -2
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +24 -6
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +27 -8
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +21 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +18 -1
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +24 -6
- data/guides/logging.txt +18 -0
- data/lib/bolt/analytics.rb +27 -8
- data/lib/bolt/apply_result.rb +3 -3
- data/lib/bolt/bolt_option_parser.rb +43 -15
- data/lib/bolt/cli.rb +79 -227
- data/lib/bolt/config.rb +131 -52
- data/lib/bolt/config/options.rb +46 -8
- data/lib/bolt/config/transport/base.rb +10 -19
- data/lib/bolt/config/transport/local.rb +0 -7
- data/lib/bolt/config/transport/options.rb +1 -1
- data/lib/bolt/config/transport/ssh.rb +8 -14
- data/lib/bolt/config/validator.rb +231 -0
- data/lib/bolt/error.rb +37 -3
- data/lib/bolt/executor.rb +103 -17
- data/lib/bolt/inventory/group.rb +2 -1
- data/lib/bolt/module_installer.rb +2 -1
- data/lib/bolt/module_installer/specs/forge_spec.rb +5 -4
- data/lib/bolt/module_installer/specs/git_spec.rb +4 -3
- data/lib/bolt/outputter/human.rb +21 -9
- data/lib/bolt/outputter/rainbow.rb +1 -1
- data/lib/bolt/pal.rb +48 -30
- data/lib/bolt/pal/yaml_plan.rb +11 -2
- data/lib/bolt/pal/yaml_plan/evaluator.rb +23 -1
- data/lib/bolt/pal/yaml_plan/loader.rb +14 -9
- data/lib/bolt/plan_creator.rb +160 -0
- data/lib/bolt/plugin.rb +1 -8
- data/lib/bolt/project.rb +30 -36
- data/lib/bolt/project_manager.rb +199 -0
- data/lib/bolt/{project_migrator/config.rb → project_manager/config_migrator.rb} +43 -5
- data/lib/bolt/{project_migrator/inventory.rb → project_manager/inventory_migrator.rb} +5 -5
- data/lib/bolt/{project_migrator/base.rb → project_manager/migrator.rb} +2 -2
- data/lib/bolt/{project_migrator/modules.rb → project_manager/module_migrator.rb} +3 -3
- data/lib/bolt/puppetdb/client.rb +3 -2
- data/lib/bolt/puppetdb/config.rb +9 -8
- data/lib/bolt/result.rb +23 -11
- data/lib/bolt/shell/bash.rb +12 -7
- data/lib/bolt/shell/powershell.rb +12 -7
- data/lib/bolt/task/run.rb +1 -1
- data/lib/bolt/transport/base.rb +18 -18
- data/lib/bolt/transport/docker.rb +23 -6
- data/lib/bolt/transport/orch.rb +23 -19
- data/lib/bolt/transport/orch/connection.rb +10 -3
- data/lib/bolt/transport/remote.rb +3 -3
- data/lib/bolt/transport/simple.rb +6 -6
- data/lib/bolt/transport/ssh/exec_connection.rb +6 -2
- data/lib/bolt/util.rb +19 -7
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt/yarn.rb +23 -0
- data/lib/bolt_server/base_config.rb +3 -1
- data/lib/bolt_server/config.rb +3 -1
- data/lib/bolt_server/file_cache.rb +2 -0
- data/lib/bolt_server/schemas/partials/task.json +2 -2
- data/lib/bolt_server/transport_app.rb +42 -11
- data/lib/bolt_spec/plans/action_stubs/command_stub.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/script_stub.rb +1 -1
- data/lib/bolt_spec/plans/mock_executor.rb +9 -6
- data/libexec/apply_catalog.rb +1 -1
- data/libexec/custom_facts.rb +1 -1
- data/libexec/query_resources.rb +1 -1
- metadata +12 -14
- data/lib/bolt/project_migrator.rb +0 -80
- data/modules/secure_env_vars/plans/init.pp +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1881e4097a89e606b9326f93e2e6fd9d934a7db1eb8609e6f9a09ffa322ac7c4
|
4
|
+
data.tar.gz: '02509b1919e57f137bf4e868332be3b73238d22d83251680dc29c7c93ef90a19'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fc1215430ac99b765c24c87ee210afb03a247a6c0baac9af3b00e34d56cfb58bacb2140dcfafbe197fd655602713463e2697c2df5083c259b66c8d8cd7bc112
|
7
|
+
data.tar.gz: 445a5f77a5beaf8a1a3c4cb2193e973ada23cb4a7a5f3a8caba2ccc47be4fc8a8fdef3ba797e082c0df3b9553c2f2e67c06084f2c2b2684347d2b9a86e45bde0
|
data/Puppetfile
CHANGED
@@ -6,16 +6,16 @@ moduledir File.join(File.dirname(__FILE__), 'modules')
|
|
6
6
|
|
7
7
|
# Core modules used by 'apply'
|
8
8
|
mod 'puppetlabs-service', '1.3.0'
|
9
|
-
mod 'puppetlabs-puppet_agent', '4.
|
10
|
-
mod 'puppetlabs-facts', '1.
|
9
|
+
mod 'puppetlabs-puppet_agent', '4.2.0'
|
10
|
+
mod 'puppetlabs-facts', '1.2.0'
|
11
11
|
|
12
12
|
# Core types and providers for Puppet 6
|
13
13
|
mod 'puppetlabs-augeas_core', '1.1.1'
|
14
14
|
mod 'puppetlabs-host_core', '1.0.3'
|
15
15
|
mod 'puppetlabs-scheduled_task', '2.2.1'
|
16
|
-
mod 'puppetlabs-sshkeys_core', '2.
|
17
|
-
mod 'puppetlabs-zfs_core', '1.
|
18
|
-
mod 'puppetlabs-cron_core', '1.0.
|
16
|
+
mod 'puppetlabs-sshkeys_core', '2.2.0'
|
17
|
+
mod 'puppetlabs-zfs_core', '1.2.0'
|
18
|
+
mod 'puppetlabs-cron_core', '1.0.5'
|
19
19
|
mod 'puppetlabs-mount_core', '1.0.4'
|
20
20
|
mod 'puppetlabs-selinux_core', '1.0.4'
|
21
21
|
mod 'puppetlabs-yumrepo_core', '1.0.7'
|
@@ -36,6 +36,7 @@ mod 'puppetlabs-azure_inventory', '0.4.1'
|
|
36
36
|
mod 'puppetlabs-gcloud_inventory', '0.1.3'
|
37
37
|
mod 'puppetlabs-http_request', '0.2.0'
|
38
38
|
mod 'puppetlabs-pkcs7', '0.1.1'
|
39
|
+
mod 'puppetlabs-secure_env_vars', '0.1.0'
|
39
40
|
mod 'puppetlabs-terraform', '0.5.0'
|
40
41
|
mod 'puppetlabs-vault', '0.3.0'
|
41
42
|
mod 'puppetlabs-yaml', '0.2.0'
|
@@ -44,4 +45,3 @@ mod 'puppetlabs-yaml', '0.2.0'
|
|
44
45
|
mod 'canary', local: true
|
45
46
|
mod 'aggregate', local: true
|
46
47
|
mod 'puppetdb_fact', local: true
|
47
|
-
mod 'secure_env_vars', local: true
|
@@ -44,9 +44,7 @@ Puppet::Functions.create_function(:catch_errors) do
|
|
44
44
|
yield
|
45
45
|
rescue Puppet::PreformattedError => e
|
46
46
|
if e.cause.is_a?(Bolt::Error)
|
47
|
-
if error_types.nil?
|
48
|
-
e.cause.to_puppet_error
|
49
|
-
elsif error_types.include?(e.cause.to_h['kind'])
|
47
|
+
if error_types.nil? || error_types.include?(e.cause.to_h['kind'])
|
50
48
|
e.cause.to_puppet_error
|
51
49
|
else
|
52
50
|
raise e
|
@@ -110,14 +110,25 @@ Puppet::Functions.create_function(:download_file, Puppet::Functions::InternalFun
|
|
110
110
|
targets = inventory.get_targets(targets)
|
111
111
|
if targets.empty?
|
112
112
|
call_function('debug', "Simulating file download of '#{source}' - no targets given - no action taken")
|
113
|
-
|
113
|
+
Bolt::ResultSet.new([])
|
114
114
|
else
|
115
|
-
r = executor.
|
116
|
-
|
115
|
+
r = if executor.in_parallel
|
116
|
+
require 'concurrent'
|
117
|
+
require 'fiber'
|
118
|
+
future = Concurrent::Future.execute do
|
119
|
+
executor.download_file(targets, source, destination, options, Puppet::Pops::PuppetStack.top_of_stack)
|
120
|
+
end
|
121
|
+
|
122
|
+
Fiber.yield('unfinished') while future.incomplete?
|
123
|
+
future.value || future.reason
|
124
|
+
else
|
125
|
+
executor.download_file(targets, source, destination, options, Puppet::Pops::PuppetStack.top_of_stack)
|
126
|
+
end
|
117
127
|
|
118
|
-
|
119
|
-
|
128
|
+
if !r.ok && !options[:catch_errors]
|
129
|
+
raise Bolt::RunFailure.new(r, 'download_file', source)
|
130
|
+
end
|
131
|
+
r
|
120
132
|
end
|
121
|
-
r
|
122
133
|
end
|
123
134
|
end
|
@@ -3,6 +3,12 @@
|
|
3
3
|
require 'bolt/error'
|
4
4
|
|
5
5
|
# Returns the facts hash for a target.
|
6
|
+
#
|
7
|
+
# Using the `facts` function does not automatically collect facts for a target,
|
8
|
+
# and will only return facts that are currently set in the inventory. To collect
|
9
|
+
# facts from a target and set them in the inventory, run the
|
10
|
+
# [facts](writing_plans.md#collect-facts-from-targets) plan or
|
11
|
+
# [puppetdb_fact](writing_plans.md#collect-facts-from-puppetdb) plan.
|
6
12
|
Puppet::Functions.create_function(:facts) do
|
7
13
|
# @param target A target.
|
8
14
|
# @return The target's facts.
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bolt/yarn'
|
4
|
+
|
5
|
+
# Map a code block onto an array, where each array element executes in parallel.
|
6
|
+
# This function is experimental.
|
7
|
+
#
|
8
|
+
# > **Note:** Not available in apply block.
|
9
|
+
Puppet::Functions.create_function(:parallelize, Puppet::Functions::InternalFunction) do
|
10
|
+
# Map a block onto an array, where each array element executes in parallel.
|
11
|
+
# This function is experimental.
|
12
|
+
# @param data The array to apply the block to.
|
13
|
+
# @return [Array] An array of PlanResult objects. Each input from the input
|
14
|
+
# array returns a corresponding PlanResult object.
|
15
|
+
# @example Execute two tasks on multiple targets. Once the task finishes on one
|
16
|
+
# target, that target can move to the next step without waiting for the task
|
17
|
+
# to finish on the second target.
|
18
|
+
# $targets = get_targets(["host1", "host2"])
|
19
|
+
# $result = parallelize ($targets) |$t| {
|
20
|
+
# run_task('a', $t)
|
21
|
+
# run_task('b', $t)
|
22
|
+
# }
|
23
|
+
dispatch :parallelize do
|
24
|
+
scope_param
|
25
|
+
param 'Array[Any]', :data
|
26
|
+
block_param 'Callable[Any]', :block
|
27
|
+
return_type 'Array[Boltlib::PlanResult]'
|
28
|
+
end
|
29
|
+
|
30
|
+
def parallelize(scope, data, &block)
|
31
|
+
unless Puppet[:tasks]
|
32
|
+
raise Puppet::ParseErrorWithIssue
|
33
|
+
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'parallelize')
|
34
|
+
end
|
35
|
+
|
36
|
+
executor = Puppet.lookup(:bolt_executor)
|
37
|
+
executor.report_function_call(self.class.name)
|
38
|
+
|
39
|
+
skein = data.each_with_index.map do |object, index|
|
40
|
+
executor.create_yarn(scope, block, object, index)
|
41
|
+
end
|
42
|
+
|
43
|
+
result = executor.round_robin(skein)
|
44
|
+
|
45
|
+
failed_indices = result.each_index.select do |i|
|
46
|
+
result[i].is_a?(Bolt::Error)
|
47
|
+
end
|
48
|
+
|
49
|
+
# TODO: Inner catch errors block?
|
50
|
+
if failed_indices.any?
|
51
|
+
raise Bolt::ParallelFailure.new(result, failed_indices)
|
52
|
+
end
|
53
|
+
|
54
|
+
result
|
55
|
+
end
|
56
|
+
end
|
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
require 'bolt/error'
|
4
4
|
|
5
|
-
# Makes a query to
|
5
|
+
# Makes a query to [puppetdb](https://puppet.com/docs/puppetdb/latest/index.html)
|
6
6
|
# using Bolt's PuppetDB client.
|
7
7
|
Puppet::Functions.create_function(:puppetdb_query) do
|
8
8
|
# rubocop:disable Layout/LineLength
|
9
9
|
# @param query A PQL query.
|
10
|
-
#
|
10
|
+
# Learn more about [Puppet's query language](https://puppet.com/docs/puppetdb/latest/api/query/tutorial-pql.html), PQL.
|
11
11
|
# @return Results of the PuppetDB query.
|
12
12
|
# @example Request certnames for all nodes
|
13
13
|
# puppetdb_query('nodes[certname] {}')
|
@@ -67,14 +67,32 @@ Puppet::Functions.create_function(:run_command) do
|
|
67
67
|
|
68
68
|
if targets.empty?
|
69
69
|
call_function('debug', "Simulating run_command('#{command}') - no targets given - no action taken")
|
70
|
-
|
70
|
+
Bolt::ResultSet.new([])
|
71
71
|
else
|
72
|
-
r = executor.
|
73
|
-
|
72
|
+
r = if executor.in_parallel
|
73
|
+
require 'concurrent'
|
74
|
+
require 'fiber'
|
75
|
+
future = Concurrent::Future.execute do
|
76
|
+
executor.run_command(targets,
|
77
|
+
command,
|
78
|
+
options,
|
79
|
+
Puppet::Pops::PuppetStack.top_of_stack)
|
80
|
+
end
|
81
|
+
|
82
|
+
Fiber.yield('unfinished') while future.incomplete?
|
83
|
+
future.value || future.reason
|
84
|
+
else
|
85
|
+
executor.run_command(targets,
|
86
|
+
command,
|
87
|
+
options,
|
88
|
+
Puppet::Pops::PuppetStack.top_of_stack)
|
89
|
+
end
|
90
|
+
|
91
|
+
if !r.ok && !options[:catch_errors]
|
92
|
+
raise Bolt::RunFailure.new(r, 'run_command', command)
|
93
|
+
end
|
74
94
|
|
75
|
-
|
76
|
-
raise Bolt::RunFailure.new(r, 'run_command', command)
|
95
|
+
r
|
77
96
|
end
|
78
|
-
r
|
79
97
|
end
|
80
98
|
end
|
@@ -84,15 +84,34 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
|
|
84
84
|
# Ensure that given targets are all Target instances)
|
85
85
|
targets = inventory.get_targets(targets)
|
86
86
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
87
|
+
if targets.empty?
|
88
|
+
Bolt::ResultSet.new([])
|
89
|
+
else
|
90
|
+
r = if executor.in_parallel
|
91
|
+
require 'concurrent'
|
92
|
+
require 'fiber'
|
93
|
+
future = Concurrent::Future.execute do
|
94
|
+
executor.run_script(targets,
|
95
|
+
found,
|
96
|
+
arguments,
|
97
|
+
options,
|
98
|
+
Puppet::Pops::PuppetStack.top_of_stack)
|
99
|
+
end
|
92
100
|
|
93
|
-
|
94
|
-
|
101
|
+
Fiber.yield('unfinished') while future.incomplete?
|
102
|
+
future.value || future.reason
|
103
|
+
else
|
104
|
+
executor.run_script(targets,
|
105
|
+
found,
|
106
|
+
arguments,
|
107
|
+
options,
|
108
|
+
Puppet::Pops::PuppetStack.top_of_stack)
|
109
|
+
end
|
110
|
+
|
111
|
+
if !r.ok && !options[:catch_errors]
|
112
|
+
raise Bolt::RunFailure.new(r, 'run_script', script)
|
113
|
+
end
|
114
|
+
r
|
95
115
|
end
|
96
|
-
r
|
97
116
|
end
|
98
117
|
end
|
@@ -133,7 +133,27 @@ Puppet::Functions.create_function(:run_task) do
|
|
133
133
|
if targets.empty?
|
134
134
|
Bolt::ResultSet.new([])
|
135
135
|
else
|
136
|
-
result = executor.
|
136
|
+
result = if executor.in_parallel
|
137
|
+
require 'concurrent'
|
138
|
+
require 'fiber'
|
139
|
+
future = Concurrent::Future.execute do
|
140
|
+
executor.run_task(targets,
|
141
|
+
task,
|
142
|
+
params,
|
143
|
+
options,
|
144
|
+
Puppet::Pops::PuppetStack.top_of_stack)
|
145
|
+
end
|
146
|
+
|
147
|
+
Fiber.yield('unfinished') while future.incomplete?
|
148
|
+
future.value || future.reason
|
149
|
+
else
|
150
|
+
executor.run_task(targets,
|
151
|
+
task,
|
152
|
+
params,
|
153
|
+
options,
|
154
|
+
Puppet::Pops::PuppetStack.top_of_stack)
|
155
|
+
end
|
156
|
+
|
137
157
|
if !result.ok && !options[:catch_errors]
|
138
158
|
raise Bolt::RunFailure.new(result, 'run_task', task_name)
|
139
159
|
end
|
@@ -180,7 +180,24 @@ Puppet::Functions.create_function(:run_task_with) do
|
|
180
180
|
else
|
181
181
|
# Combine the results from the task run with any failing results that were
|
182
182
|
# generated earlier when creating the target mapping
|
183
|
-
task_result = executor.
|
183
|
+
task_result = if executor.in_parallel
|
184
|
+
require 'concurrent'
|
185
|
+
require 'fiber'
|
186
|
+
future = Concurrent::Future.execute do
|
187
|
+
executor.run_task_with(target_mapping,
|
188
|
+
task,
|
189
|
+
options,
|
190
|
+
Puppet::Pops::PuppetStack.top_of_stack)
|
191
|
+
end
|
192
|
+
|
193
|
+
Fiber.yield('unfinished') while future.incomplete?
|
194
|
+
future.value || future.reason
|
195
|
+
else
|
196
|
+
executor.run_task_with(target_mapping,
|
197
|
+
task,
|
198
|
+
options,
|
199
|
+
Puppet::Pops::PuppetStack.top_of_stack)
|
200
|
+
end
|
184
201
|
result = Bolt::ResultSet.new(task_result.results + error_set)
|
185
202
|
|
186
203
|
if !result.ok && !options[:catch_errors]
|
@@ -81,14 +81,32 @@ Puppet::Functions.create_function(:upload_file, Puppet::Functions::InternalFunct
|
|
81
81
|
targets = inventory.get_targets(targets)
|
82
82
|
if targets.empty?
|
83
83
|
call_function('debug', "Simulating file upload of '#{found}' - no targets given - no action taken")
|
84
|
-
|
84
|
+
Bolt::ResultSet.new([])
|
85
85
|
else
|
86
|
-
r = executor.
|
87
|
-
|
86
|
+
r = if executor.in_parallel
|
87
|
+
require 'concurrent'
|
88
|
+
require 'fiber'
|
89
|
+
future = Concurrent::Future.execute do
|
90
|
+
executor.upload_file(targets,
|
91
|
+
found,
|
92
|
+
destination,
|
93
|
+
options,
|
94
|
+
Puppet::Pops::PuppetStack.top_of_stack)
|
95
|
+
end
|
88
96
|
|
89
|
-
|
90
|
-
|
97
|
+
Fiber.yield('unfinished') while future.incomplete?
|
98
|
+
future.value || future.reason
|
99
|
+
else
|
100
|
+
executor.upload_file(targets,
|
101
|
+
found,
|
102
|
+
destination,
|
103
|
+
options,
|
104
|
+
Puppet::Pops::PuppetStack.top_of_stack)
|
105
|
+
end
|
106
|
+
if !r.ok && !options[:catch_errors]
|
107
|
+
raise Bolt::RunFailure.new(r, 'upload_file', source)
|
108
|
+
end
|
109
|
+
r
|
91
110
|
end
|
92
|
-
r
|
93
111
|
end
|
94
112
|
end
|
data/guides/logging.txt
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
TOPIC
|
2
|
+
logging
|
3
|
+
|
4
|
+
DESCRIPTION
|
5
|
+
Bolt prints messages both to the console and to log files. Messages can
|
6
|
+
either come from Bolt's 'outputter', which logs user-facing messages like
|
7
|
+
progress and results, or from the 'logger', which logs warnings, errors, and
|
8
|
+
log-structured output to log files. Both of these message streams are
|
9
|
+
configurable.
|
10
|
+
|
11
|
+
By default, Bolt logs to the console at 'warn' level and writes a log file to
|
12
|
+
'<project>/bolt-debug.log' at 'debug' level. Unless you are running a plan,
|
13
|
+
Bolt runs in verbose mode by default.
|
14
|
+
|
15
|
+
To learn more about projects, see the 'project' guide.
|
16
|
+
|
17
|
+
DOCUMENTATION
|
18
|
+
https://pup.pt/bolt-logging
|
data/lib/bolt/analytics.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'bolt/util'
|
4
4
|
require 'bolt/version'
|
5
|
+
require 'find'
|
5
6
|
require 'json'
|
6
7
|
require 'logging'
|
7
8
|
require 'securerandom'
|
@@ -23,14 +24,16 @@ module Bolt
|
|
23
24
|
plan_steps: :cd8,
|
24
25
|
return_type: :cd9,
|
25
26
|
inventory_version: :cd10,
|
26
|
-
boltdir_type: :cd11
|
27
|
+
boltdir_type: :cd11,
|
28
|
+
puppet_plan_count: :cd12,
|
29
|
+
yaml_plan_count: :cd13
|
27
30
|
}.freeze
|
28
31
|
|
29
32
|
def self.build_client
|
30
33
|
logger = Bolt::Logger.logger(self)
|
31
34
|
begin
|
32
|
-
config_file = config_path
|
33
|
-
config = load_config(config_file
|
35
|
+
config_file = config_path
|
36
|
+
config = load_config(config_file)
|
34
37
|
rescue ArgumentError
|
35
38
|
config = { 'disabled' => true }
|
36
39
|
end
|
@@ -51,7 +54,7 @@ module Bolt
|
|
51
54
|
NoopClient.new
|
52
55
|
end
|
53
56
|
|
54
|
-
def self.config_path
|
57
|
+
def self.config_path
|
55
58
|
path = File.expand_path(File.join('~', '.puppetlabs', 'etc', 'bolt', 'analytics.yaml'))
|
56
59
|
old_path = File.expand_path(File.join('~', '.puppetlabs', 'bolt', 'analytics.yaml'))
|
57
60
|
|
@@ -59,7 +62,7 @@ module Bolt
|
|
59
62
|
if File.exist?(old_path)
|
60
63
|
message = "Detected analytics configuration files at '#{old_path}' and '#{path}'. Loading "\
|
61
64
|
"analytics configuration from '#{path}'."
|
62
|
-
|
65
|
+
Bolt::Logger.warn_once('duplicate_analytics', message)
|
63
66
|
end
|
64
67
|
|
65
68
|
path
|
@@ -70,12 +73,12 @@ module Bolt
|
|
70
73
|
end
|
71
74
|
end
|
72
75
|
|
73
|
-
def self.load_config(filename
|
76
|
+
def self.load_config(filename)
|
74
77
|
if File.exist?(filename)
|
75
78
|
Bolt::Util.read_optional_yaml_hash(filename, 'analytics')
|
76
79
|
else
|
77
80
|
unless ENV['BOLT_DISABLE_ANALYTICS']
|
78
|
-
|
81
|
+
Bolt::Logger.warn_once('analytics_opt_out', <<~ANALYTICS)
|
79
82
|
Bolt collects data about how you use it. You can opt out of providing this data.
|
80
83
|
|
81
84
|
To disable analytics data collection, add this line to ~/.puppetlabs/etc/bolt/analytics.yaml :
|
@@ -134,11 +137,23 @@ module Bolt
|
|
134
137
|
end
|
135
138
|
|
136
139
|
def report_bundled_content(mode, name)
|
137
|
-
if bundled_content[mode.split
|
140
|
+
if bundled_content[mode.split.first]&.include?(name)
|
138
141
|
event('Bundled Content', mode, label: name)
|
139
142
|
end
|
140
143
|
end
|
141
144
|
|
145
|
+
def plan_counts(plans_path)
|
146
|
+
pp_count, yaml_count = if File.exist?(plans_path)
|
147
|
+
%w[pp yaml].map do |extension|
|
148
|
+
Find.find(plans_path.to_s).grep(/.*\.#{extension}/).length
|
149
|
+
end
|
150
|
+
else
|
151
|
+
[0, 0]
|
152
|
+
end
|
153
|
+
|
154
|
+
{ puppet_plan_count: pp_count, yaml_plan_count: yaml_count }
|
155
|
+
end
|
156
|
+
|
142
157
|
def event(category, action, label: nil, value: nil, **kwargs)
|
143
158
|
custom_dimensions = Bolt::Util.walk_keys(kwargs) do |k|
|
144
159
|
CUSTOM_DIMENSIONS[k] || raise("Unknown analytics key '#{k}'")
|
@@ -224,6 +239,10 @@ module Bolt
|
|
224
239
|
|
225
240
|
def report_bundled_content(mode, name); end
|
226
241
|
|
242
|
+
def plan_counts(_)
|
243
|
+
{}
|
244
|
+
end
|
245
|
+
|
227
246
|
def event(category, action, **_kwargs)
|
228
247
|
@logger.trace "Skipping submission of '#{category} #{action}' event because analytics is disabled"
|
229
248
|
end
|