Add ipv4_only option to limit connecting to guest IPv4 addresses only

This commit is contained in:
Cameron Jack 2022-02-16 07:50:19 +11:00
parent 3d68e16f1b
commit f509231e7c
5 changed files with 69 additions and 4 deletions

View file

@ -12,9 +12,13 @@ module VagrantPlugins
def call(env)
timeout = env[:machine].provider_config.ip_address_timeout
ipv4_only = env[:machine].provider_config.ipv4_only
env[:ui].output("Waiting for the machine to report its IP address...")
env[:ui].detail("Timeout: #{timeout} seconds")
if ipv4_only
env[:ui].detail("Waiting for IPv4 address only")
end
guest_ip = nil
Timeout.timeout(timeout) do
@ -29,8 +33,8 @@ module VagrantPlugins
if guest_ip
begin
IPAddr.new(guest_ip)
break
ip = IPAddr.new(guest_ip)
break unless ipv4_only && !ip.ipv4?()
rescue IPAddr::InvalidAddressError
# Ignore, continue looking.
@logger.warn("Invalid IP address returned: #{guest_ip}")

View file

@ -50,6 +50,8 @@ module VagrantPlugins
attr_accessor :vm_integration_services
# @return [Boolean] Enable Enhanced session mode
attr_accessor :enable_enhanced_session_mode
# @return [Boolean] Enable IPv4 only for connection to guest
attr_accessor :ipv4_only
def initialize
@ip_address_timeout = UNSET_VALUE
@ -68,6 +70,7 @@ module VagrantPlugins
@enable_checkpoints = UNSET_VALUE
@vm_integration_services = {}
@enable_enhanced_session_mode = UNSET_VALUE
@ipv4_only = UNSET_VALUE
end
def finalize!
@ -107,6 +110,10 @@ module VagrantPlugins
@enable_checkpoints ||= @enable_automatic_checkpoints
@enable_enhanced_session_mode = false if @enable_enhanced_session_mode == UNSET_VALUE
if @ipv4_only == UNSET_VALUE
@ipv4_only = Vagrant::Util::Platform.wsl? ? true : false
end
end
def validate(machine)

View file

@ -9,14 +9,16 @@ describe VagrantPlugins::HyperV::Action::WaitForIPAddress do
let(:provider){ double("provider", driver: driver) }
let(:driver){ double("driver") }
let(:machine){ double("machine", provider: provider, provider_config: provider_config) }
let(:provider_config){ double("provider_config", ip_address_timeout: ip_address_timeout) }
let(:provider_config){ double("provider_config", ip_address_timeout: ip_address_timeout, ipv4_only: ipv4_only) }
let(:ip_address_timeout){ 1 }
let(:ipv4_only){ false }
let(:subject){ described_class.new(app, env) }
before do
allow(driver).to receive(:read_guest_ip).and_return("ip" => "127.0.0.1")
allow(app).to receive(:call)
allow(Vagrant::Util::Platform).to receive(:wsl?).and_return(false)
end
it "should call the app on success" do
@ -35,4 +37,30 @@ describe VagrantPlugins::HyperV::Action::WaitForIPAddress do
expect(subject).to receive(:sleep)
subject.call(env)
end
it "should call the app on success with IPv6 address" do
expect(driver).to receive(:read_guest_ip).and_return("ip" => "FE80:0000:0000:0000:0202:B3FF:FE1E:8329")
subject.call(env)
end
context "IPv4_only" do
let(:ipv4_only){ true }
it "should call the app on success" do
expect(app).to receive(:call)
subject.call(env)
end
it "should set a timeout for waiting for IPv4 address" do
expect(Timeout).to receive(:timeout).with(ip_address_timeout)
subject.call(env)
end
it "should retry until it receives a valid IPv4 address" do
expect(driver).to receive(:read_guest_ip).and_return("ip" => "FE80:0000:0000:0000:0202:B3FF:FE1E:8329")
expect(driver).to receive(:read_guest_ip).and_return("ip" => "127.0.0.1")
expect(subject).to receive(:sleep)
subject.call(env)
end
end
end

View file

@ -242,7 +242,6 @@ describe VagrantPlugins::HyperV::Config do
end
end
describe "#enable_enhanced_session_mode" do
it "is false by default" do
subject.finalize!
@ -255,4 +254,30 @@ describe VagrantPlugins::HyperV::Config do
expect(subject.enable_enhanced_session_mode).to eq(true)
end
end
describe "#ipv4_only" do
context "within the WSL" do
before{ allow(Vagrant::Util::Platform).to receive(:wsl?).and_return(true) }
it "is true by default when in WSL" do
subject.finalize!
expect(subject.ipv4_only).to eq(true)
end
end
context "not within the WSL" do
before{ allow(Vagrant::Util::Platform).to receive(:wsl?).and_return(false) }
it "is false by default" do
subject.finalize!
expect(subject.ipv4_only).to eq(false)
end
end
it "can be set" do
subject.ipv4_only = true
subject.finalize!
expect(subject.ipv4_only).to eq(true)
end
end
end

View file

@ -20,6 +20,7 @@ you may set. A complete reference is shown below:
- `enable_automatic_checkpoints` (boolean) Enable automatic checkpoints of the VM. Default: false
- `enable_enhanced_session_mode` (boolean) - Enable enhanced session transport type for the VM. Default: false
- `ip_address_timeout` (integer) - Number of seconds to wait for the VM to report an IP address. Default: 120.
- `ipv4_only` (boolean) - Only connect to a guests IPv4 address ignoring an IPv6 address. Default: false unless running in WSL, in which case it will default to true.
- `linked_clone` (boolean) - Use differencing disk instead of cloning entire VHD. Default: false
- `mac` (string) - MAC address for the guest network interface
- `maxmemory` (integer) - Maximum number of megabytes allowed to be allocated for the VM. When set Dynamic Memory Allocation will be enabled.