provisioners/ansible: add `IdentitiesOnly=yes`
This SSH option is always set, except when Vagrant is running from an
operating system fo the Solaris-family, as this parameter is not
supported by SunSSH. Logic taken from
bed1f8335f/lib/vagrant/util/ssh.rb (L116-L121)
Fix #5017
This commit is contained in:
parent
49d1a92bf6
commit
c3cae3d235
|
@ -5,6 +5,7 @@ BUG FIXES:
|
|||
- core: push configurations are validated with global configs [GH-5130]
|
||||
- guests/funtoo: fix incorrect path in configure networks [GH-4812]
|
||||
- plugins/login: allow users to login with a token [GH-5145]
|
||||
- provisioners/ansible: fix SSH settings to support more than 5 ssh keys [GH-5017]
|
||||
|
||||
## 1.7.2 (January 6, 2015)
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require "vagrant/util/platform"
|
||||
|
||||
module VagrantPlugins
|
||||
module Ansible
|
||||
class Provisioner < Vagrant.plugin("2", :provisioner)
|
||||
|
@ -209,6 +211,12 @@ module VagrantPlugins
|
|||
# Don't access user's known_hosts file, except when host_key_checking is enabled.
|
||||
ssh_options << "-o UserKnownHostsFile=/dev/null" unless config.host_key_checking
|
||||
|
||||
# Set IdentitiesOnly=yes to avoid authentication errors when the host has more than 5 ssh keys.
|
||||
# Notes:
|
||||
# - Solaris/OpenSolaris/Illumos uses SunSSH which doesn't support the IdentitiesOnly option.
|
||||
# - this could be improved by sharing logic with lib/vagrant/util/ssh.rb
|
||||
ssh_options << "-o IdentitiesOnly=yes" unless Vagrant::Util::Platform.solaris?
|
||||
|
||||
# Multiple Private Keys
|
||||
@ssh_info[:private_key_path].drop(1).each do |key|
|
||||
ssh_options << "-o IdentityFile=#{key}"
|
||||
|
|
|
@ -50,6 +50,7 @@ VF
|
|||
let(:generated_inventory_file) { File.join(generated_inventory_dir, 'vagrant_ansible_inventory') }
|
||||
|
||||
before do
|
||||
Vagrant::Util::Platform.stub(solaris?: false)
|
||||
subject.instance_variable_get(:@logger).stub(:debug?).and_return(false)
|
||||
|
||||
machine.stub(ssh_info: ssh_info)
|
||||
|
@ -103,10 +104,11 @@ VF
|
|||
cmd_opts = args.last
|
||||
|
||||
if expected_host_key_checking
|
||||
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to be_nil unless config.raw_arguments
|
||||
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to_not include("-o UserKnownHostsFile=/dev/null")
|
||||
else
|
||||
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o UserKnownHostsFile=/dev/null")
|
||||
end
|
||||
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o IdentitiesOnly=yes")
|
||||
expect(cmd_opts[:env]['ANSIBLE_FORCE_COLOR']).to eql("true")
|
||||
expect(cmd_opts[:env]['ANSIBLE_HOST_KEY_CHECKING']).to eql(expected_host_key_checking.to_s)
|
||||
expect(cmd_opts[:env]['PYTHONUNBUFFERED']).to eql(1)
|
||||
|
@ -270,7 +272,7 @@ VF
|
|||
config.host_key_checking = true
|
||||
end
|
||||
|
||||
it_should_set_arguments_and_environment_variables 6, 3, true
|
||||
it_should_set_arguments_and_environment_variables 6, 4, true
|
||||
end
|
||||
|
||||
describe "with boolean (flag) options disabled" do
|
||||
|
@ -465,7 +467,7 @@ VF
|
|||
|
||||
it "shows the ansible-playbook command" do
|
||||
expect(machine.env.ui).to receive(:detail).with { |full_command|
|
||||
expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --limit='machine1' --inventory-file=#{generated_inventory_dir} playbook.yml")
|
||||
expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --limit='machine1' --inventory-file=#{generated_inventory_dir} playbook.yml")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -480,7 +482,7 @@ VF
|
|||
|
||||
it "shows the ansible-playbook command" do
|
||||
expect(machine.env.ui).to receive(:detail).with { |full_command|
|
||||
expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --limit='machine1' --inventory-file=#{generated_inventory_dir} -v playbook.yml")
|
||||
expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --limit='machine1' --inventory-file=#{generated_inventory_dir} -v playbook.yml")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -538,10 +540,52 @@ VF
|
|||
|
||||
it "shows the ansible-playbook command, with additional quotes when required" do
|
||||
expect(machine.env.ui).to receive(:detail).with { |full_command|
|
||||
expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=true ANSIBLE_SSH_ARGS='-o IdentityFile=/my/key2 -o ForwardAgent=yes -o ControlMaster=no -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/my/key1 --user=testuser --connection=ssh --limit='machine*:&vagrant:!that_one' --inventory-file=#{generated_inventory_dir} --extra-vars=@#{File.expand_path(__FILE__)} --sudo --sudo-user=deployer -vvv --ask-sudo-pass --ask-vault-pass --vault-password-file=#{File.expand_path(__FILE__)} --tags=db,www --skip-tags=foo,bar --start-at-task='an awesome task' --why-not --su-user=foot --ask-su-pass --limit='all' playbook.yml")
|
||||
expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=true ANSIBLE_SSH_ARGS='-o IdentitiesOnly=yes -o IdentityFile=/my/key2 -o ForwardAgent=yes -o ControlMaster=no -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/my/key1 --user=testuser --connection=ssh --limit='machine*:&vagrant:!that_one' --inventory-file=#{generated_inventory_dir} --extra-vars=@#{File.expand_path(__FILE__)} --sudo --sudo-user=deployer -vvv --ask-sudo-pass --ask-vault-pass --vault-password-file=#{File.expand_path(__FILE__)} --tags=db,www --skip-tags=foo,bar --start-at-task='an awesome task' --why-not --su-user=foot --ask-su-pass --limit='all' playbook.yml")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Special cases related to the Vagrant Host operating system in use
|
||||
#
|
||||
|
||||
context "with a Solaris-like host" do
|
||||
before do
|
||||
Vagrant::Util::Platform.stub(solaris?: true)
|
||||
end
|
||||
|
||||
it "does not set IdentitiesOnly=yes in ANSIBLE_SSH_ARGS" do
|
||||
expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args|
|
||||
cmd_opts = args.last
|
||||
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to_not include("-o IdentitiesOnly=yes")
|
||||
|
||||
# Note:
|
||||
# The expectation below is a workaround to a possible misuse (or bug) in RSpec/Ruby stack.
|
||||
# If 'args' variable is not required by in this block, the "Vagrant::Util::Subprocess).to receive"
|
||||
# surprisingly expects to receive "no args".
|
||||
# This problem can be "solved" by using args the "unnecessary" (but harmless) expectation below:
|
||||
expect(true).to be_true
|
||||
}
|
||||
end
|
||||
|
||||
describe "and with host_key_checking option enabled" do
|
||||
it "does not set ANSIBLE_SSH_ARGS environment variable" do
|
||||
config.host_key_checking = true
|
||||
|
||||
expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args|
|
||||
cmd_opts = args.last
|
||||
expect(cmd_opts[:env]).to_not include('ANSIBLE_SSH_ARGS')
|
||||
|
||||
# Note:
|
||||
# The expectation below is a workaround to a possible misuse (or bug) in RSpec/Ruby stack.
|
||||
# If 'args' variable is not required by in this block, the "Vagrant::Util::Subprocess).to receive"
|
||||
# surprisingly expects to receive "no args".
|
||||
# This problem can be "solved" by using args the "unnecessary" (but harmless) expectation below:
|
||||
expect(true).to be_true
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue