From 1e5a203ddc779a0434fe88112e8beaad11ffe6c8 Mon Sep 17 00:00:00 2001 From: Dexter <45038532+munchtoast@users.noreply.github.com> Date: Fri, 4 Jul 2025 04:15:25 -0400 Subject: [PATCH] Vagrant: Ensure IP Subnet not in use by localhost (#12332) * feat(subnet): Ensure Vagrant subnet not in use by localhost This commit ensures that Vagrantfile supplied $subnet is not in use by the localhost. Previously, if the subnet is in use by localhost (i.e. bridge network), Vagrant VM boxes can not communicate. * refactor(socket): Use ruby Socket library to find addrs This commit reverts the usage of Ruby .scan() which may result in failure if program is not provided. Instead, this commit refactors to use Socket library to determine interfaces in use, then proceeds to compare with Vagrantfile supplied subnets. Additionally, the commit supports IPv6 comparisons. --- Vagrantfile | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Vagrantfile b/Vagrantfile index af4ab0ab8..833ca95ee 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -4,6 +4,8 @@ # For help on using kubespray with vagrant, check out docs/developers/vagrant.md require 'fileutils' +require 'ipaddr' +require 'socket' Vagrant.require_version ">= 2.0.0" @@ -99,6 +101,33 @@ $extra_vars ||= {} host_vars = {} +def collect_networks(subnet, subnet_ipv6) + Socket.getifaddrs.filter_map do |iface| + next unless iface&.netmask&.ip_address && iface.addr + + is_ipv6 = iface.addr.ipv6? + ip = IPAddr.new(iface.addr.ip_address.split('%').first) + ip_test = is_ipv6 ? IPAddr.new("#{subnet_ipv6}::0") : IPAddr.new("#{subnet}.0") + + prefix = IPAddr.new(iface.netmask.ip_address).to_i.to_s(2).count('1') + network = ip.mask(prefix) + + [IPAddr.new("#{network}/#{prefix}"), ip_test] + end +end + +def subnet_in_use?(network_ips) + network_ips.any? { |net, test_ip| net.include?(test_ip) && test_ip != net } +end + +network_ips = collect_networks($subnet, $subnet_ipv6) + +if subnet_in_use?(network_ips) + puts "Invalid subnet provided, subnet is already in use: #{$subnet}.0" + puts "Subnets in use: #{network_ips.inspect}" + exit 1 +end + # throw error if os is not supported if ! SUPPORTED_OS.key?($os) puts "Unsupported OS: #{$os}"