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
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../bolt/project_manager/migrator'
|
4
|
+
|
5
|
+
module Bolt
|
6
|
+
class ProjectManager
|
7
|
+
class InventoryMigrator < Migrator
|
8
|
+
def migrate(inventory_file, backup_dir)
|
9
|
+
inventory1to2(inventory_file, backup_dir)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Migrates an inventory v1 file to inventory v2.
|
13
|
+
#
|
14
|
+
private def inventory1to2(inventory_file, backup_dir)
|
15
|
+
unless File.exist?(inventory_file)
|
16
|
+
return true
|
17
|
+
end
|
18
|
+
|
19
|
+
data = Bolt::Util.read_yaml_hash(inventory_file, 'inventory')
|
20
|
+
data.delete('version') if data['version'] != 2
|
21
|
+
migrated = migrate_group(data)
|
22
|
+
|
23
|
+
return true unless migrated
|
24
|
+
|
25
|
+
@outputter.print_message "Migrating inventory\n\n"
|
26
|
+
|
27
|
+
backup_file(inventory_file, backup_dir)
|
28
|
+
|
29
|
+
begin
|
30
|
+
File.write(inventory_file, data.to_yaml)
|
31
|
+
@outputter.print_action_step(
|
32
|
+
"Successfully migrated Bolt inventory to the latest version."
|
33
|
+
)
|
34
|
+
true
|
35
|
+
rescue StandardError => e
|
36
|
+
raise Bolt::FileError.new(
|
37
|
+
"Unable to write to #{inventory_file}: #{e.message}. See "\
|
38
|
+
"http://pup.pt/bolt-inventory to manually update.",
|
39
|
+
inventory_file
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Walks an inventory hash and replaces all 'nodes' keys with 'targets'
|
45
|
+
# keys and all 'name' keys nested in a 'targets' hash with 'uri' keys.
|
46
|
+
# Data is modified in place.
|
47
|
+
#
|
48
|
+
private def migrate_group(group)
|
49
|
+
migrated = false
|
50
|
+
if group.key?('nodes')
|
51
|
+
migrated = true
|
52
|
+
targets = group['nodes'].map do |target|
|
53
|
+
target['uri'] = target.delete('name') if target.is_a?(Hash)
|
54
|
+
target
|
55
|
+
end
|
56
|
+
group.delete('nodes')
|
57
|
+
group['targets'] = targets
|
58
|
+
end
|
59
|
+
(group['groups'] || []).each do |subgroup|
|
60
|
+
migrated_group = migrate_group(subgroup)
|
61
|
+
migrated ||= migrated_group
|
62
|
+
end
|
63
|
+
migrated
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require_relative '../../bolt/error'
|
5
|
+
|
6
|
+
module Bolt
|
7
|
+
class ProjectManager
|
8
|
+
class Migrator
|
9
|
+
def initialize(outputter)
|
10
|
+
@outputter = outputter
|
11
|
+
end
|
12
|
+
|
13
|
+
protected def backup_file(origin_path, backup_dir)
|
14
|
+
unless File.exist?(origin_path)
|
15
|
+
@outputter.print_action_step(
|
16
|
+
"Could not find file #{origin_path}, skipping backup."
|
17
|
+
)
|
18
|
+
return
|
19
|
+
end
|
20
|
+
|
21
|
+
date = Time.new.strftime("%Y%m%d_%H%M%S%L")
|
22
|
+
FileUtils.mkdir_p(backup_dir)
|
23
|
+
|
24
|
+
filename = File.basename(origin_path)
|
25
|
+
backup_path = File.join(backup_dir, "#{filename}.#{date}.bak")
|
26
|
+
|
27
|
+
@outputter.print_action_step(
|
28
|
+
"Backing up #{filename} from #{origin_path} to #{backup_path}"
|
29
|
+
)
|
30
|
+
|
31
|
+
begin
|
32
|
+
FileUtils.cp(origin_path, backup_path)
|
33
|
+
rescue StandardError => e
|
34
|
+
raise Bolt::FileError.new("#{e.message}; unable to create backup of #{filename}.", origin_path)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../bolt/project_manager/migrator'
|
4
|
+
|
5
|
+
module Bolt
|
6
|
+
class ProjectManager
|
7
|
+
class ModuleMigrator < Migrator
|
8
|
+
def migrate(project, configured_modulepath)
|
9
|
+
return true if project.managed_moduledir.exist?
|
10
|
+
|
11
|
+
@outputter.print_message "Migrating project modules\n\n"
|
12
|
+
|
13
|
+
config = project.project_file
|
14
|
+
puppetfile = project.puppetfile
|
15
|
+
managed_moduledir = project.managed_moduledir
|
16
|
+
new_modulepath = [(project.path + 'modules').to_s]
|
17
|
+
old_modulepath = [(project.path + 'modules').to_s,
|
18
|
+
(project.path + 'site-modules').to_s,
|
19
|
+
(project.path + 'site').to_s]
|
20
|
+
|
21
|
+
# Notify user to manually migrate modules if using non-default modulepath
|
22
|
+
if configured_modulepath != new_modulepath && configured_modulepath != old_modulepath
|
23
|
+
@outputter.print_action_step(
|
24
|
+
"Project has a non-default configured modulepath, unable to automatically "\
|
25
|
+
"migrate project modules. To migrate project modules manually, see "\
|
26
|
+
"http://pup.pt/bolt-modules"
|
27
|
+
)
|
28
|
+
true
|
29
|
+
# Migrate modules from Puppetfile
|
30
|
+
elsif File.exist?(puppetfile)
|
31
|
+
migrate_modules_from_puppetfile(config, puppetfile, managed_moduledir, old_modulepath)
|
32
|
+
# Migrate modules to updated modulepath
|
33
|
+
else
|
34
|
+
consolidate_modules(old_modulepath)
|
35
|
+
update_project_config([], config)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Migrates modules by reading a Puppetfile and prompting the user for
|
40
|
+
# which ones are direct dependencies for the project. Once the user has
|
41
|
+
# selected the direct dependencies, this will resolve the modules, write a
|
42
|
+
# new Puppetfile, install the modules, and then move any remaining modules
|
43
|
+
# to the new moduledir.
|
44
|
+
#
|
45
|
+
private def migrate_modules_from_puppetfile(config, puppetfile_path, managed_moduledir, modulepath)
|
46
|
+
require_relative '../../bolt/module_installer/installer'
|
47
|
+
require_relative '../../bolt/module_installer/puppetfile'
|
48
|
+
require_relative '../../bolt/module_installer/resolver'
|
49
|
+
require_relative '../../bolt/module_installer/specs'
|
50
|
+
|
51
|
+
begin
|
52
|
+
@outputter.print_action_step("Parsing Puppetfile at #{puppetfile_path}")
|
53
|
+
puppetfile = Bolt::ModuleInstaller::Puppetfile.parse(puppetfile_path, skip_unsupported_modules: true)
|
54
|
+
rescue Bolt::Error => e
|
55
|
+
@outputter.print_action_error("#{e.message}\nSkipping module migration.")
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
|
59
|
+
# Prompt for direct dependencies
|
60
|
+
modules = select_modules(puppetfile.modules)
|
61
|
+
|
62
|
+
# Create specs to resolve from
|
63
|
+
specs = Bolt::ModuleInstaller::Specs.new(modules.map(&:to_hash))
|
64
|
+
|
65
|
+
@outputter.start_spin
|
66
|
+
# Attempt to resolve dependencies
|
67
|
+
begin
|
68
|
+
@outputter.print_message('')
|
69
|
+
@outputter.print_action_step("Resolving module dependencies, this might take a moment")
|
70
|
+
puppetfile = Bolt::ModuleInstaller::Resolver.new.resolve(specs)
|
71
|
+
rescue Bolt::Error => e
|
72
|
+
@outputter.print_action_error("#{e.message}\nSkipping module migration.")
|
73
|
+
return false
|
74
|
+
end
|
75
|
+
|
76
|
+
migrate_managed_modules(puppetfile, puppetfile_path, managed_moduledir)
|
77
|
+
@outputter.stop_spin
|
78
|
+
|
79
|
+
# Move remaining modules to 'modules'
|
80
|
+
consolidate_modules(modulepath)
|
81
|
+
|
82
|
+
# Delete old modules that are now managed
|
83
|
+
delete_modules(modulepath.first, puppetfile.modules)
|
84
|
+
|
85
|
+
# Add modules to project
|
86
|
+
update_project_config(modules.map(&:to_hash), config)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Migrates the managed modules. If modules were selected to be managed,
|
90
|
+
# the Puppetfile is rewritten and modules are installed. If no modules
|
91
|
+
# were selected, the Puppetfile is deleted.
|
92
|
+
#
|
93
|
+
private def migrate_managed_modules(puppetfile, puppetfile_path, managed_moduledir)
|
94
|
+
if puppetfile.modules.any?
|
95
|
+
# Show the new Puppetfile content
|
96
|
+
message = "Generated new Puppetfile content:\n\n"
|
97
|
+
message += puppetfile.modules.map(&:to_spec).join("\n").to_s
|
98
|
+
@outputter.print_action_step(message)
|
99
|
+
|
100
|
+
# Write Puppetfile
|
101
|
+
@outputter.print_action_step("Updating Puppetfile at #{puppetfile_path}")
|
102
|
+
puppetfile.write(puppetfile_path, managed_moduledir)
|
103
|
+
|
104
|
+
# Install Puppetfile
|
105
|
+
@outputter.print_action_step("Syncing modules from #{puppetfile_path} to #{managed_moduledir}")
|
106
|
+
Bolt::ModuleInstaller::Installer.new.install(puppetfile_path, managed_moduledir)
|
107
|
+
else
|
108
|
+
@outputter.print_action_step(
|
109
|
+
"Project does not include any managed modules, deleting Puppetfile "\
|
110
|
+
"at #{puppetfile_path}"
|
111
|
+
)
|
112
|
+
FileUtils.rm(puppetfile_path)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Prompts the user to select modules, returning a list of
|
117
|
+
# the selected modules.
|
118
|
+
#
|
119
|
+
private def select_modules(modules)
|
120
|
+
@outputter.print_action_step(
|
121
|
+
"Select modules that are direct dependencies of your project. Bolt will "\
|
122
|
+
"automatically manage dependencies for each module selected, so do not "\
|
123
|
+
"select a module's dependencies unless you use content from it directly "\
|
124
|
+
"in your project."
|
125
|
+
)
|
126
|
+
|
127
|
+
all = Bolt::Util.prompt_yes_no("Select all modules?", @outputter)
|
128
|
+
return modules if all
|
129
|
+
|
130
|
+
modules.select do |mod|
|
131
|
+
Bolt::Util.prompt_yes_no("Select #{mod.full_name}?", @outputter)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Consolidates all modules on the modulepath to 'modules'.
|
136
|
+
#
|
137
|
+
private def consolidate_modules(modulepath)
|
138
|
+
moduledir, *sources = modulepath
|
139
|
+
|
140
|
+
sources.select! { |source| Dir.exist?(source) }
|
141
|
+
|
142
|
+
if sources.any?
|
143
|
+
@outputter.print_action_step(
|
144
|
+
"Moving modules from #{sources.join(', ')} to #{moduledir}"
|
145
|
+
)
|
146
|
+
|
147
|
+
FileUtils.mkdir_p(moduledir)
|
148
|
+
move_modules(moduledir, sources)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Moves modules from a list of source directories to the specified
|
153
|
+
# moduledir, deleting the source directory after it's done.
|
154
|
+
#
|
155
|
+
private def move_modules(moduledir, sources)
|
156
|
+
moduledir = Pathname.new(moduledir)
|
157
|
+
|
158
|
+
sources.each do |source|
|
159
|
+
source = Pathname.new(source)
|
160
|
+
|
161
|
+
source.each_child do |mod|
|
162
|
+
next unless mod.directory?
|
163
|
+
next if (moduledir + mod.basename).directory?
|
164
|
+
FileUtils.mv(mod, moduledir)
|
165
|
+
end
|
166
|
+
|
167
|
+
FileUtils.rm_r(source)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# Deletes modules from a specified directory.
|
172
|
+
#
|
173
|
+
private def delete_modules(moduledir, modules)
|
174
|
+
@outputter.print_action_step("Cleaning up #{moduledir}")
|
175
|
+
moduledir = Pathname.new(moduledir)
|
176
|
+
|
177
|
+
modules.each do |mod|
|
178
|
+
path = moduledir + mod.name
|
179
|
+
FileUtils.rm_r(path) if path.directory?
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Adds a list of modules to the project configuration file.
|
184
|
+
#
|
185
|
+
private def update_project_config(modules, config_file)
|
186
|
+
@outputter.print_action_step("Updating project configuration at #{config_file}")
|
187
|
+
data = Bolt::Util.read_optional_yaml_hash(config_file, 'project')
|
188
|
+
data.merge!('modules' => modules)
|
189
|
+
data.delete('modulepath')
|
190
|
+
|
191
|
+
begin
|
192
|
+
File.write(config_file, data.to_yaml)
|
193
|
+
true
|
194
|
+
rescue StandardError => e
|
195
|
+
raise Bolt::FileError.new(
|
196
|
+
"Unable to write to #{config_file}: #{e.message}",
|
197
|
+
config_file
|
198
|
+
)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'project_manager/config_migrator'
|
4
|
+
require_relative 'project_manager/inventory_migrator'
|
5
|
+
require_relative 'project_manager/module_migrator'
|
6
|
+
|
7
|
+
module Bolt
|
8
|
+
class ProjectManager
|
9
|
+
INVENTORY_TEMPLATE = <<~INVENTORY
|
10
|
+
# This is an example inventory.yaml
|
11
|
+
# To read more about inventory files, see https://pup.pt/bolt-inventory
|
12
|
+
#
|
13
|
+
# groups:
|
14
|
+
# - name: linux
|
15
|
+
# targets:
|
16
|
+
# - target1.example.com
|
17
|
+
# - target2.example.com
|
18
|
+
# config:
|
19
|
+
# transport: ssh
|
20
|
+
# ssh:
|
21
|
+
# private-key: /path/to/private_key.pem
|
22
|
+
# - name: windows
|
23
|
+
# targets:
|
24
|
+
# - name: win1
|
25
|
+
# uri: target3.example.com
|
26
|
+
# - name: win2
|
27
|
+
# uri: target4.example.com
|
28
|
+
# config:
|
29
|
+
# transport: winrm
|
30
|
+
# config:
|
31
|
+
# ssh:
|
32
|
+
# host-key-check: false
|
33
|
+
# winrm:
|
34
|
+
# user: Administrator
|
35
|
+
# password: Bolt!
|
36
|
+
# ssl: false
|
37
|
+
INVENTORY
|
38
|
+
|
39
|
+
GITIGNORE_CONTENT = <<~GITIGNORE
|
40
|
+
.modules/
|
41
|
+
.resource_types/
|
42
|
+
bolt-debug.log
|
43
|
+
.plan_cache.json
|
44
|
+
.plugin_cache.json
|
45
|
+
.task_cache.json
|
46
|
+
.rerun.json
|
47
|
+
GITIGNORE
|
48
|
+
|
49
|
+
def initialize(config, outputter, pal)
|
50
|
+
@config = config
|
51
|
+
@outputter = outputter
|
52
|
+
@pal = pal
|
53
|
+
end
|
54
|
+
|
55
|
+
# Creates a new project at the specified directory.
|
56
|
+
#
|
57
|
+
def create(path, name, modules)
|
58
|
+
require_relative '../bolt/module_installer'
|
59
|
+
|
60
|
+
project = Pathname.new(File.expand_path(path))
|
61
|
+
old_config = project + 'bolt.yaml'
|
62
|
+
config = project + 'bolt-project.yaml'
|
63
|
+
puppetfile = project + 'Puppetfile'
|
64
|
+
moduledir = project + '.modules'
|
65
|
+
inventoryfile = project + 'inventory.yaml'
|
66
|
+
gitignore = project + '.gitignore'
|
67
|
+
project_name = name || File.basename(project)
|
68
|
+
|
69
|
+
if config.exist?
|
70
|
+
if modules
|
71
|
+
command = Bolt::Util.powershell? ? 'Add-BoltModule -Module' : 'bolt module add'
|
72
|
+
raise Bolt::Error.new(
|
73
|
+
"Found existing project directory with #{config.basename} at #{project}, "\
|
74
|
+
"unable to initialize project with modules. To add modules to the project, "\
|
75
|
+
"run '#{command} <module>' instead.",
|
76
|
+
'bolt/existing-project-error'
|
77
|
+
)
|
78
|
+
else
|
79
|
+
raise Bolt::Error.new(
|
80
|
+
"Found existing project directory with #{config.basename} at #{project}, "\
|
81
|
+
"unable to initialize project.",
|
82
|
+
'bolt/existing-project-error'
|
83
|
+
)
|
84
|
+
end
|
85
|
+
elsif old_config.exist?
|
86
|
+
command = Bolt::Util.powershell? ? 'Update-BoltProject' : 'bolt project migrate'
|
87
|
+
raise Bolt::Error.new(
|
88
|
+
"Found existing project directory with #{old_config.basename} at #{project}, "\
|
89
|
+
"unable to initialize project. #{old_config.basename} is deprecated. To "\
|
90
|
+
"update the project to current best practices, run '#{command}'.",
|
91
|
+
'bolt/existing-project-error'
|
92
|
+
)
|
93
|
+
elsif modules && puppetfile.exist?
|
94
|
+
raise Bolt::Error.new(
|
95
|
+
"Found existing Puppetfile at #{puppetfile}, unable to initialize project "\
|
96
|
+
"with modules.",
|
97
|
+
'bolt/existing-puppetfile-error'
|
98
|
+
)
|
99
|
+
elsif project_name !~ Bolt::Module::MODULE_NAME_REGEX
|
100
|
+
if name
|
101
|
+
raise Bolt::ValidationError,
|
102
|
+
"The provided project name '#{project_name}' is invalid; project name must "\
|
103
|
+
"begin with a lowercase letter and can include lowercase letters, "\
|
104
|
+
"numbers, and underscores."
|
105
|
+
else
|
106
|
+
command = Bolt::Util.powershell? ? 'New-BoltProject -Name' : 'bolt project init'
|
107
|
+
raise Bolt::ValidationError,
|
108
|
+
"The current directory name '#{project_name}' is an invalid project name. "\
|
109
|
+
"Please specify a name using '#{command} <name>'."
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# If modules were specified, resolve and install first. We want to error
|
114
|
+
# early here and not initialize the project if the modules cannot be
|
115
|
+
# resolved and installed.
|
116
|
+
if modules
|
117
|
+
@outputter.start_spin
|
118
|
+
Bolt::ModuleInstaller.new(@outputter, @pal).install(modules, puppetfile, moduledir)
|
119
|
+
@outputter.stop_spin
|
120
|
+
end
|
121
|
+
|
122
|
+
data = { 'name' => project_name }
|
123
|
+
data['modules'] = modules || []
|
124
|
+
|
125
|
+
begin
|
126
|
+
File.write(config.to_path, data.to_yaml)
|
127
|
+
rescue StandardError => e
|
128
|
+
raise Bolt::FileError.new("Could not create bolt-project.yaml at #{project}: #{e.message}", nil)
|
129
|
+
end
|
130
|
+
|
131
|
+
unless inventoryfile.exist?
|
132
|
+
begin
|
133
|
+
File.write(inventoryfile.to_path, INVENTORY_TEMPLATE)
|
134
|
+
rescue StandardError => e
|
135
|
+
raise Bolt::FileError.new("Could not create inventory.yaml at #{project}: #{e.message}", nil)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
unless gitignore.exist?
|
140
|
+
begin
|
141
|
+
File.write(gitignore.to_path, GITIGNORE_CONTENT)
|
142
|
+
rescue StandardError => e
|
143
|
+
raise Bolt::FileError.new("Could not create .gitignore at #{project}: #{e.message}", nil)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
@outputter.print_message("Successfully created Bolt project at #{project}")
|
148
|
+
|
149
|
+
0
|
150
|
+
end
|
151
|
+
|
152
|
+
# Migrates a project to use the latest file versions and best practices.
|
153
|
+
#
|
154
|
+
def migrate
|
155
|
+
unless $stdin.tty?
|
156
|
+
raise Bolt::Error.new(
|
157
|
+
"stdin is not a tty, unable to migrate project",
|
158
|
+
'bolt/stdin-not-a-tty-error'
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
@outputter.print_message("Migrating project #{@config.project.path}\n\n")
|
163
|
+
|
164
|
+
@outputter.print_action_step(
|
165
|
+
"Migrating a Bolt project might make irreversible changes to the project's "\
|
166
|
+
"configuration and inventory files. Before continuing, make sure the "\
|
167
|
+
"project has a backup or uses a version control system."
|
168
|
+
)
|
169
|
+
|
170
|
+
return 0 unless Bolt::Util.prompt_yes_no("Continue with project migration?", @outputter)
|
171
|
+
|
172
|
+
@outputter.print_message('')
|
173
|
+
|
174
|
+
ok = migrate_inventory && migrate_config && migrate_modules
|
175
|
+
|
176
|
+
if ok
|
177
|
+
@outputter.print_message("Project successfully migrated")
|
178
|
+
else
|
179
|
+
@outputter.print_error("Project could not be migrated completely")
|
180
|
+
end
|
181
|
+
|
182
|
+
ok ? 0 : 1
|
183
|
+
end
|
184
|
+
|
185
|
+
# Migrates the project-level configuration file to the latest version.
|
186
|
+
#
|
187
|
+
private def migrate_config
|
188
|
+
migrator = ConfigMigrator.new(@outputter)
|
189
|
+
configfile = @config.project.path + 'bolt.yaml'
|
190
|
+
|
191
|
+
migrator.migrate(
|
192
|
+
configfile,
|
193
|
+
@config.project.project_file,
|
194
|
+
@config.inventoryfile || @config.project.inventory_file,
|
195
|
+
@config.project.backup_dir
|
196
|
+
)
|
197
|
+
end
|
198
|
+
|
199
|
+
# Migrates the inventory file to the latest version.
|
200
|
+
#
|
201
|
+
private def migrate_inventory
|
202
|
+
migrator = InventoryMigrator.new(@outputter)
|
203
|
+
|
204
|
+
migrator.migrate(
|
205
|
+
@config.inventoryfile || @config.project.inventory_file,
|
206
|
+
@config.project.backup_dir
|
207
|
+
)
|
208
|
+
end
|
209
|
+
|
210
|
+
# Migrates the project's modules to use current best practices.
|
211
|
+
#
|
212
|
+
private def migrate_modules
|
213
|
+
migrator = ModuleMigrator.new(@outputter)
|
214
|
+
|
215
|
+
migrator.migrate(
|
216
|
+
@config.project,
|
217
|
+
@config.modulepath[0...-1]
|
218
|
+
)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'logging'
|
5
|
+
require_relative '../../bolt/puppetdb/instance'
|
6
|
+
|
7
|
+
module Bolt
|
8
|
+
module PuppetDB
|
9
|
+
class Client
|
10
|
+
# @param config [Hash] A map of default PuppetDB configuration.
|
11
|
+
# @param instances [Hash] A map of configuration for named PuppetDB instances.
|
12
|
+
# @param default [String] The name of PuppetDB instance to use as the default.
|
13
|
+
# @param project [String] The path to the Bolt project.
|
14
|
+
#
|
15
|
+
def initialize(config:, instances: {}, default: nil, project: nil)
|
16
|
+
@logger = Bolt::Logger.logger(self)
|
17
|
+
|
18
|
+
@instances = instances.transform_values do |instance_config|
|
19
|
+
Bolt::PuppetDB::Instance.new(config: instance_config, project: project)
|
20
|
+
end
|
21
|
+
|
22
|
+
@default_instance = if default
|
23
|
+
validate_instance(default)
|
24
|
+
@instances[default]
|
25
|
+
else
|
26
|
+
Bolt::PuppetDB::Instance.new(config: config, project: project, load_defaults: true)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Checks whether a given named instance is configured, erroring if not.
|
31
|
+
#
|
32
|
+
# @param name [String] The name of the PuppetDB instance.
|
33
|
+
#
|
34
|
+
private def validate_instance(name)
|
35
|
+
unless @instances[name]
|
36
|
+
raise Bolt::PuppetDBError, "PuppetDB instance '#{name}' has not been configured, unable to connect"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Yields the PuppetDB instance to connect to.
|
41
|
+
#
|
42
|
+
# @param name [String] The name of the PuppetDB instance.
|
43
|
+
# @yield [Bolt::PuppetDB::Instance]
|
44
|
+
#
|
45
|
+
private def with_instance(name = nil)
|
46
|
+
yield instance(name)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Selects the PuppetDB instance to connect to. If an instance is not specified,
|
50
|
+
# the default instance is used.
|
51
|
+
#
|
52
|
+
# @param name [String] The name of the PuppetDB instance.
|
53
|
+
# @return [Bolt::PuppetDB::Instance]
|
54
|
+
#
|
55
|
+
def instance(name = nil)
|
56
|
+
if name
|
57
|
+
validate_instance(name)
|
58
|
+
@instances[name]
|
59
|
+
else
|
60
|
+
@default_instance
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Queries certnames from the PuppetDB instance.
|
65
|
+
#
|
66
|
+
# @param query [String] The PDB query.
|
67
|
+
# @param instance [String] The name of the PuppetDB instance.
|
68
|
+
#
|
69
|
+
def query_certnames(query, instance = nil)
|
70
|
+
return [] unless query
|
71
|
+
|
72
|
+
@logger.debug("Querying certnames")
|
73
|
+
results = make_query(query, nil, instance)
|
74
|
+
|
75
|
+
if results&.first && !results.first&.key?('certname')
|
76
|
+
fields = results.first&.keys
|
77
|
+
raise Bolt::PuppetDBError, "Query results did not contain a 'certname' field: got #{fields.join(', ')}"
|
78
|
+
end
|
79
|
+
|
80
|
+
results&.map { |result| result['certname'] }&.uniq
|
81
|
+
end
|
82
|
+
|
83
|
+
# Retrieve facts from PuppetDB for a list of nodes.
|
84
|
+
#
|
85
|
+
# @param certnames [Array] The list of certnames to retrieve facts for.
|
86
|
+
# @param instance [String] The name of the PuppetDB instance.
|
87
|
+
#
|
88
|
+
def facts_for_node(certnames, instance = nil)
|
89
|
+
return {} if certnames.empty? || certnames.nil?
|
90
|
+
|
91
|
+
certnames.uniq!
|
92
|
+
name_query = certnames.map { |c| ["=", "certname", c] }
|
93
|
+
name_query.insert(0, "or")
|
94
|
+
|
95
|
+
@logger.debug("Querying certnames")
|
96
|
+
result = make_query(name_query, 'inventory', instance)
|
97
|
+
|
98
|
+
result&.each_with_object({}) do |node, coll|
|
99
|
+
coll[node['certname']] = node['facts']
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Retrive fact values for a list of nodes.
|
104
|
+
#
|
105
|
+
# @param certnames [Array] The list of certnames to retrieve fact values for.
|
106
|
+
# @param facts [Array] The list of facts to retrive.
|
107
|
+
# @param instance [String] The name of the PuppetDB instance.
|
108
|
+
#
|
109
|
+
def fact_values(certnames = [], facts = [], instance = nil)
|
110
|
+
return {} if certnames.empty? || facts.empty?
|
111
|
+
|
112
|
+
certnames.uniq!
|
113
|
+
name_query = certnames.each_slice(100).map { |slice| ["in", "certname", ["array", slice]] }
|
114
|
+
name_query.unshift("or")
|
115
|
+
|
116
|
+
facts_query = facts.map { |f| ["=", "path", f] }
|
117
|
+
facts_query.unshift("or")
|
118
|
+
|
119
|
+
query = ['and', name_query, facts_query]
|
120
|
+
|
121
|
+
@logger.debug("Querying certnames")
|
122
|
+
result = make_query(query, 'fact-contents', instance)
|
123
|
+
result.map! { |h| h.delete_if { |k, _v| %w[environment name].include?(k) } }
|
124
|
+
result.group_by { |c| c['certname'] }
|
125
|
+
end
|
126
|
+
|
127
|
+
# Sends a command to PuppetDB using the commands API.
|
128
|
+
#
|
129
|
+
# @param command [String] The command to invoke.
|
130
|
+
# @param version [Integer] The version of the command to invoke.
|
131
|
+
# @param payload [Hash] The payload to send with the command.
|
132
|
+
# @param instance [String] The name of the PuppetDB instance.
|
133
|
+
#
|
134
|
+
def send_command(command, version, payload, instance = nil)
|
135
|
+
with_instance(instance) do |pdb|
|
136
|
+
pdb.send_command(command, version, payload)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Sends a query to PuppetDB.
|
141
|
+
#
|
142
|
+
# @param query [String] The query to send to PuppetDB.
|
143
|
+
# @param path [String] The API path to append to the query URL.
|
144
|
+
# @param instance [String] The name of the PuppetDB instance.
|
145
|
+
#
|
146
|
+
def make_query(query, path = nil, instance = nil)
|
147
|
+
with_instance(instance) do |pdb|
|
148
|
+
pdb.make_query(query, path)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|