provisioners/ansible: Validate compatibility_mode
- Use `'auto'` instead of `nil` for the auto-detection mode - Add strict validation and related error message
This commit is contained in:
parent
e2621a42fc
commit
a327e34861
|
@ -46,7 +46,7 @@ module VagrantPlugins
|
|||
def initialize
|
||||
@become = UNSET_VALUE
|
||||
@become_user = UNSET_VALUE
|
||||
@compatibility_mode = UNSET_VALUE
|
||||
@compatibility_mode = Ansible::COMPATIBILITY_MODE_AUTO
|
||||
@config_file = UNSET_VALUE
|
||||
@extra_vars = UNSET_VALUE
|
||||
@galaxy_role_file = UNSET_VALUE
|
||||
|
@ -95,6 +95,12 @@ module VagrantPlugins
|
|||
def validate(machine)
|
||||
@errors = _detected_errors
|
||||
|
||||
# Validate that a compatibility mode was provided
|
||||
if !compatibility_mode
|
||||
@errors << I18n.t("vagrant.provisioners.ansible.errors.no_compatibility_mode",
|
||||
valid_modes: Ansible::COMPATIBILITY_MODES.map { |s| "'#{s}'" }.join(', '))
|
||||
end
|
||||
|
||||
# Validate that a playbook path was provided
|
||||
if !playbook
|
||||
@errors << I18n.t("vagrant.provisioners.ansible.errors.no_playbook")
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
|
||||
module VagrantPlugins
|
||||
module Ansible
|
||||
COMPATIBILITY_MODE_AUTO = "auto".freeze
|
||||
COMPATIBILITY_MODE_V1_8 = "1.8".freeze
|
||||
COMPATIBILITY_MODE_V2_0 = "2.0".freeze
|
||||
DEFAULT_COMPATIBILITY_MODE = COMPATIBILITY_MODE_V1_8
|
||||
COMPATIBILITY_MODES = [COMPATIBILITY_MODE_V1_8, COMPATIBILITY_MODE_V2_0].freeze
|
||||
SAFE_COMPATIBILITY_MODE = COMPATIBILITY_MODE_V1_8
|
||||
COMPATIBILITY_MODES = [
|
||||
COMPATIBILITY_MODE_AUTO,
|
||||
COMPATIBILITY_MODE_V1_8,
|
||||
COMPATIBILITY_MODE_V2_0,
|
||||
].freeze
|
||||
end
|
||||
end
|
|
@ -48,11 +48,11 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
def set_compatibility_mode
|
||||
unless config.compatibility_mode
|
||||
if config.compatibility_mode == Ansible::COMPATIBILITY_MODE_AUTO
|
||||
detect_compatibility_mode(gather_ansible_version)
|
||||
end
|
||||
|
||||
unless Ansible::COMPATIBILITY_MODES.include?(config.compatibility_mode)
|
||||
unless Ansible::COMPATIBILITY_MODES.slice(1..-1).include?(config.compatibility_mode)
|
||||
raise "Programming Error: compatibility_mode must correctly set at this stage!"
|
||||
end
|
||||
|
||||
|
@ -60,7 +60,7 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
def detect_compatibility_mode(ansible_version_stdoutput)
|
||||
if config.compatibility_mode
|
||||
if config.compatibility_mode != Ansible::COMPATIBILITY_MODE_AUTO
|
||||
raise "Programming Error: detect_compatibility_mode() shouldn't have been called."
|
||||
end
|
||||
|
||||
|
@ -86,8 +86,8 @@ module VagrantPlugins
|
|||
# Nothing to do here, the fallback to default compatibility_mode is done below
|
||||
end
|
||||
|
||||
unless config.compatibility_mode
|
||||
config.compatibility_mode = Ansible::DEFAULT_COMPATIBILITY_MODE
|
||||
if config.compatibility_mode == Ansible::COMPATIBILITY_MODE_AUTO
|
||||
config.compatibility_mode = Ansible::SAFE_COMPATIBILITY_MODE
|
||||
|
||||
@machine.env.ui.warn(I18n.t("vagrant.provisioners.ansible.compatibility_mode_not_detected",
|
||||
compatibility_mode: config.compatibility_mode,
|
||||
|
|
|
@ -2374,6 +2374,8 @@ en:
|
|||
`%{config_option}` does not exist on the %{system}: %{path}
|
||||
extra_vars_invalid: |-
|
||||
`extra_vars` must be a hash or a path to an existing file. Received: %{value} (as %{type})
|
||||
no_compatibility_mode: |-
|
||||
`compatibility_mode` must be correctly set (possible values: %{valid_modes}).
|
||||
no_playbook: |-
|
||||
`playbook` file path must be set.
|
||||
raw_arguments_invalid: |-
|
||||
|
|
|
@ -5,7 +5,7 @@ shared_examples_for 'options shared by both Ansible provisioners' do
|
|||
|
||||
expect(subject.become).to be(false)
|
||||
expect(subject.become_user).to be_nil
|
||||
expect(subject.compatibility_mode).to be_nil
|
||||
expect(subject.compatibility_mode).to eql(VagrantPlugins::Ansible::COMPATIBILITY_MODE_AUTO)
|
||||
expect(subject.config_file).to be_nil
|
||||
expect(subject.extra_vars).to be_nil
|
||||
expect(subject.galaxy_command).to eql("ansible-galaxy install --role-file=%{role_file} --roles-path=%{roles_path} --force")
|
||||
|
@ -46,23 +46,37 @@ shared_examples_for 'an Ansible provisioner' do | path_prefix, ansible_setup |
|
|||
|
||||
describe "compatibility_mode option" do
|
||||
|
||||
%w(1.8 2.0).each do |minimal_version|
|
||||
it "supports compatibility mode '#{minimal_version}'" do
|
||||
subject.compatibility_mode = minimal_version
|
||||
VagrantPlugins::Ansible::COMPATIBILITY_MODES.each do |valid_mode|
|
||||
it "supports compatibility mode '#{valid_mode}'" do
|
||||
subject.compatibility_mode = valid_mode
|
||||
subject.finalize!
|
||||
|
||||
result = subject.validate(machine)
|
||||
expect(subject.compatibility_mode).to eql(minimal_version)
|
||||
expect(subject.compatibility_mode).to eql(valid_mode)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns an error if the compatibility mode is not set" do
|
||||
subject.compatibility_mode = nil
|
||||
subject.finalize!
|
||||
|
||||
result = subject.validate(machine)
|
||||
expect(result[provisioner_label]).to eql([
|
||||
I18n.t("vagrant.provisioners.ansible.errors.no_compatibility_mode",
|
||||
valid_modes: "'auto', '1.8', '2.0'")
|
||||
])
|
||||
end
|
||||
|
||||
%w(invalid 1.9 2.3).each do |invalid_mode|
|
||||
it "silently forces the compatibility mode detection for invalid mode '#{invalid_mode}'" do
|
||||
it "returns an error if the compatibility mode is invalid (e.g. '#{invalid_mode}')" do
|
||||
subject.compatibility_mode = invalid_mode
|
||||
subject.finalize!
|
||||
|
||||
result = subject.validate(machine)
|
||||
expect(subject.compatibility_mode).to be_nil
|
||||
expect(result[provisioner_label]).to eql([
|
||||
I18n.t("vagrant.provisioners.ansible.errors.no_compatibility_mode",
|
||||
valid_modes: "'auto', '1.8', '2.0'")
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -109,6 +123,7 @@ shared_examples_for 'an Ansible provisioner' do | path_prefix, ansible_setup |
|
|||
end
|
||||
|
||||
it "it collects and returns all detected errors" do
|
||||
subject.compatibility_mode = nil
|
||||
subject.playbook = nil
|
||||
subject.extra_vars = ["var1", 3, "var2", 5]
|
||||
subject.raw_arguments = { arg1: 1, arg2: "foo" }
|
||||
|
@ -116,7 +131,10 @@ shared_examples_for 'an Ansible provisioner' do | path_prefix, ansible_setup |
|
|||
|
||||
result = subject.validate(machine)
|
||||
|
||||
expect(result[provisioner_label].size).to eql(3)
|
||||
expect(result[provisioner_label].size).to eql(4)
|
||||
expect(result[provisioner_label]).to include(
|
||||
I18n.t("vagrant.provisioners.ansible.errors.no_compatibility_mode",
|
||||
valid_modes: "'auto', '1.8', '2.0'"))
|
||||
expect(result[provisioner_label]).to include(
|
||||
I18n.t("vagrant.provisioners.ansible.errors.no_playbook"))
|
||||
expect(result[provisioner_label]).to include(
|
||||
|
|
|
@ -305,9 +305,9 @@ VF
|
|||
"ask_become_pass" => "--ask-sudo-pass"})
|
||||
end
|
||||
|
||||
context "with no compatibility_mode defined" do
|
||||
context "with compatibility_mode 'auto'" do
|
||||
before do
|
||||
config.compatibility_mode = nil
|
||||
config.compatibility_mode = VagrantPlugins::Ansible::COMPATIBILITY_MODE_AUTO
|
||||
end
|
||||
|
||||
valid_versions = {
|
||||
|
@ -348,16 +348,16 @@ VF
|
|||
allow(subject).to receive(:gather_ansible_version).and_return(unknown_ansible_version)
|
||||
end
|
||||
|
||||
it "applies the default compatibility mode ('#{VagrantPlugins::Ansible::DEFAULT_COMPATIBILITY_MODE}')" do
|
||||
it "applies the safest compatibility mode ('#{VagrantPlugins::Ansible::SAFE_COMPATIBILITY_MODE}')" do
|
||||
expect(Vagrant::Util::Subprocess).to receive(:execute).with('ansible-playbook', any_args) { |*args|
|
||||
expect(config.compatibility_mode).to eq(VagrantPlugins::Ansible::DEFAULT_COMPATIBILITY_MODE)
|
||||
expect(config.compatibility_mode).to eq(VagrantPlugins::Ansible::SAFE_COMPATIBILITY_MODE)
|
||||
}.and_return(default_execute_result)
|
||||
end
|
||||
|
||||
it "warns about not being able to detect the best compatibility mode" do
|
||||
expect(machine.env.ui).to receive(:warn).with(
|
||||
I18n.t("vagrant.provisioners.ansible.compatibility_mode_not_detected",
|
||||
compatibility_mode: VagrantPlugins::Ansible::DEFAULT_COMPATIBILITY_MODE,
|
||||
compatibility_mode: VagrantPlugins::Ansible::SAFE_COMPATIBILITY_MODE,
|
||||
gathered_version: unknown_ansible_version) +
|
||||
"\n")
|
||||
end
|
||||
|
|
|
@ -29,10 +29,11 @@ Some of these options are for advanced usage only and should not be used unless
|
|||
|
||||
Possible values:
|
||||
|
||||
- `"1.8"` (Ansible versions prior to 1.8 should mostly work well, but some options might not be supported)
|
||||
- `"2.0"` (The generated Ansible inventory will be incompatible with Ansible 1.x)
|
||||
- `"auto"` _(Vagrant will automatically select the optimal compatibilty mode by checking the Ansible version currently available)_
|
||||
- `"1.8"` _(Ansible versions prior to 1.8 should mostly work well, but some options might not be supported)_
|
||||
- `"2.0"` _(The generated Ansible inventory will be incompatible with Ansible 1.x)_
|
||||
|
||||
By default this option is not set, and Vagrant will try to automatically set the optimal compatibilty mode by checking the Ansible version currently available. Note that Vagrant doesn't validate this option, and any unsupported value (e.g. "2.3") will also lead Vagrant to auto-detect the compatibility mode.
|
||||
By default this option is set to `"auto"`. If Vagrant is not able to detect any supported Ansible version, it will falls back on the compatibility mode `"1.8"` with a warning.
|
||||
|
||||
<div class="alert alert-info">
|
||||
<strong>Compatibility Note:</strong>
|
||||
|
|
Loading…
Reference in New Issue