openbolt 5.0.0.rc1
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 +7 -0
- data/Puppetfile +52 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +60 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/containerresult.rb +51 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/future.rb +25 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resourceinstance.rb +71 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/result.rb +55 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resultset.rb +65 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/target.rb +93 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +33 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +38 -0
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +208 -0
- data/bolt-modules/boltlib/lib/puppet/functions/background.rb +62 -0
- data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +57 -0
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +130 -0
- data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +31 -0
- data/bolt-modules/boltlib/lib/puppet/functions/fail_plan.rb +52 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +87 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_target.rb +34 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_targets.rb +35 -0
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +74 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb +97 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb +47 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +52 -0
- data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +40 -0
- data/bolt-modules/boltlib/lib/puppet/functions/resolve_references.rb +42 -0
- data/bolt-modules/boltlib/lib/puppet/functions/resource.rb +53 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +106 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_container.rb +162 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +291 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +145 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +164 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +211 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_config.rb +48 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +43 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +145 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_var.rb +38 -0
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +101 -0
- data/bolt-modules/boltlib/lib/puppet/functions/vars.rb +29 -0
- data/bolt-modules/boltlib/lib/puppet/functions/wait.rb +131 -0
- data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +59 -0
- data/bolt-modules/boltlib/lib/puppet/functions/without_default_logging.rb +39 -0
- data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +50 -0
- data/bolt-modules/boltlib/types/planresult.pp +18 -0
- data/bolt-modules/boltlib/types/targetspec.pp +7 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +42 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/sleep.rb +20 -0
- data/bolt-modules/dir/lib/puppet/functions/dir/children.rb +35 -0
- data/bolt-modules/file/lib/puppet/functions/file/delete.rb +21 -0
- data/bolt-modules/file/lib/puppet/functions/file/exists.rb +28 -0
- data/bolt-modules/file/lib/puppet/functions/file/join.rb +20 -0
- data/bolt-modules/file/lib/puppet/functions/file/read.rb +33 -0
- data/bolt-modules/file/lib/puppet/functions/file/readable.rb +28 -0
- data/bolt-modules/file/lib/puppet/functions/file/write.rb +24 -0
- data/bolt-modules/log/lib/puppet/functions/log/debug.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/error.rb +40 -0
- data/bolt-modules/log/lib/puppet/functions/log/fatal.rb +40 -0
- data/bolt-modules/log/lib/puppet/functions/log/info.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/trace.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/warn.rb +41 -0
- data/bolt-modules/out/lib/puppet/functions/out/message.rb +36 -0
- data/bolt-modules/out/lib/puppet/functions/out/verbose.rb +35 -0
- data/bolt-modules/prompt/lib/puppet/functions/prompt/menu.rb +103 -0
- data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +65 -0
- data/bolt-modules/system/lib/puppet/functions/system/env.rb +20 -0
- data/exe/bolt +17 -0
- data/guides/debugging.yaml +27 -0
- data/guides/inventory.yaml +23 -0
- data/guides/links.yaml +12 -0
- data/guides/logging.yaml +17 -0
- data/guides/module.yaml +18 -0
- data/guides/modulepath.yaml +24 -0
- data/guides/project.yaml +21 -0
- data/guides/targets.yaml +28 -0
- data/guides/transports.yaml +22 -0
- data/lib/bolt/analytics.rb +233 -0
- data/lib/bolt/application.rb +806 -0
- data/lib/bolt/applicator.rb +368 -0
- data/lib/bolt/apply_inventory.rb +93 -0
- data/lib/bolt/apply_result.rb +154 -0
- data/lib/bolt/apply_target.rb +90 -0
- data/lib/bolt/bolt_option_parser.rb +1226 -0
- data/lib/bolt/catalog/logging.rb +15 -0
- data/lib/bolt/catalog.rb +144 -0
- data/lib/bolt/cli.rb +949 -0
- data/lib/bolt/config/modulepath.rb +30 -0
- data/lib/bolt/config/options.rb +673 -0
- data/lib/bolt/config/transport/base.rb +133 -0
- data/lib/bolt/config/transport/docker.rb +34 -0
- data/lib/bolt/config/transport/jail.rb +33 -0
- data/lib/bolt/config/transport/local.rb +39 -0
- data/lib/bolt/config/transport/lxd.rb +34 -0
- data/lib/bolt/config/transport/options.rb +431 -0
- data/lib/bolt/config/transport/orch.rb +41 -0
- data/lib/bolt/config/transport/podman.rb +33 -0
- data/lib/bolt/config/transport/remote.rb +24 -0
- data/lib/bolt/config/transport/ssh.rb +138 -0
- data/lib/bolt/config/transport/winrm.rb +63 -0
- data/lib/bolt/config.rb +515 -0
- data/lib/bolt/container_result.rb +105 -0
- data/lib/bolt/error.rb +194 -0
- data/lib/bolt/executor.rb +539 -0
- data/lib/bolt/fiber_executor.rb +190 -0
- data/lib/bolt/inventory/group.rb +446 -0
- data/lib/bolt/inventory/inventory.rb +391 -0
- data/lib/bolt/inventory/options.rb +139 -0
- data/lib/bolt/inventory/target.rb +293 -0
- data/lib/bolt/inventory.rb +120 -0
- data/lib/bolt/logger.rb +252 -0
- data/lib/bolt/module.rb +54 -0
- data/lib/bolt/module_installer/installer.rb +44 -0
- data/lib/bolt/module_installer/puppetfile/forge_module.rb +54 -0
- data/lib/bolt/module_installer/puppetfile/git_module.rb +37 -0
- data/lib/bolt/module_installer/puppetfile/module.rb +26 -0
- data/lib/bolt/module_installer/puppetfile.rb +131 -0
- data/lib/bolt/module_installer/resolver.rb +129 -0
- data/lib/bolt/module_installer/specs/forge_spec.rb +91 -0
- data/lib/bolt/module_installer/specs/git_spec.rb +150 -0
- data/lib/bolt/module_installer/specs/id/base.rb +116 -0
- data/lib/bolt/module_installer/specs/id/gitclone.rb +120 -0
- data/lib/bolt/module_installer/specs/id/github.rb +90 -0
- data/lib/bolt/module_installer/specs/id/gitlab.rb +92 -0
- data/lib/bolt/module_installer/specs.rb +95 -0
- data/lib/bolt/module_installer.rb +208 -0
- data/lib/bolt/node/errors.rb +55 -0
- data/lib/bolt/node/output.rb +29 -0
- data/lib/bolt/outputter/human.rb +958 -0
- data/lib/bolt/outputter/json.rb +205 -0
- data/lib/bolt/outputter/logger.rb +76 -0
- data/lib/bolt/outputter/rainbow.rb +118 -0
- data/lib/bolt/outputter.rb +57 -0
- data/lib/bolt/pal/issues.rb +19 -0
- data/lib/bolt/pal/logging.rb +17 -0
- data/lib/bolt/pal/yaml_plan/evaluator.rb +83 -0
- data/lib/bolt/pal/yaml_plan/loader.rb +94 -0
- data/lib/bolt/pal/yaml_plan/parameter.rb +63 -0
- data/lib/bolt/pal/yaml_plan/step/command.rb +45 -0
- data/lib/bolt/pal/yaml_plan/step/download.rb +37 -0
- data/lib/bolt/pal/yaml_plan/step/eval.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/message.rb +31 -0
- data/lib/bolt/pal/yaml_plan/step/plan.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/resources.rb +170 -0
- data/lib/bolt/pal/yaml_plan/step/script.rb +62 -0
- data/lib/bolt/pal/yaml_plan/step/task.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/upload.rb +37 -0
- data/lib/bolt/pal/yaml_plan/step/verbose.rb +31 -0
- data/lib/bolt/pal/yaml_plan/step.rb +223 -0
- data/lib/bolt/pal/yaml_plan/transpiler.rb +90 -0
- data/lib/bolt/pal/yaml_plan.rb +172 -0
- data/lib/bolt/pal.rb +847 -0
- data/lib/bolt/plan_creator.rb +219 -0
- data/lib/bolt/plan_future.rb +86 -0
- data/lib/bolt/plan_result.rb +44 -0
- data/lib/bolt/plugin/cache.rb +76 -0
- data/lib/bolt/plugin/env_var.rb +54 -0
- data/lib/bolt/plugin/module.rb +276 -0
- data/lib/bolt/plugin/prompt.rb +36 -0
- data/lib/bolt/plugin/puppet_connect_data.rb +84 -0
- data/lib/bolt/plugin/puppetdb.rb +124 -0
- data/lib/bolt/plugin/task.rb +72 -0
- data/lib/bolt/plugin.rb +380 -0
- data/lib/bolt/project.rb +219 -0
- data/lib/bolt/project_manager/config_migrator.rb +113 -0
- data/lib/bolt/project_manager/inventory_migrator.rb +67 -0
- data/lib/bolt/project_manager/migrator.rb +39 -0
- data/lib/bolt/project_manager/module_migrator.rb +203 -0
- data/lib/bolt/project_manager.rb +221 -0
- data/lib/bolt/puppetdb/client.rb +153 -0
- data/lib/bolt/puppetdb/config.rb +176 -0
- data/lib/bolt/puppetdb/instance.rb +146 -0
- data/lib/bolt/puppetdb.rb +15 -0
- data/lib/bolt/r10k_log_proxy.rb +30 -0
- data/lib/bolt/rerun.rb +55 -0
- data/lib/bolt/resource_instance.rb +133 -0
- data/lib/bolt/result.rb +247 -0
- data/lib/bolt/result_set.rb +128 -0
- data/lib/bolt/shell/bash/tmpdir.rb +62 -0
- data/lib/bolt/shell/bash.rb +516 -0
- data/lib/bolt/shell/powershell/snippets.rb +181 -0
- data/lib/bolt/shell/powershell.rb +365 -0
- data/lib/bolt/shell.rb +105 -0
- data/lib/bolt/target.rb +174 -0
- data/lib/bolt/task/puppet_server.rb +27 -0
- data/lib/bolt/task/run.rb +55 -0
- data/lib/bolt/task.rb +163 -0
- data/lib/bolt/transport/base.rb +252 -0
- data/lib/bolt/transport/docker/connection.rb +150 -0
- data/lib/bolt/transport/docker.rb +23 -0
- data/lib/bolt/transport/jail/connection.rb +81 -0
- data/lib/bolt/transport/jail.rb +21 -0
- data/lib/bolt/transport/local/connection.rb +106 -0
- data/lib/bolt/transport/local.rb +20 -0
- data/lib/bolt/transport/lxd/connection.rb +115 -0
- data/lib/bolt/transport/lxd.rb +26 -0
- data/lib/bolt/transport/orch/connection.rb +111 -0
- data/lib/bolt/transport/orch.rb +271 -0
- data/lib/bolt/transport/podman/connection.rb +102 -0
- data/lib/bolt/transport/podman.rb +19 -0
- data/lib/bolt/transport/remote.rb +41 -0
- data/lib/bolt/transport/simple.rb +54 -0
- data/lib/bolt/transport/ssh/connection.rb +321 -0
- data/lib/bolt/transport/ssh/exec_connection.rb +140 -0
- data/lib/bolt/transport/ssh.rb +48 -0
- data/lib/bolt/transport/winrm/connection.rb +378 -0
- data/lib/bolt/transport/winrm.rb +33 -0
- data/lib/bolt/util/format.rb +68 -0
- data/lib/bolt/util/puppet_log_level.rb +21 -0
- data/lib/bolt/util.rb +465 -0
- data/lib/bolt/validator.rb +227 -0
- data/lib/bolt/version.rb +5 -0
- data/lib/bolt.rb +8 -0
- data/lib/bolt_server/acl.rb +39 -0
- data/lib/bolt_server/base_config.rb +112 -0
- data/lib/bolt_server/config.rb +64 -0
- data/lib/bolt_server/file_cache.rb +200 -0
- data/lib/bolt_server/request_error.rb +11 -0
- data/lib/bolt_server/schemas/action-check_node_connections.json +14 -0
- data/lib/bolt_server/schemas/action-run_command.json +12 -0
- data/lib/bolt_server/schemas/action-run_script.json +47 -0
- data/lib/bolt_server/schemas/action-run_task.json +20 -0
- data/lib/bolt_server/schemas/action-upload_file.json +47 -0
- data/lib/bolt_server/schemas/partials/target-any.json +10 -0
- data/lib/bolt_server/schemas/partials/target-ssh.json +88 -0
- data/lib/bolt_server/schemas/partials/target-winrm.json +67 -0
- data/lib/bolt_server/schemas/partials/task.json +94 -0
- data/lib/bolt_server/schemas/transport-ssh.json +25 -0
- data/lib/bolt_server/schemas/transport-winrm.json +19 -0
- data/lib/bolt_server/transport_app.rb +554 -0
- data/lib/bolt_spec/bolt_context.rb +226 -0
- data/lib/bolt_spec/plans/action_stubs/command_stub.rb +51 -0
- data/lib/bolt_spec/plans/action_stubs/download_stub.rb +66 -0
- data/lib/bolt_spec/plans/action_stubs/plan_stub.rb +55 -0
- data/lib/bolt_spec/plans/action_stubs/script_stub.rb +59 -0
- data/lib/bolt_spec/plans/action_stubs/task_stub.rb +57 -0
- data/lib/bolt_spec/plans/action_stubs/upload_stub.rb +65 -0
- data/lib/bolt_spec/plans/action_stubs.rb +196 -0
- data/lib/bolt_spec/plans/mock_executor.rb +361 -0
- data/lib/bolt_spec/plans/publish_stub.rb +49 -0
- data/lib/bolt_spec/plans.rb +190 -0
- data/lib/bolt_spec/run.rb +246 -0
- data/lib/logging_extensions/logging.rb +13 -0
- data/libexec/apply_catalog.rb +130 -0
- data/libexec/bolt_catalog +68 -0
- data/libexec/custom_facts.rb +63 -0
- data/libexec/query_resources.rb +75 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/count.rb +21 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/nodes.rb +22 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/targets.rb +21 -0
- data/modules/aggregate/plans/count.pp +56 -0
- data/modules/aggregate/plans/targets.pp +56 -0
- data/modules/canary/lib/puppet/functions/canary/merge.rb +13 -0
- data/modules/canary/lib/puppet/functions/canary/random_split.rb +22 -0
- data/modules/canary/lib/puppet/functions/canary/skip.rb +25 -0
- data/modules/canary/plans/init.pp +100 -0
- data/modules/puppet_connect/plans/test_input_data.pp +94 -0
- data/modules/puppetdb_fact/plans/init.pp +20 -0
- data/resources/bolt_bash_completion.sh +214 -0
- metadata +735 -0
data/guides/module.yaml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
topic: module
|
3
|
+
guide: |
|
4
|
+
Modules are shareable, reusable packages of Puppet content. They can include
|
5
|
+
tasks, plans, functions, and other types of content that you can use in your
|
6
|
+
project. You can download and install modules to your project from the
|
7
|
+
Puppet Forge or write your own modules. Bolt also ships with several helpful
|
8
|
+
modules pre-installed that are available to all of your projects.
|
9
|
+
|
10
|
+
Bolt makes it easy to manage the modules that your project depends on. You
|
11
|
+
can use Bolt commands to install a project's modules, add new modules to a
|
12
|
+
project, and view the modules that are available to the project.
|
13
|
+
|
14
|
+
To learn more about managing modules in a project, see the documentation.
|
15
|
+
To learn how modules are loaded by Bolt, see the 'modulepath' guide.
|
16
|
+
|
17
|
+
documentation:
|
18
|
+
- https://pup.pt/bolt-modules
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
topic: modulepath
|
3
|
+
guide: |
|
4
|
+
The modulepath is an ordered list of directories that Bolt loads modules
|
5
|
+
from. When Bolt runs a command, it automatically loads modules from the
|
6
|
+
modulepath.
|
7
|
+
|
8
|
+
While Bolt has a default modulepath, you can also configure your own
|
9
|
+
modulepath, which can include directories within the project or directories
|
10
|
+
elsewhere on your system. Regardless of whether your project uses a default
|
11
|
+
or configured modulepath, Bolt automatically adds directories to the
|
12
|
+
modulepath. This includes modules containing core Bolt content, which is
|
13
|
+
added to the beginning of the modulepath, and bundled content, which is
|
14
|
+
added to the end of the modulepath.
|
15
|
+
|
16
|
+
Modules loaded from a directory listed earlier in the modulepath take
|
17
|
+
precedence over modules with the same name loaded from a directory later in
|
18
|
+
the modulepath. Bolt will not warn or error when two modules share a name
|
19
|
+
and instead will ignore modules with a lower precedence.
|
20
|
+
|
21
|
+
To learn more about modules, see the 'module' guide.
|
22
|
+
|
23
|
+
documentation:
|
24
|
+
- https://pup.pt/bolt-project-reference#modulepath
|
data/guides/project.yaml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
topic: project
|
3
|
+
guide: |
|
4
|
+
A Bolt project is a directory that serves as the launching point for Bolt
|
5
|
+
and allows you to create a shareable orchestration application. Projects
|
6
|
+
typically include a project configuration file, an inventory file, and any
|
7
|
+
content you use in your project workflow, such as tasks and plans.
|
8
|
+
|
9
|
+
When you run Bolt, it runs in the context of a project. If the directory you
|
10
|
+
run Bolt from is not a project, Bolt attempts to find a project by
|
11
|
+
traversing the parent directories. If Bolt is unable to find a project, it
|
12
|
+
runs from the default project, located at '~/.puppetlabs/bolt'.
|
13
|
+
|
14
|
+
A directory is only considered a Bolt project when it has a project
|
15
|
+
configuration file named 'bolt-project.yaml'. Bolt doesn't load project data
|
16
|
+
and content, including inventory files, unless the data and content are part
|
17
|
+
of a project.
|
18
|
+
|
19
|
+
documentation:
|
20
|
+
- https://pup.pt/bolt-projects
|
21
|
+
- https://pup.pt/bolt-project-reference
|
data/guides/targets.yaml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
topic: targets
|
3
|
+
guide: |
|
4
|
+
A target is a device that Bolt connects to and runs actions on. Targets can
|
5
|
+
be physical, such as servers, or virtual, such as containers or virtual
|
6
|
+
machines.
|
7
|
+
|
8
|
+
Several of Bolt's commands connect to targets and run actions on them.
|
9
|
+
These commands require a target or targets to run on. You can specify
|
10
|
+
targets to a command using one of the following command-line options:
|
11
|
+
|
12
|
+
*nix options Powershell options
|
13
|
+
-t, --targets TARGETS -T, -Targets TARGETS
|
14
|
+
-q, --query QUERY -Q, -Query QUERY
|
15
|
+
--rerun FILTER -Rerun FILTER
|
16
|
+
|
17
|
+
The 'targets' option accepts a comma-separated list of target URIs or group
|
18
|
+
names, or can read a target list from an input file '@<file>' or stdin '-'.
|
19
|
+
URIs can be specified with the format [protocol://][user@]host[:port]. To
|
20
|
+
learn more about available protocols and their defaults, run 'bolt guide
|
21
|
+
transports'.
|
22
|
+
|
23
|
+
Typically, targets and their configuration and data are listed in a
|
24
|
+
project's inventory file. For more information about inventory files,
|
25
|
+
see 'bolt guide inventory'.
|
26
|
+
|
27
|
+
documentation:
|
28
|
+
- https://pup.pt/bolt-commands
|
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
topic: transports
|
3
|
+
guide: |
|
4
|
+
Bolt uses transports (also known as protocols) to establish a connection
|
5
|
+
with a target in order to run actions on the target. The default transport is
|
6
|
+
SSH, and you can see available transports along with their configuration
|
7
|
+
options and defaults at http://pup.pt/bolt-reference.
|
8
|
+
|
9
|
+
You can specify a transport for a target by prepending '<transport>://' to
|
10
|
+
the target's URI. For example, to connect to a target with hostname
|
11
|
+
'example.com' as user 'Administrator' using the WinRM transport, you would
|
12
|
+
pass the following to the target flag:
|
13
|
+
winrm://Administrator@example.com
|
14
|
+
|
15
|
+
You can also specify a default transport for all targets by passing the
|
16
|
+
'--transport' flag on *nix systems and the '-Transport' flag in Powershell.
|
17
|
+
Finally, you can set the transport for a target in the inventory. For more
|
18
|
+
information about the Bolt inventory, run 'bolt guide inventory'.
|
19
|
+
|
20
|
+
documentation:
|
21
|
+
- https://pup.pt/bolt-commands#specify-a-transport
|
22
|
+
- http://pup.pt/bolt-inventory#transport-configuration
|
@@ -0,0 +1,233 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../bolt/util'
|
4
|
+
require_relative '../bolt/version'
|
5
|
+
require 'find'
|
6
|
+
require 'json'
|
7
|
+
require 'logging'
|
8
|
+
require 'securerandom'
|
9
|
+
|
10
|
+
module Bolt
|
11
|
+
module Analytics
|
12
|
+
PROTOCOL_VERSION = 1
|
13
|
+
APPLICATION_NAME = 'bolt'
|
14
|
+
TRACKING_ID = 'UA-120367942-1'
|
15
|
+
TRACKING_URL = 'https://google-analytics.com/collect'
|
16
|
+
CUSTOM_DIMENSIONS = {
|
17
|
+
operating_system: :cd1,
|
18
|
+
inventory_nodes: :cd2,
|
19
|
+
inventory_groups: :cd3,
|
20
|
+
target_nodes: :cd4,
|
21
|
+
output_format: :cd5,
|
22
|
+
statement_count: :cd6,
|
23
|
+
resource_mean: :cd7,
|
24
|
+
plan_steps: :cd8,
|
25
|
+
return_type: :cd9,
|
26
|
+
inventory_version: :cd10,
|
27
|
+
boltdir_type: :cd11,
|
28
|
+
puppet_plan_count: :cd12,
|
29
|
+
yaml_plan_count: :cd13
|
30
|
+
}.freeze
|
31
|
+
|
32
|
+
def self.build_client(enabled = true)
|
33
|
+
begin
|
34
|
+
config_file = config_path
|
35
|
+
config = enabled ? load_config(config_file) : {}
|
36
|
+
rescue ArgumentError
|
37
|
+
config = { 'disabled' => true }
|
38
|
+
end
|
39
|
+
|
40
|
+
if !enabled || config['disabled'] || ENV['BOLT_DISABLE_ANALYTICS']
|
41
|
+
Bolt::Logger.debug "Analytics opt-out is set, analytics will be disabled"
|
42
|
+
NoopClient.new
|
43
|
+
else
|
44
|
+
unless config.key?('user-id')
|
45
|
+
config['user-id'] = SecureRandom.uuid
|
46
|
+
write_config(config_file, config)
|
47
|
+
end
|
48
|
+
|
49
|
+
Client.new(config['user-id'])
|
50
|
+
end
|
51
|
+
rescue StandardError => e
|
52
|
+
Bolt::Logger.debug "Failed to initialize analytics client, analytics will be disabled: #{e}"
|
53
|
+
NoopClient.new
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.config_path
|
57
|
+
path = File.expand_path(File.join('~', '.puppetlabs', 'etc', 'bolt', 'analytics.yaml'))
|
58
|
+
old_path = File.expand_path(File.join('~', '.puppetlabs', 'bolt', 'analytics.yaml'))
|
59
|
+
|
60
|
+
if File.exist?(path)
|
61
|
+
if File.exist?(old_path)
|
62
|
+
message = "Detected analytics configuration files at '#{old_path}' and '#{path}'. Loading "\
|
63
|
+
"analytics configuration from '#{path}'."
|
64
|
+
Bolt::Logger.warn_once('duplicate_analytics', message)
|
65
|
+
end
|
66
|
+
|
67
|
+
path
|
68
|
+
elsif File.exist?(old_path)
|
69
|
+
old_path
|
70
|
+
else
|
71
|
+
path
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.load_config(filename)
|
76
|
+
if File.exist?(filename)
|
77
|
+
Bolt::Util.read_optional_yaml_hash(filename, 'analytics')
|
78
|
+
else
|
79
|
+
unless ENV['BOLT_DISABLE_ANALYTICS']
|
80
|
+
msg = <<~ANALYTICS
|
81
|
+
Bolt collects data about how you use it. You can opt out of providing this data.
|
82
|
+
To learn how to disable data collection, or see what data Bolt collects and why,
|
83
|
+
see http://pup.pt/bolt-analytics
|
84
|
+
ANALYTICS
|
85
|
+
Bolt::Logger.warn_once('analytics_opt_out', msg)
|
86
|
+
end
|
87
|
+
|
88
|
+
{}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.write_config(filename, config)
|
93
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
94
|
+
File.write(filename, config.to_yaml)
|
95
|
+
rescue StandardError => e
|
96
|
+
Bolt::Logger.warn_once('unwriteable_file', "Could not write analytics configuration to #{filename}.")
|
97
|
+
# This will get caught by build_client and create a NoopClient
|
98
|
+
raise e
|
99
|
+
end
|
100
|
+
|
101
|
+
class Client
|
102
|
+
attr_reader :user_id
|
103
|
+
attr_accessor :bundled_content
|
104
|
+
|
105
|
+
def initialize(user_id)
|
106
|
+
# lazy-load expensive gem code
|
107
|
+
require 'concurrent/configuration'
|
108
|
+
require 'concurrent/future'
|
109
|
+
require 'httpclient'
|
110
|
+
require 'locale'
|
111
|
+
|
112
|
+
@logger = Bolt::Logger.logger(self)
|
113
|
+
@http = HTTPClient.new
|
114
|
+
@user_id = user_id
|
115
|
+
@executor = Concurrent.global_io_executor
|
116
|
+
@os = compute_os
|
117
|
+
@bundled_content = {}
|
118
|
+
end
|
119
|
+
|
120
|
+
def screen_view(screen, **kwargs)
|
121
|
+
custom_dimensions = Bolt::Util.walk_keys(kwargs) do |k|
|
122
|
+
CUSTOM_DIMENSIONS[k] || raise("Unknown analytics key '#{k}'")
|
123
|
+
end
|
124
|
+
|
125
|
+
screen_view_params = {
|
126
|
+
# Type
|
127
|
+
t: 'screenview',
|
128
|
+
# Screen Name
|
129
|
+
cd: screen
|
130
|
+
}.merge(custom_dimensions)
|
131
|
+
|
132
|
+
submit(base_params.merge(screen_view_params))
|
133
|
+
end
|
134
|
+
|
135
|
+
def report_bundled_content(mode, name)
|
136
|
+
if bundled_content[mode.split.first]&.include?(name)
|
137
|
+
event('Bundled Content', mode, label: name)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def event(category, action, label: nil, value: nil, **kwargs)
|
142
|
+
custom_dimensions = Bolt::Util.walk_keys(kwargs) do |k|
|
143
|
+
CUSTOM_DIMENSIONS[k] || raise("Unknown analytics key '#{k}'")
|
144
|
+
end
|
145
|
+
|
146
|
+
event_params = {
|
147
|
+
# Type
|
148
|
+
t: 'event',
|
149
|
+
# Event Category
|
150
|
+
ec: category,
|
151
|
+
# Event Action
|
152
|
+
ea: action
|
153
|
+
}.merge(custom_dimensions)
|
154
|
+
|
155
|
+
# Event Label
|
156
|
+
event_params[:el] = label if label
|
157
|
+
# Event Value
|
158
|
+
event_params[:ev] = value if value
|
159
|
+
|
160
|
+
submit(base_params.merge(event_params))
|
161
|
+
end
|
162
|
+
|
163
|
+
def submit(params)
|
164
|
+
# Handle analytics submission in the background to avoid blocking the
|
165
|
+
# app or polluting the log with errors
|
166
|
+
Concurrent::Future.execute(executor: @executor) do
|
167
|
+
@logger.trace "Submitting analytics: #{JSON.pretty_generate(params)}"
|
168
|
+
@http.post(TRACKING_URL, params)
|
169
|
+
@logger.trace "Completed analytics submission"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# These parameters have terrible names. See this page for complete documentation:
|
174
|
+
# https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
|
175
|
+
def base_params
|
176
|
+
{
|
177
|
+
v: PROTOCOL_VERSION,
|
178
|
+
# Client ID
|
179
|
+
cid: @user_id,
|
180
|
+
# Tracking ID
|
181
|
+
tid: TRACKING_ID,
|
182
|
+
# Application Name
|
183
|
+
an: APPLICATION_NAME,
|
184
|
+
# Application Version
|
185
|
+
av: Bolt::VERSION,
|
186
|
+
# Anonymize IPs
|
187
|
+
aip: true,
|
188
|
+
# User locale
|
189
|
+
ul: Locale.current.to_rfc,
|
190
|
+
# Custom Dimension 1 (Operating System)
|
191
|
+
cd1: @os
|
192
|
+
}
|
193
|
+
end
|
194
|
+
|
195
|
+
def compute_os
|
196
|
+
require 'facter'
|
197
|
+
os = Facter.value('os')
|
198
|
+
"#{os['name']} #{os.dig('release', 'major')}"
|
199
|
+
end
|
200
|
+
|
201
|
+
# If the user is running a very fast command, there may not be time for
|
202
|
+
# analytics submission to complete before the command is finished. In
|
203
|
+
# that case, we give a little buffer for any stragglers to finish up.
|
204
|
+
# 250ms strikes a balance between accomodating slower networks while not
|
205
|
+
# introducing a noticeable "hang".
|
206
|
+
def finish
|
207
|
+
@executor.shutdown
|
208
|
+
@executor.wait_for_termination(0.25)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
class NoopClient
|
213
|
+
attr_accessor :bundled_content
|
214
|
+
|
215
|
+
def initialize
|
216
|
+
@logger = Bolt::Logger.logger(self)
|
217
|
+
@bundled_content = []
|
218
|
+
end
|
219
|
+
|
220
|
+
def screen_view(screen, **_kwargs)
|
221
|
+
@logger.trace "Skipping submission of '#{screen}' screenview because analytics is disabled"
|
222
|
+
end
|
223
|
+
|
224
|
+
def report_bundled_content(mode, name); end
|
225
|
+
|
226
|
+
def event(category, action, **_kwargs)
|
227
|
+
@logger.trace "Skipping submission of '#{category} #{action}' event because analytics is disabled"
|
228
|
+
end
|
229
|
+
|
230
|
+
def finish; end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|