diff --git a/plugins/commands/winrm_config/command.rb b/plugins/commands/winrm_config/command.rb index a2b1c2051..a2adeefa9 100644 --- a/plugins/commands/winrm_config/command.rb +++ b/plugins/commands/winrm_config/command.rb @@ -35,9 +35,14 @@ module VagrantPlugins winrm_info = CommunicatorWinRM::Helper.winrm_info(machine) raise Vagrant::Errors::WinRMNotRead if winrm_info.nil? + rdp_info = get_rdp_info(machine) || {} + variables = { host_key: options[:host] || machine.name || "vagrant", - rdp_port: machine.config.rdp.port, + rdp_host: rdp_info[:host] || winrm_info[:host], + rdp_port: rdp_info[:port], + rdp_user: rdp_info[:username], + rdp_pass: rdp_info[:password], winrm_host: winrm_info[:host], winrm_port: winrm_info[:port], winrm_user: machine.config.winrm.username, @@ -54,6 +59,66 @@ module VagrantPlugins # Success, exit status 0 0 end + + protected + + # Generate RDP information for machine + # + # @param [Vagrant::Machine] machine Guest machine + # @return [Hash, nil] + def get_rdp_info(machine) + rdp_info = {} + if machine.provider.capability?(:rdp_info) + rdp_info = machine.provider.capability(:rdp_info) + rdp_info ||= {} + end + + ssh_info = machine.ssh_info || {} + + if !rdp_info[:username] + username = ssh_info[:username] + if machine.config.vm.communicator == :winrm + username = machine.config.winrm.username + end + rdp_info[:username] = username + end + + if !rdp_info[:password] + password = ssh_info[:password] + if machine.config.vm.communicator == :winrm + password = machine.config.winrm.password + end + rdp_info[:password] = password + end + + rdp_info[:host] ||= ssh_info[:host] + rdp_info[:port] ||= machine.config.rdp.port + rdp_info[:username] ||= machine.config.rdp.username + + if rdp_info[:host] == "127.0.0.1" + # We need to find a forwarded port... + search_port = machine.config.rdp.search_port + ports = nil + if machine.provider.capability?(:forwarded_ports) + ports = machine.provider.capability(:forwarded_ports) + else + ports = {}.tap do |result| + machine.config.vm.networks.each do |type, netopts| + next if type != :forwarded_port + next if !netopts[:host] + result[netopts[:host]] = netopts[:guest] + end + end + end + + ports = ports.invert + port = ports[search_port] + rdp_info[:port] = port + return nil if !port + end + + rdp_info + end end end end diff --git a/templates/commands/winrm_config/config.erb b/templates/commands/winrm_config/config.erb index 97d93e6d5..9eb269eb1 100644 --- a/templates/commands/winrm_config/config.erb +++ b/templates/commands/winrm_config/config.erb @@ -3,4 +3,9 @@ Host <%= host_key %> User <%= winrm_user %> Password <%= winrm_password %> Port <%= winrm_port %> + <% if rdp_port -%> + RDPHostName <%= rdp_host %> RDPPort <%= rdp_port %> + RDPUser <%= rdp_user %> + RDPPassword <%= rdp_pass %> + <% end -%> diff --git a/test/unit/plugins/commands/winrm_config/command_test.rb b/test/unit/plugins/commands/winrm_config/command_test.rb index 3530f21d7..95d3be329 100644 --- a/test/unit/plugins/commands/winrm_config/command_test.rb +++ b/test/unit/plugins/commands/winrm_config/command_test.rb @@ -26,10 +26,13 @@ describe VagrantPlugins::CommandWinRMConfig::Command do let(:config) { double("config", winrm: double("winrm-config", username: "vagrant", password: "vagrant"), - rdp: double("rdp-config", port: 9876) + rdp: rdp_config, + vm: double("vm-config", communicator: :winrm) ) } + let(:rdp_config) { double("rdp-config", port: 9876) } + subject { described_class.new(argv, iso_env) } before do @@ -53,7 +56,10 @@ Host #{machine.name} User vagrant Password vagrant Port 1234 + RDPHostName testhost.vagrant.dev RDPPort 9876 + RDPUser vagrant + RDPPassword vagrant WINRMCONFIG end @@ -74,9 +80,64 @@ Host my-host User vagrant Password vagrant Port 1234 + RDPHostName testhost.vagrant.dev RDPPort 9876 + RDPUser vagrant + RDPPassword vagrant WINRMCONFIG end end + + context "when no RDP port is configured" do + let(:rdp_config) { double("rdp-config", port: nil) } + + it "should not include any RDP configuration information" do + output = "" + allow(subject).to receive(:safe_puts) do |data| + output += data if data + end + + subject.execute + expect(output).not_to include("RDP") + end + end + + context "when provider has rdp_info capability" do + let(:rdp_info) { + {host: "provider-host", port: 9999, username: "pvagrant", password: "pvagrant"} + } + + before do + allow(machine.provider).to receive(:capability?).with(:rdp_info).and_return(true) + allow(machine.provider).to receive(:capability).with(:rdp_info).and_return(rdp_info) + end + + it "should use provider RDP information" do + output = "" + allow(subject).to receive(:safe_puts) do |data| + output += data if data + end + + subject.execute + expect(output).to include("RDPPort 9999") + expect(output).to include("RDPHostName provider-host") + expect(output).to include("RDPUser pvagrant") + expect(output).to include("RDPPassword pvagrant") + end + + context "when provider rdp_info does not include host" do + before { rdp_info[:host] = nil } + + it "should use winrm host" do + output = "" + allow(subject).to receive(:safe_puts) do |data| + output += data if data + end + + subject.execute + expect(output).to include("RDPHostName testhost.vagrant.dev") + end + end + end end end