WinRM SSL support
This commit is contained in:
parent
61a792ac9f
commit
234adaae63
|
@ -106,11 +106,8 @@ module VagrantPlugins
|
|||
|
||||
WinRMShell.new(
|
||||
winrm_info[:host],
|
||||
@machine.config.winrm.username,
|
||||
@machine.config.winrm.password,
|
||||
port: winrm_info[:port],
|
||||
timeout_in_seconds: @machine.config.winrm.timeout,
|
||||
max_tries: @machine.config.winrm.max_tries,
|
||||
winrm_info[:port],
|
||||
@machine.config.winrm
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -8,25 +8,32 @@ module VagrantPlugins
|
|||
attr_accessor :guest_port
|
||||
attr_accessor :max_tries
|
||||
attr_accessor :timeout
|
||||
attr_accessor :transport
|
||||
attr_accessor :ssl_peer_verification
|
||||
|
||||
def initialize
|
||||
@username = UNSET_VALUE
|
||||
@password = UNSET_VALUE
|
||||
@host = UNSET_VALUE
|
||||
@port = UNSET_VALUE
|
||||
@guest_port = UNSET_VALUE
|
||||
@max_tries = UNSET_VALUE
|
||||
@timeout = UNSET_VALUE
|
||||
@username = UNSET_VALUE
|
||||
@password = UNSET_VALUE
|
||||
@host = UNSET_VALUE
|
||||
@port = UNSET_VALUE
|
||||
@guest_port = UNSET_VALUE
|
||||
@max_tries = UNSET_VALUE
|
||||
@timeout = UNSET_VALUE
|
||||
@transport = UNSET_VALUE
|
||||
@ssl_peer_verification = UNSET_VALUE
|
||||
end
|
||||
|
||||
def finalize!
|
||||
@username = "vagrant" if @username == UNSET_VALUE
|
||||
@password = "vagrant" if @password == UNSET_VALUE
|
||||
@username = "vagrant" if @username == UNSET_VALUE
|
||||
@password = "vagrant" if @password == UNSET_VALUE
|
||||
@transport = :plaintext if @transport == UNSET_VALUE
|
||||
@host = nil if @host == UNSET_VALUE
|
||||
@port = 5985 if @port == UNSET_VALUE
|
||||
@guest_port = 5985 if @guest_port == UNSET_VALUE
|
||||
is_ssl = @transport == :ssl
|
||||
@port = (is_ssl ? 5986 : 5985) if @port == UNSET_VALUE
|
||||
@guest_port = (is_ssl ? 5986 : 5985) if @guest_port == UNSET_VALUE
|
||||
@max_tries = 20 if @max_tries == UNSET_VALUE
|
||||
@timeout = 1800 if @timeout == UNSET_VALUE
|
||||
@ssl_peer_verification = true if @ssl_peer_verification == UNSET_VALUE
|
||||
end
|
||||
|
||||
def validate(machine)
|
||||
|
@ -38,6 +45,9 @@ module VagrantPlugins
|
|||
errors << "winrm.guest_port cannot be nil." if @guest_port.nil?
|
||||
errors << "winrm.max_tries cannot be nil." if @max_tries.nil?
|
||||
errors << "winrm.timeout cannot be nil." if @timeout.nil?
|
||||
unless @ssl_peer_verification == true || @ssl_peer_verification == false
|
||||
errors << "winrm.ssl_peer_verification must be a boolean."
|
||||
end
|
||||
|
||||
{ "WinRM" => errors }
|
||||
end
|
||||
|
|
|
@ -32,23 +32,21 @@ module VagrantPlugins
|
|||
]
|
||||
|
||||
attr_reader :logger
|
||||
attr_reader :username
|
||||
attr_reader :password
|
||||
attr_reader :host
|
||||
attr_reader :port
|
||||
attr_reader :timeout_in_seconds
|
||||
attr_reader :max_tries
|
||||
attr_reader :username
|
||||
attr_reader :password
|
||||
attr_reader :config
|
||||
|
||||
def initialize(host, username, password, options = {})
|
||||
def initialize(host, port, config)
|
||||
@logger = Log4r::Logger.new("vagrant::communication::winrmshell")
|
||||
@logger.debug("initializing WinRMShell")
|
||||
|
||||
@host = host
|
||||
@port = options[:port] || 5985
|
||||
@username = username
|
||||
@password = password
|
||||
@timeout_in_seconds = options[:timeout_in_seconds] || 60
|
||||
@max_tries = options[:max_tries] || 20
|
||||
@host = host
|
||||
@port = port
|
||||
@username = config.username
|
||||
@password = config.password
|
||||
@config = config
|
||||
end
|
||||
|
||||
def powershell(command, &block)
|
||||
|
@ -87,7 +85,7 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
def execute_shell_with_retry(command, shell, &block)
|
||||
retryable(tries: @max_tries, on: @@exceptions_to_retry_on, sleep: 10) do
|
||||
retryable(tries: @config.max_tries, on: @@exceptions_to_retry_on, sleep: 10) do
|
||||
@logger.debug("#{shell} executing:\n#{command}")
|
||||
output = session.send(shell, command) do |out, err|
|
||||
block.call(:stdout, out) if block_given? && out
|
||||
|
@ -118,10 +116,11 @@ module VagrantPlugins
|
|||
@logger.info("Attempting to connect to WinRM...")
|
||||
@logger.info(" - Host: #{@host}")
|
||||
@logger.info(" - Port: #{@port}")
|
||||
@logger.info(" - Username: #{@username}")
|
||||
@logger.info(" - Username: #{@config.username}")
|
||||
@logger.info(" - Transport: #{@config.transport}")
|
||||
|
||||
client = ::WinRM::WinRMWebService.new(endpoint, :plaintext, endpoint_options)
|
||||
client.set_timeout(@timeout_in_seconds)
|
||||
client = ::WinRM::WinRMWebService.new(endpoint, @config.transport.to_sym, endpoint_options)
|
||||
client.set_timeout(@config.timeout)
|
||||
client.toggle_nori_type_casting(:off) #we don't want coersion of types
|
||||
client
|
||||
end
|
||||
|
@ -131,7 +130,14 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
def endpoint
|
||||
"http://#{@host}:#{@port}/wsman"
|
||||
case @config.transport.to_sym
|
||||
when :ssl
|
||||
"https://#{@host}:#{@port}/wsman"
|
||||
when :plaintext
|
||||
"http://#{@host}:#{@port}/wsman"
|
||||
else
|
||||
raise Errors::WinRMInvalidTransport, transport: @config.transport
|
||||
end
|
||||
end
|
||||
|
||||
def endpoint_options
|
||||
|
@ -139,8 +145,8 @@ module VagrantPlugins
|
|||
pass: @password,
|
||||
host: @host,
|
||||
port: @port,
|
||||
operation_timeout: @timeout_in_seconds,
|
||||
basic_auth_only: true }
|
||||
basic_auth_only: true,
|
||||
no_ssl_peer_verification: !@config.ssl_peer_verification }
|
||||
end
|
||||
end #WinShell class
|
||||
end
|
||||
|
|
|
@ -399,10 +399,15 @@ module VagrantPlugins
|
|||
host_ip: "127.0.0.1",
|
||||
id: "winrm",
|
||||
auto_correct: true
|
||||
end
|
||||
end
|
||||
|
||||
if !@__networks["forwarded_port-ssh"]
|
||||
network :forwarded_port,
|
||||
guest: 5986,
|
||||
host: 55986,
|
||||
host_ip: "127.0.0.1",
|
||||
id: "winrm-ssl",
|
||||
auto_correct: true
|
||||
end
|
||||
elsif !@__networks["forwarded_port-ssh"]
|
||||
network :forwarded_port,
|
||||
guest: 22,
|
||||
host: 2222,
|
||||
|
|
|
@ -101,6 +101,6 @@ describe VagrantPlugins::CommunicatorWinRM::Communicator do
|
|||
expect(shell).to receive(:download).with("from", "to")
|
||||
subject.download("from", "to")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,14 +1,23 @@
|
|||
require File.expand_path("../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/communicators/winrm/shell")
|
||||
require Vagrant.source_root.join("plugins/communicators/winrm/config")
|
||||
|
||||
describe VagrantPlugins::CommunicatorWinRM::WinRMShell do
|
||||
include_context "unit"
|
||||
|
||||
let(:session) { double("winrm_session") }
|
||||
let(:port) { config.transport == :ssl ? 5986 : 5985 }
|
||||
let(:config) {
|
||||
VagrantPlugins::CommunicatorWinRM::Config.new.tap do |c|
|
||||
c.username = 'username'
|
||||
c.password = 'password'
|
||||
c.finalize!
|
||||
end
|
||||
}
|
||||
|
||||
subject do
|
||||
described_class.new('localhost', 'username', 'password').tap do |comm|
|
||||
described_class.new('localhost', port, config).tap do |comm|
|
||||
allow(comm).to receive(:new_session).and_return(session)
|
||||
end
|
||||
end
|
||||
|
@ -20,7 +29,8 @@ describe VagrantPlugins::CommunicatorWinRM::WinRMShell do
|
|||
end
|
||||
|
||||
it "should raise auth error when exception message contains 401" do
|
||||
expect(session).to receive(:powershell).with(/^dir.+/).and_raise(
|
||||
config.winrm.max_tries = 2
|
||||
expect(session).to receive(:powershell).with(/^dir.+/).twice.and_raise(
|
||||
StandardError.new("Oh no! a 401 SOAP error!"))
|
||||
expect { subject.powershell("dir") }.to raise_error(
|
||||
VagrantPlugins::CommunicatorWinRM::Errors::AuthError)
|
||||
|
@ -42,8 +52,22 @@ describe VagrantPlugins::CommunicatorWinRM::WinRMShell do
|
|||
end
|
||||
|
||||
describe ".endpoint" do
|
||||
it "should create winrm endpoint address" do
|
||||
expect(subject.send(:endpoint)).to eq("http://localhost:5985/wsman")
|
||||
context 'when transport is :ssl' do
|
||||
let(:config) {
|
||||
VagrantPlugins::CommunicatorWinRM::Config.new.tap do |c|
|
||||
c.transport = :ssl
|
||||
c.finalize!
|
||||
end
|
||||
}
|
||||
it "should create winrm endpoint address using https" do
|
||||
expect(subject.send(:endpoint)).to eq("https://localhost:5986/wsman")
|
||||
end
|
||||
end
|
||||
|
||||
context "when transport is :plaintext" do
|
||||
it "should create winrm endpoint address using http" do
|
||||
expect(subject.send(:endpoint)).to eq("http://localhost:5985/wsman")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -51,7 +75,7 @@ describe VagrantPlugins::CommunicatorWinRM::WinRMShell do
|
|||
it "should create endpoint options" do
|
||||
expect(subject.send(:endpoint_options)).to eq(
|
||||
{ user: "username", pass: "password", host: "localhost", port: 5985,
|
||||
operation_timeout: 60, basic_auth_only: true })
|
||||
basic_auth_only: true, no_ssl_peer_verification: false })
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -23,6 +23,13 @@ describe VagrantPlugins::Kernel_V2::VMConfig do
|
|||
end
|
||||
end
|
||||
|
||||
def find_network(name)
|
||||
network_definitions = subject.networks.map do |n|
|
||||
n[1]
|
||||
end
|
||||
network_definitions.find {|n| n[:id] == name}
|
||||
end
|
||||
|
||||
before do
|
||||
env = double("env")
|
||||
env.stub(root_path: nil)
|
||||
|
@ -183,6 +190,7 @@ describe VagrantPlugins::Kernel_V2::VMConfig do
|
|||
subject.finalize!
|
||||
n = subject.networks
|
||||
expect(n.length).to eq(2)
|
||||
|
||||
expect(n[0][0]).to eq(:forwarded_port)
|
||||
expect(n[0][1][:guest]).to eq(5985)
|
||||
expect(n[0][1][:host]).to eq(55985)
|
||||
|
@ -190,9 +198,10 @@ describe VagrantPlugins::Kernel_V2::VMConfig do
|
|||
expect(n[0][1][:id]).to eq("winrm")
|
||||
|
||||
expect(n[1][0]).to eq(:forwarded_port)
|
||||
expect(n[1][1][:guest]).to eq(22)
|
||||
expect(n[1][1][:host]).to eq(2222)
|
||||
expect(n[1][1][:id]).to eq("ssh")
|
||||
expect(n[1][1][:guest]).to eq(5986)
|
||||
expect(n[1][1][:host]).to eq(55986)
|
||||
expect(n[1][1][:host_ip]).to eq("127.0.0.1")
|
||||
expect(n[1][1][:id]).to eq("winrm-ssl")
|
||||
end
|
||||
|
||||
it "allows overriding SSH" do
|
||||
|
@ -214,12 +223,22 @@ describe VagrantPlugins::Kernel_V2::VMConfig do
|
|||
guest: 22, host: 14100, id: "winrm"
|
||||
subject.finalize!
|
||||
|
||||
n = subject.networks
|
||||
expect(n.length).to eq(2)
|
||||
expect(n[0][0]).to eq(:forwarded_port)
|
||||
expect(n[0][1][:guest]).to eq(22)
|
||||
expect(n[0][1][:host]).to eq(14100)
|
||||
expect(n[0][1][:id]).to eq("winrm")
|
||||
winrm_network = find_network 'winrm'
|
||||
expect(winrm_network[:guest]).to eq(22)
|
||||
expect(winrm_network[:host]).to eq(14100)
|
||||
expect(winrm_network[:id]).to eq("winrm")
|
||||
end
|
||||
|
||||
it "allows overriding WinRM SSL" do
|
||||
subject.communicator = :winrmssl
|
||||
subject.network "forwarded_port",
|
||||
guest: 22, host: 14100, id: "winrmssl"
|
||||
subject.finalize!
|
||||
|
||||
winrmssl_network = find_network 'winrmssl'
|
||||
expect(winrmssl_network[:guest]).to eq(22)
|
||||
expect(winrmssl_network[:host]).to eq(14100)
|
||||
expect(winrmssl_network[:id]).to eq("winrmssl")
|
||||
end
|
||||
|
||||
it "turns all forwarded port ports to ints" do
|
||||
|
|
|
@ -28,7 +28,7 @@ Gem::Specification.new do |s|
|
|||
s.add_dependency "rb-kqueue", "~> 0.2.0"
|
||||
s.add_dependency "rest-client", ">= 1.6.0", "< 2.0"
|
||||
s.add_dependency "wdm", "~> 0.1.0"
|
||||
s.add_dependency "winrm", "~> 1.1.3"
|
||||
s.add_dependency "winrm", "= 1.3.0.dev.2"
|
||||
|
||||
# We lock this down to avoid compilation issues.
|
||||
s.add_dependency "nokogiri", "= 1.6.3.1"
|
||||
|
|
Loading…
Reference in New Issue