From ee5537973664bae95908259d3af9f6db7df94f32 Mon Sep 17 00:00:00 2001 From: Gilles Cornu Date: Wed, 18 Nov 2015 23:34:55 +0100 Subject: [PATCH 1/5] provisioner/ansible: support winrm connection mode This is a first cut to resolve #5086. --- .../provisioners/ansible/provisioner/host.rb | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/plugins/provisioners/ansible/provisioner/host.rb b/plugins/provisioners/ansible/provisioner/host.rb index 23d59f7d2..54928bdfc 100644 --- a/plugins/provisioners/ansible/provisioner/host.rb +++ b/plugins/provisioners/ansible/provisioner/host.rb @@ -147,20 +147,23 @@ module VagrantPlugins @machine.env.active_machines.each do |am| begin m = @machine.env.machine(*am) + + # Call only once the SSH and WinRM info computation + # Note that machines configured with WinRM communicator, also have a "partial" ssh_info. m_ssh_info = m.ssh_info - if !m_ssh_info.nil? - forced_ssh_user = "" - if config.force_remote_user - forced_ssh_user = "ansible_ssh_user='#{m_ssh_info[:username]}' " - end - machines += "#{m.name} ansible_ssh_host=#{m_ssh_info[:host]} ansible_ssh_port=#{m_ssh_info[:port]} #{forced_ssh_user}ansible_ssh_private_key_file='#{m_ssh_info[:private_key_path][0]}'\n" + if m.config.vm.communicator == :winrm + m_winrm_net_info = CommunicatorWinRM::Helper.winrm_info(m) # can raise a WinRMNotReady exception... + machines += get_inventory_winrm_machine(m, m_winrm_net_info) + @inventory_machines[m.name] = m + elsif !m_ssh_info.nil? + machines += get_inventory_ssh_machine(m, m_ssh_info) @inventory_machines[m.name] = m else @logger.error("Auto-generated inventory: Impossible to get SSH information for machine '#{m.name} (#{m.provider_name})'. This machine should be recreated.") # Let a note about this missing machine machines += "# MISSING: '#{m.name}' machine was probably removed without using Vagrant. This machine should be recreated.\n" end - rescue Vagrant::Errors::MachineNotFound => e + rescue Vagrant::Errors::MachineNotFound, CommunicatorWinRM::Errors::WinRMNotReady => e @logger.info("Auto-generated inventory: Skip machine '#{am[0]} (#{am[1]})', which is not configured for this Vagrant environment.") end end @@ -168,6 +171,24 @@ module VagrantPlugins return machines end + def get_inventory_ssh_machine(machine, ssh_info) + forced_remote_user = "" + if config.force_remote_user + forced_remote_user = "ansible_ssh_user='#{ssh_info[:username]}' " + end + + "#{machine.name} ansible_ssh_host=#{ssh_info[:host]} ansible_ssh_port=#{ssh_info[:port]} #{forced_remote_user}ansible_ssh_private_key_file='#{ssh_info[:private_key_path][0]}'\n" + end + + def get_inventory_winrm_machine(machine, winrm_net_info) + forced_remote_user = "" + if config.force_remote_user + forced_remote_user = "ansible_ssh_user='#{machine.config.winrm.username}' " + end + + "#{machine.name} ansible_connection=winrm ansible_ssh_host=#{winrm_net_info[:host]} ansible_ssh_port=#{winrm_net_info[:port]} #{forced_remote_user}ansible_ssh_pass='#{machine.config.winrm.password}'\n" + end + def ansible_ssh_args @ansible_ssh_args ||= prepare_ansible_ssh_args end From e2f0d2ebb7e6d94679fe8a2b0a736edb52a7295f Mon Sep 17 00:00:00 2001 From: Gilles Cornu Date: Sun, 22 Nov 2015 20:48:21 +0100 Subject: [PATCH 2/5] provisioners/ansible: add a unit test for winrm ref #5086 --- .../provisioners/ansible/provisioner_test.rb | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/test/unit/plugins/provisioners/ansible/provisioner_test.rb b/test/unit/plugins/provisioners/ansible/provisioner_test.rb index 94626389a..d937dacff 100644 --- a/test/unit/plugins/provisioners/ansible/provisioner_test.rb +++ b/test/unit/plugins/provisioners/ansible/provisioner_test.rb @@ -129,7 +129,7 @@ VF } end - it "enables '#{expected_transport_mode}' transport mode" do + it "enables '#{expected_transport_mode}' as default transport mode" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| index = args.rindex("--connection=#{expected_transport_mode}") expect(index).to be > 0 @@ -373,6 +373,41 @@ VF end end + context "with winrm communicator" do + + let(:iso_winrm_env) do + env = isolated_environment + env.vagrantfile <<-VF +Vagrant.configure("2") do |config| + config.winrm.username = 'winner' + config.winrm.password = 'winword' + config.winrm.transport = :ssl + + config.vm.define :machine1 do |machine| + machine.vm.box = "winbox" + machine.vm.communicator = :winrm + end +end +VF + env.create_vagrant_env + end + + let(:machine) { iso_winrm_env.machine(iso_winrm_env.machine_names[0], :dummy) } + + it_should_set_arguments_and_environment_variables + + it "generates an inventory with winrm connection settings" do + + expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| + expect(config.inventory_path).to be_nil + expect(File.exists?(generated_inventory_file)).to be_true + inventory_content = File.read(generated_inventory_file) + + expect(inventory_content).to include("machine1 ansible_connection=winrm ansible_ssh_host=127.0.0.1 ansible_ssh_port=55986 ansible_ssh_user='winner' ansible_ssh_pass='winword'\n") + } + end + end + describe "with inventory_path option" do before do config.inventory_path = existing_file From de96b54272f0d7eb717df0f5d7d2c065cd8b1786 Mon Sep 17 00:00:00 2001 From: Gilles Cornu Date: Mon, 23 Nov 2015 09:05:36 +0100 Subject: [PATCH 3/5] provisioners/ansible: full test coverage of winrm At the moment, the vagrant ssh username is used as default username when force_remote_user option is disabled, even for winrm-communiating machines. This could be improved in the future, but people hitting this problem can easily work around it by syncing `config.ssh.unsername` and `config.winrm.username` in their Vagrantfile. ref #5086 --- .../provisioners/ansible/provisioner_test.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/unit/plugins/provisioners/ansible/provisioner_test.rb b/test/unit/plugins/provisioners/ansible/provisioner_test.rb index d937dacff..08e01dc9d 100644 --- a/test/unit/plugins/provisioners/ansible/provisioner_test.rb +++ b/test/unit/plugins/provisioners/ansible/provisioner_test.rb @@ -406,6 +406,21 @@ VF expect(inventory_content).to include("machine1 ansible_connection=winrm ansible_ssh_host=127.0.0.1 ansible_ssh_port=55986 ansible_ssh_user='winner' ansible_ssh_pass='winword'\n") } end + + describe "with force_remote_user option disabled" do + before do + config.force_remote_user = false + end + + it "doesn't set ansiber user in inventory and use '--user' arguemnt with the vagrant ssh username" do + expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| + inventory_content = File.read(generated_inventory_file) + + expect(inventory_content).to include("machine1 ansible_connection=winrm ansible_ssh_host=127.0.0.1 ansible_ssh_port=55986 ansible_ssh_pass='winword'\n") + expect(args).to include("--user=testuser") + } + end + end end describe "with inventory_path option" do From ef6609847234d7475f93555239ff550ad55757a6 Mon Sep 17 00:00:00 2001 From: Gilles Cornu Date: Mon, 23 Nov 2015 09:10:28 +0100 Subject: [PATCH 4/5] provisioners/ansible: fix a typo in rspec example [ci skip] --- test/unit/plugins/provisioners/ansible/provisioner_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/plugins/provisioners/ansible/provisioner_test.rb b/test/unit/plugins/provisioners/ansible/provisioner_test.rb index 08e01dc9d..9fb9f8517 100644 --- a/test/unit/plugins/provisioners/ansible/provisioner_test.rb +++ b/test/unit/plugins/provisioners/ansible/provisioner_test.rb @@ -412,7 +412,7 @@ VF config.force_remote_user = false end - it "doesn't set ansiber user in inventory and use '--user' arguemnt with the vagrant ssh username" do + it "doesn't set ansiber user in inventory and use '--user' argument with the vagrant ssh username" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| inventory_content = File.read(generated_inventory_file) From e4ff8ee3989f85701855d10852e729eb76c6644c Mon Sep 17 00:00:00 2001 From: Gilles Cornu Date: Mon, 23 Nov 2015 09:12:56 +0100 Subject: [PATCH 5/5] provisioners/ansible: fix a typo in rspec example [ci skip] good morning @gildegoma!!! --- test/unit/plugins/provisioners/ansible/provisioner_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/plugins/provisioners/ansible/provisioner_test.rb b/test/unit/plugins/provisioners/ansible/provisioner_test.rb index 9fb9f8517..55b40cd18 100644 --- a/test/unit/plugins/provisioners/ansible/provisioner_test.rb +++ b/test/unit/plugins/provisioners/ansible/provisioner_test.rb @@ -412,7 +412,7 @@ VF config.force_remote_user = false end - it "doesn't set ansiber user in inventory and use '--user' argument with the vagrant ssh username" do + it "doesn't set the ansible remote user in inventory and use '--user' argument with the vagrant ssh username" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| inventory_content = File.read(generated_inventory_file)