vagrant-bolt 0.1.0
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/.gitignore +15 -0
- data/.rspec +2 -0
- data/.rubocop.yml +124 -0
- data/.travis.yml +28 -0
- data/.yardopts +1 -0
- data/Gemfile +37 -0
- data/LICENSE +12 -0
- data/Puppetfile +7 -0
- data/README.md +431 -0
- data/Rakefile +19 -0
- data/Vagrantfile +47 -0
- data/acceptance/artifacts/.keep +0 -0
- data/acceptance/components/bolt_spec.rb +98 -0
- data/acceptance/skeletons/advanced/Vagrantfile +26 -0
- data/acceptance/skeletons/base/Vagrantfile +11 -0
- data/acceptance/skeletons/base/modules/facts/CHANGELOG.md +26 -0
- data/acceptance/skeletons/base/modules/facts/CONTRIBUTING.md +279 -0
- data/acceptance/skeletons/base/modules/facts/Gemfile +98 -0
- data/acceptance/skeletons/base/modules/facts/LICENSE +201 -0
- data/acceptance/skeletons/base/modules/facts/README.md +45 -0
- data/acceptance/skeletons/base/modules/facts/Rakefile +8 -0
- data/acceptance/skeletons/base/modules/facts/checksums.json +42 -0
- data/acceptance/skeletons/base/modules/facts/lib/puppet/functions/facts/group_by.rb +14 -0
- data/acceptance/skeletons/base/modules/facts/metadata.json +62 -0
- data/acceptance/skeletons/base/modules/facts/plans/info.pp +16 -0
- data/acceptance/skeletons/base/modules/facts/plans/init.pp +13 -0
- data/acceptance/skeletons/base/modules/facts/tasks/bash.json +5 -0
- data/acceptance/skeletons/base/modules/facts/tasks/bash.sh +93 -0
- data/acceptance/skeletons/base/modules/facts/tasks/init.json +10 -0
- data/acceptance/skeletons/base/modules/facts/tasks/powershell.json +4 -0
- data/acceptance/skeletons/base/modules/facts/tasks/powershell.ps1 +56 -0
- data/acceptance/skeletons/base/modules/facts/tasks/ruby.json +4 -0
- data/acceptance/skeletons/base/modules/facts/tasks/ruby.rb +40 -0
- data/acceptance/skeletons/provisioner/Vagrantfile +19 -0
- data/acceptance/skeletons/trigger/Vagrantfile +22 -0
- data/acceptance/vagrant-spec.config.rb +22 -0
- data/lib/vagrant-bolt.rb +57 -0
- data/lib/vagrant-bolt/command.rb +65 -0
- data/lib/vagrant-bolt/config.rb +6 -0
- data/lib/vagrant-bolt/config/bolt.rb +135 -0
- data/lib/vagrant-bolt/config/global.rb +172 -0
- data/lib/vagrant-bolt/config_builder.rb +11 -0
- data/lib/vagrant-bolt/config_builder/config.rb +150 -0
- data/lib/vagrant-bolt/config_builder/monkey_patches.rb +71 -0
- data/lib/vagrant-bolt/config_builder/provisioner.rb +106 -0
- data/lib/vagrant-bolt/config_builder/triggers.rb +29 -0
- data/lib/vagrant-bolt/plugin.rb +39 -0
- data/lib/vagrant-bolt/provisioner.rb +18 -0
- data/lib/vagrant-bolt/runner.rb +88 -0
- data/lib/vagrant-bolt/util/bolt.rb +139 -0
- data/lib/vagrant-bolt/util/config.rb +43 -0
- data/lib/vagrant-bolt/util/machine.rb +73 -0
- data/lib/vagrant-bolt/version.rb +5 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/unit/config/bolt_spec.rb +150 -0
- data/spec/unit/config/global_spec.rb +95 -0
- data/spec/unit/provisioner/bolt_spec.rb +39 -0
- data/spec/unit/runner/runner_spec.rb +122 -0
- data/spec/unit/util/bolt_spec.rb +148 -0
- data/spec/unit/util/config_spec.rb +53 -0
- data/spec/unit/vagrant_spec.rb +9 -0
- data/tasks/acceptance.rake +45 -0
- data/tasks/spec.rake +5 -0
- data/templates/locales/en.yml +24 -0
- data/vagrant-bolt.gemspec +24 -0
- metadata +109 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# VM level requires overriding to_proc to allow access to the node config object
|
4
|
+
# @!visibility private
|
5
|
+
module VagrantBolt::ConfigBuilder::MonkeyPatches
|
6
|
+
def to_proc
|
7
|
+
proc do |config|
|
8
|
+
super.call(config)
|
9
|
+
eval_bolt_root(config)
|
10
|
+
eval_bolt_triggers_root(config)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def eval_bolt(config)
|
15
|
+
# noop
|
16
|
+
end
|
17
|
+
|
18
|
+
def eval_bolt_root(vm_root_config)
|
19
|
+
# Configure the vm bolt object if the options exist
|
20
|
+
with_attr(:bolt) do |bolt_config|
|
21
|
+
f = VagrantBolt::ConfigBuilder::Config.new_from_hash(bolt_config)
|
22
|
+
f.call(vm_root_config)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def eval_bolt_triggers(config)
|
27
|
+
# noop
|
28
|
+
end
|
29
|
+
|
30
|
+
def eval_bolt_triggers_root(vm_root_config)
|
31
|
+
# Configure the vm bolt object if the options exist
|
32
|
+
triggers = attr(:bolt_triggers) || [] # rubocop:disable Style/Attr
|
33
|
+
triggers.each do |config|
|
34
|
+
f = VagrantBolt::ConfigBuilder::Triggers.new_from_hash(config)
|
35
|
+
f.call(vm_root_config)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class ConfigBuilder::Model::VM
|
41
|
+
def_model_delegator :bolt
|
42
|
+
def_model_delegator :bolt_triggers
|
43
|
+
end
|
44
|
+
|
45
|
+
ConfigBuilder::Model::VM.prepend(VagrantBolt::ConfigBuilder::MonkeyPatches)
|
46
|
+
|
47
|
+
# Allow for the role filter to handle bolt configs and bolt_triggers
|
48
|
+
# @!visibility private
|
49
|
+
module VagrantBolt::ConfigBuilder::MonkeyPatches::FilterRoles
|
50
|
+
def merge_nodes!(left, right)
|
51
|
+
super.tap do |result|
|
52
|
+
array_keys = ['bolt_triggers']
|
53
|
+
array_keys.each do |key|
|
54
|
+
next unless right.key?(key)
|
55
|
+
|
56
|
+
result[key] ||= []
|
57
|
+
result[key].unshift(*right[key])
|
58
|
+
end
|
59
|
+
|
60
|
+
hash_keys = ['bolt']
|
61
|
+
hash_keys.each do |key|
|
62
|
+
next unless right.key?(key)
|
63
|
+
|
64
|
+
result[key] ||= {}
|
65
|
+
result[key] = right[key].merge(result[key])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
ConfigBuilder::Filter::Roles.prepend(VagrantBolt::ConfigBuilder::MonkeyPatches::FilterRoles)
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'config_builder/model'
|
4
|
+
require_relative 'monkey_patches'
|
5
|
+
|
6
|
+
class VagrantBolt::ConfigBuilder::Provisioner < ConfigBuilder::Model::Provisioner::Base
|
7
|
+
# @!attribute [rw] args
|
8
|
+
# @return [String] Additional arguments for the bolt command
|
9
|
+
def_model_attribute :args
|
10
|
+
|
11
|
+
# @!attribute [rw] bolt_exe
|
12
|
+
# @return [String] The full path to the bolt command. If not passed in, the default from PATH will be used.
|
13
|
+
def_model_attribute :bolt_exe
|
14
|
+
|
15
|
+
# @!attribute [rw] boltdir
|
16
|
+
# @return [String] The bolt working directory. Defaults to `.`
|
17
|
+
def_model_attribute :boltdir
|
18
|
+
|
19
|
+
# @!attribute [rw] debug
|
20
|
+
# @return [Boolean] Shows debug logging
|
21
|
+
def_model_attribute :debug
|
22
|
+
|
23
|
+
# @!attribute [rw] host_key_check
|
24
|
+
# @return [Boolean] If the connection should check the host key on the remote host (linux)
|
25
|
+
def_model_attribute :host_key_check
|
26
|
+
|
27
|
+
# @!attribute [rw] modulepath
|
28
|
+
# @return [String] The path to the modules. Defaults to `modules`.
|
29
|
+
def_model_attribute :modulepath
|
30
|
+
|
31
|
+
# @!attribute [rw] name
|
32
|
+
# @return [String] The name of task or plan to run
|
33
|
+
def_model_attribute :name
|
34
|
+
|
35
|
+
# @!attribute [rw] nodes
|
36
|
+
# Note: The `node_list` will override this setting.
|
37
|
+
# @return [Array<String, Symbol>, "ALL"] The nodes to run the task or plan on.
|
38
|
+
# Valid values are an array of machine names or the string "ALL".
|
39
|
+
def_model_attribute :nodes
|
40
|
+
|
41
|
+
# @!attribute [rw] noop
|
42
|
+
# @return [Boolean] If the command should be run with noop. Only valid with tasks and apply.
|
43
|
+
def_model_attribute :noop
|
44
|
+
|
45
|
+
# @!attribute [rw] excludes
|
46
|
+
# Note: The `node_list` will override this setting.
|
47
|
+
# Note: This will be merged with `nodes`, with `excludes` taking precidence.
|
48
|
+
# @return [Array<String, Symbol>] The nodes to exclude from running this task or plan on.
|
49
|
+
# Valid values are an array of machine names.
|
50
|
+
def_model_attribute :excludes
|
51
|
+
|
52
|
+
# @!attribute [rw] node_list
|
53
|
+
# This setting overrides `nodes` and needs to be in the `protocol://ipaddress:port` URI format
|
54
|
+
# @return [String] The bolt node list. This defaults to the currnet node.
|
55
|
+
def_model_attribute :node_list
|
56
|
+
|
57
|
+
# @!attribute [rw] params
|
58
|
+
# @return [Hash] The paramater hash for the task or plan
|
59
|
+
def_model_attribute :params
|
60
|
+
|
61
|
+
# @!attribute [rw] command
|
62
|
+
# @return [Symbol] Whether bolt should use a task or plan
|
63
|
+
def_model_attribute :command
|
64
|
+
|
65
|
+
# @!attribute [rw] user
|
66
|
+
# @return [String] The user to authenticate on the machine.
|
67
|
+
def_model_attribute :user
|
68
|
+
|
69
|
+
# @!attribute [rw] password
|
70
|
+
# @return [String] The password to authenticate on the machine.
|
71
|
+
def_model_attribute :password
|
72
|
+
|
73
|
+
# @!attribute [rw] port
|
74
|
+
# @return [String] The port to connect to the machine.
|
75
|
+
def_model_attribute :port
|
76
|
+
|
77
|
+
# @!attribute [rw] private_key
|
78
|
+
# @return [String] The path of the private_key to authenticate on the machine.
|
79
|
+
def_model_attribute :private_key
|
80
|
+
|
81
|
+
# @!attribute [rw] run_as
|
82
|
+
# @return [String] User to run as using privilege escalation.
|
83
|
+
def_model_attribute :run_as
|
84
|
+
|
85
|
+
# @!attribute [rw] sudo_password
|
86
|
+
# @return [String] The password to authenticate sudo on the machine.
|
87
|
+
def_model_attribute :sudo_password
|
88
|
+
|
89
|
+
# @!attribute [rw] ssl
|
90
|
+
# @return [Boolean] If the connection should use SSL on with WinRM (Windows)
|
91
|
+
def_model_attribute :ssl
|
92
|
+
|
93
|
+
# @!attribute [rw] ssl_verify
|
94
|
+
# @return [Boolean] If the connection should verify SSL on with WinRM (Windows)
|
95
|
+
def_model_attribute :ssl_verify
|
96
|
+
|
97
|
+
# @!attribute [rw] tmpdir
|
98
|
+
# @return [String] The directory to upload and execute temporary files on the target
|
99
|
+
def_model_attribute :tmpdir
|
100
|
+
|
101
|
+
# @!attribute [rw] verbose
|
102
|
+
# @return [Boolean] Shows verbose logging
|
103
|
+
def_model_attribute :verbose
|
104
|
+
|
105
|
+
ConfigBuilder::Model::Provisioner.register('bolt', self)
|
106
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'config_builder/model'
|
4
|
+
require_relative 'monkey_patches'
|
5
|
+
|
6
|
+
class VagrantBolt::ConfigBuilder::Triggers < VagrantBolt::ConfigBuilder::Config
|
7
|
+
# @!attribute [rw] trigger_type
|
8
|
+
# @return [Symbol] A symbol containing the the trigger action. Valid values are `:before` and `:after`
|
9
|
+
def_model_attribute :trigger_type
|
10
|
+
|
11
|
+
# @!attribute [rw] trigger_commands
|
12
|
+
# @return [Array<Symbol>] The commands that the trigger should run on. E.g. `[:up, :provision]`
|
13
|
+
def_model_attribute :trigger_commands
|
14
|
+
|
15
|
+
def to_proc
|
16
|
+
options = @attrs.dup
|
17
|
+
trigger_type = options.delete(:trigger_type)
|
18
|
+
trigger_commands = options.delete(:trigger_commands)
|
19
|
+
command = options.delete(:command)
|
20
|
+
name = options.delete(:name)
|
21
|
+
proc do |config|
|
22
|
+
config.trigger.send(trigger_type, trigger_commands) do |trigger|
|
23
|
+
trigger.ruby do |env, machine|
|
24
|
+
VagrantBolt.send(command, name, env, machine, **options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vagrant'
|
4
|
+
require_relative 'version'
|
5
|
+
|
6
|
+
raise "vagrant-bolt version #{VagrantBolt::VERSION} requires Vagrant 2.2 or later" if Vagrant::VERSION < "2.2.0"
|
7
|
+
|
8
|
+
class VagrantBolt::Plugin < Vagrant.plugin('2')
|
9
|
+
name 'bolt'
|
10
|
+
|
11
|
+
description <<-DESC
|
12
|
+
Vagrant provisioning with Puppet Bolt
|
13
|
+
DESC
|
14
|
+
|
15
|
+
config(:bolt) do
|
16
|
+
require_relative 'config'
|
17
|
+
VagrantBolt::Config::Global
|
18
|
+
end
|
19
|
+
|
20
|
+
config(:bolt, :provisioner) do
|
21
|
+
require_relative 'config'
|
22
|
+
VagrantBolt::Config::Bolt
|
23
|
+
end
|
24
|
+
|
25
|
+
provisioner(:bolt) do
|
26
|
+
require_relative 'provisioner'
|
27
|
+
VagrantBolt::Provisioner
|
28
|
+
end
|
29
|
+
|
30
|
+
command(:bolt) do
|
31
|
+
require_relative 'command'
|
32
|
+
VagrantBolt::Command
|
33
|
+
end
|
34
|
+
|
35
|
+
# Enables config builder loading of this plugin
|
36
|
+
def self.config_builder_hook
|
37
|
+
require_relative 'config_builder'
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vagrant'
|
4
|
+
require 'vagrant/errors'
|
5
|
+
|
6
|
+
class VagrantBolt::Provisioner < Vagrant.plugin('2', :provisioner)
|
7
|
+
# Provision VMs with Bolt
|
8
|
+
# Creates a trigger for each bolt provisioner
|
9
|
+
|
10
|
+
def provision
|
11
|
+
runner = VagrantBolt::Runner.new(@machine.env, @machine, @config)
|
12
|
+
runner.run(@config.command, @config.name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def cleanup
|
16
|
+
# We don't do any clean up for this provisioner
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'util/bolt'
|
4
|
+
require_relative 'util/config'
|
5
|
+
require_relative 'util/machine'
|
6
|
+
|
7
|
+
class VagrantBolt::Runner
|
8
|
+
def initialize(env, machine, boltconfig = nil)
|
9
|
+
@env = env
|
10
|
+
@machine = machine
|
11
|
+
@boltconfig = boltconfig.nil? ? VagrantBolt::Config::Bolt.new : boltconfig
|
12
|
+
@inventory_path = VagrantBolt::Util::Bolt.inventory_file(@env)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Run a bolt task or plan
|
16
|
+
# @param [Symbol, String] command The command of bolt to run; task or plan
|
17
|
+
# @param [String] name The name of the bolt task or plan to run
|
18
|
+
# @param [Hash] args A optional hash of bolt config overrides. No merging will be done with the overrides
|
19
|
+
# @example run('task', 'facts', {node_list: "machinename"})
|
20
|
+
def run(command, name, **args)
|
21
|
+
@boltconfig = setup_overrides(command, name, **args)
|
22
|
+
# Don't run anything if there are nodes to run it on
|
23
|
+
# TODO: Gate this in a more efficient manner. It is possible to run plans without a node list.
|
24
|
+
return if @boltconfig.node_list.nil?
|
25
|
+
|
26
|
+
@inventory_path = VagrantBolt::Util::Bolt.update_inventory_file(@env)
|
27
|
+
validate
|
28
|
+
command = VagrantBolt::Util::Bolt.generate_bolt_command(@boltconfig, @inventory_path)
|
29
|
+
VagrantBolt::Util::Machine.run_command(command, @machine.ui)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Set up config overrides
|
35
|
+
# @param [Symbol, String] command The command of bolt to run; task or plan
|
36
|
+
# @param [String] name The name of the bolt task or plan to run
|
37
|
+
# @param [Hash] args A optional hash of bolt config overrides; {run_as: "vagrant"}
|
38
|
+
# @return [Object] Bolt config with ssh info populated
|
39
|
+
def setup_overrides(command, name, **args)
|
40
|
+
config = @boltconfig.dup
|
41
|
+
config.command = command
|
42
|
+
config.name = name
|
43
|
+
# Merge the root config to get the defaults for the environment
|
44
|
+
config = VagrantBolt::Util::Config.merge_config(config, @env.vagrantfile.config.bolt)
|
45
|
+
# Add any additional arguments to the config object
|
46
|
+
config.set_options(args) unless args.nil?
|
47
|
+
# Configure the node_list based on the config
|
48
|
+
config.node_list ||= [config.nodes - config.excludes].flatten.join(',') unless config.nodes.empty? || config.nodes.to_s.casecmp("all").zero?
|
49
|
+
config.node_list ||= [VagrantBolt::Util::Machine.nodes_in_environment(@env).map(&:name) - config.excludes].flatten.join(',') if config.nodes.to_s.casecmp("all").zero?
|
50
|
+
config.node_list ||= @machine.name.to_s unless config.excludes.include?(@machine.name.to_s)
|
51
|
+
|
52
|
+
# Ensure these are absolute paths to allow for running vagrant commands outside of the root dir
|
53
|
+
config.modulepath = VagrantBolt::Util::Config.full_path(config.modulepath, @env.root_path)
|
54
|
+
config.boltdir = VagrantBolt::Util::Config.full_path(config.boltdir, @env.root_path)
|
55
|
+
|
56
|
+
config
|
57
|
+
end
|
58
|
+
|
59
|
+
# Validate the config object for configuration issues
|
60
|
+
# Print and raise an exception if errors exist
|
61
|
+
def validate
|
62
|
+
errors = {}
|
63
|
+
errors.merge!(@boltconfig.validate(@machine))
|
64
|
+
errors.merge!(validate_config)
|
65
|
+
|
66
|
+
errors.keys.each do |key|
|
67
|
+
errors.delete(key) if errors[key].empty?
|
68
|
+
end
|
69
|
+
|
70
|
+
# rubocop:disable Style/GuardClause
|
71
|
+
if errors && !errors.empty?
|
72
|
+
raise Vagrant::Errors::ConfigInvalid,
|
73
|
+
errors: Vagrant::Util::TemplateRenderer.render(
|
74
|
+
"config/validation_failed",
|
75
|
+
errors: errors,
|
76
|
+
)
|
77
|
+
end
|
78
|
+
# rubocop:enable Style/GuardClause
|
79
|
+
end
|
80
|
+
|
81
|
+
# Validate a bolt config object for logical errors
|
82
|
+
def validate_config
|
83
|
+
errors = []
|
84
|
+
errors << I18n.t('vagrant-bolt.config.bolt.errors.command_not_specified') if @boltconfig.command.nil?
|
85
|
+
errors << I18n.t('vagrant-bolt.config.bolt.errors.no_task_or_plan') if @boltconfig.name.nil?
|
86
|
+
{ "Bolt" => errors }
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'machine'
|
4
|
+
|
5
|
+
module VagrantBolt::Util
|
6
|
+
module Bolt
|
7
|
+
# Bolt Centric Utility Functions
|
8
|
+
|
9
|
+
# Create a bolt command from the config
|
10
|
+
# @param config [Object] The config objects
|
11
|
+
# @param inventory_path [String] The path of the inventory file
|
12
|
+
# @return [String] The bolt command
|
13
|
+
def self.generate_bolt_command(config, inventory_path = nil)
|
14
|
+
command = []
|
15
|
+
command << config.bolt_exe
|
16
|
+
command << "#{config.command} run \'#{config.name}\'"
|
17
|
+
|
18
|
+
config.instance_variables_hash.each do |key, value|
|
19
|
+
next if key.to_s.start_with?('__')
|
20
|
+
next if config.blacklist.include?(key)
|
21
|
+
next if value.nil?
|
22
|
+
|
23
|
+
key = key.tr('_', '-')
|
24
|
+
case value
|
25
|
+
when TrueClass, FalseClass
|
26
|
+
# Verbose and debug do not have --no flags so exclude them
|
27
|
+
next if ['verbose', 'debug', 'noop'].include?(key) && !value
|
28
|
+
|
29
|
+
arg = value ? "--#{key}" : "--no-#{key}"
|
30
|
+
command << arg
|
31
|
+
when String
|
32
|
+
command << "--#{key} \'#{value}\'"
|
33
|
+
when Hash
|
34
|
+
command << "--#{key} \'#{value.to_json}\'" unless value.empty?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
command << "--inventoryfile \'#{inventory_path}\'" unless inventory_path.nil?
|
39
|
+
command << "--nodes \'#{config.node_list}\'" unless config.node_list.nil?
|
40
|
+
command << config.args unless config.args.nil?
|
41
|
+
command.flatten.join(" ")
|
42
|
+
end
|
43
|
+
|
44
|
+
# Generate a bolt inventory hash for the environment
|
45
|
+
# @param env [Object] The env object
|
46
|
+
# @return [Hash] The hash of config options for the inventory.yaml
|
47
|
+
def self.generate_inventory_hash(env)
|
48
|
+
inventory = { 'nodes' => [] }
|
49
|
+
inventory.merge!(env.vagrantfile.config.bolt.inventory_config.compact)
|
50
|
+
VagrantBolt::Util::Machine.nodes_in_environment(env).each do |vm|
|
51
|
+
next unless VagrantBolt::Util::Machine.running?(vm)
|
52
|
+
|
53
|
+
inventory['nodes'] << generate_node_hash(vm)
|
54
|
+
end
|
55
|
+
inventory.compact
|
56
|
+
end
|
57
|
+
|
58
|
+
# Generate a bolt inventory node hash from the VM config
|
59
|
+
# @param machine [Object] The machine object
|
60
|
+
# @return [Hash] The hash of config options for the VM
|
61
|
+
def self.generate_node_hash(machine)
|
62
|
+
# Only call ssh_info once
|
63
|
+
node_hash = {}
|
64
|
+
ssh_info = machine.ssh_info
|
65
|
+
return node_hash if ssh_info.nil?
|
66
|
+
|
67
|
+
node_hash['alias'] = machine.name.to_s
|
68
|
+
machine_config = machine.config.bolt.inventory_config
|
69
|
+
node_hash['config'] = {}
|
70
|
+
transport = VagrantBolt::Util::Machine.windows?(machine) ? 'winrm' : 'ssh'
|
71
|
+
node_hash['config'][transport] = machine_transport_hash(machine, machine_config, ssh_info).compact
|
72
|
+
node_hash['config']['transport'] = transport
|
73
|
+
node_hash['name'] = "#{transport}://#{ssh_info[:host]}:#{node_hash['config'][transport]['port']}"
|
74
|
+
machine_config.each do |key, value|
|
75
|
+
next if key == 'config' || value.nil? || value.empty?
|
76
|
+
|
77
|
+
node_hash[key] = value
|
78
|
+
end
|
79
|
+
node_hash.compact
|
80
|
+
end
|
81
|
+
|
82
|
+
# Return a transport config hash for a node
|
83
|
+
# @param machine [Object] The machine
|
84
|
+
# @param machine_config [Hash] A hash of the machine config options
|
85
|
+
# @param ssh_info [Hash] The ssh hash for the machine
|
86
|
+
def self.machine_transport_hash(machine, machine_config = {}, ssh_info = nil)
|
87
|
+
config = {}
|
88
|
+
if VagrantBolt::Util::Machine.windows?(machine)
|
89
|
+
transport = 'winrm'
|
90
|
+
config['ssl'] = (machine.config.winrm.transport == :ssl)
|
91
|
+
config['ssl_verify'] = machine.config.winrm.ssl_peer_verification
|
92
|
+
config['port'] = machine.config.winrm.port
|
93
|
+
config['user'] = machine.config.winrm.username
|
94
|
+
config['password'] = machine.config.winrm.password
|
95
|
+
else
|
96
|
+
transport = 'ssh'
|
97
|
+
config['private-key'] = ssh_info[:private_key_path][0] unless ssh_info[:private_key_path].nil?
|
98
|
+
config['host-key-check'] = (ssh_info[:verify_host_key] == true)
|
99
|
+
config['port'] = ssh_info[:port]
|
100
|
+
config['user'] = ssh_info[:username]
|
101
|
+
config['password'] = ssh_info[:password]
|
102
|
+
end
|
103
|
+
config.merge!(machine_config['config'][transport]) if machine_config.dig('config', transport)
|
104
|
+
config
|
105
|
+
end
|
106
|
+
|
107
|
+
# Return the path to the inventory file
|
108
|
+
# @param env [Object] The environment
|
109
|
+
# @return [String] The path to the inventory file
|
110
|
+
def self.inventory_file(env)
|
111
|
+
File.join(env.local_data_path, 'bolt_inventory.yaml')
|
112
|
+
end
|
113
|
+
|
114
|
+
# Update and write the inventory file for the current running machines
|
115
|
+
# @param env [Object] The envionment object
|
116
|
+
# @param inventory_file [String] The path where the inventory_file should be written.
|
117
|
+
# @return path to the inventory file
|
118
|
+
def self.update_inventory_file(env, inventory_file = nil)
|
119
|
+
inventory = generate_inventory_hash(env).to_yaml
|
120
|
+
inventory_file ||= Pathname.new(inventory_file(env))
|
121
|
+
# TODO: This lock should be global
|
122
|
+
lock = Mutex.new
|
123
|
+
lock.synchronize do
|
124
|
+
if !File.exist?(inventory_file) || (inventory != File.read(inventory_file))
|
125
|
+
begin
|
126
|
+
inventory_tmpfile = Tempfile.new('.vagrant_bolt_inventory', env.local_data_path)
|
127
|
+
inventory_tmpfile.write(inventory)
|
128
|
+
inventory_tmpfile.close
|
129
|
+
File.rename(inventory_tmpfile.path, inventory_file)
|
130
|
+
ensure
|
131
|
+
inventory_tmpfile.close
|
132
|
+
inventory_tmpfile.unlink
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
inventory_file
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|