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