Module: VagrantDockerNetworksManager::Util
- Defined in:
- lib/vagrant-docker-networks-manager/util.rb
Class Method Summary collapse
- .cidr_overlap?(a, b) ⇒ Boolean
- .docker_available? ⇒ Boolean
- .docker_network_exists?(name) ⇒ Boolean
- .docker_subnet_conflicts?(target_cidr, ignore_network: nil) ⇒ Boolean
- .each_docker_cidr(ignore_network: nil) ⇒ Object
- .inspect_networks_batched(ids_or_names) ⇒ Object
- .list_plugin_networks ⇒ Object
- .list_plugin_networks_detailed ⇒ Object
- .normalize_cidr(cidr) ⇒ Object
- .read_network_labels(name) ⇒ Object
- .sh!(*args) ⇒ Object
- .valid_subnet?(cidr) ⇒ Boolean
Class Method Details
.cidr_overlap?(a, b) ⇒ Boolean
123 124 125 126 127 128 129 130 131 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 123 def cidr_overlap?(a, b) ip_a, mask_a = a.to_s.split("/", 2); ip_b, mask_b = b.to_s.split("/", 2) return false unless mask_a && mask_b na = IPAddr.new(ip_a).mask(mask_a.to_i) nb = IPAddr.new(ip_b).mask(mask_b.to_i) na.include?(IPAddr.new(ip_b)) || nb.include?(IPAddr.new(ip_a)) rescue false end |
.docker_available? ⇒ Boolean
22 23 24 25 26 27 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 22 def docker_available? _out, _err, status = Open3.capture3("docker", "info") status.success? rescue false end |
.docker_network_exists?(name) ⇒ Boolean
29 30 31 32 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 29 def docker_network_exists?(name) out, _err, st = Open3.capture3("docker", "network", "ls", "--format", "{{.Name}}") st.success? && out.split.include?(name) end |
.docker_subnet_conflicts?(target_cidr, ignore_network: nil) ⇒ Boolean
146 147 148 149 150 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 146 def docker_subnet_conflicts?(target_cidr, ignore_network: nil) t_norm = normalize_cidr(target_cidr) return false unless t_norm each_docker_cidr(ignore_network: ignore_network).any? { |c| cidr_overlap?(t_norm, c) } end |
.each_docker_cidr(ignore_network: nil) ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 133 def each_docker_cidr(ignore_network: nil) out, _e, st = Open3.capture3("docker", "network", "ls", "-q") return [] unless st.success? out.split.each_slice(50).flat_map do |chunk| o, _e2, st2 = Open3.capture3("docker", "network", "inspect", *chunk) next [] unless st2.success? JSON.parse(o).filter_map do |net| next if ignore_network && net["Name"] == ignore_network (net.dig("IPAM","Config") || []).map { |cfg| normalize_cidr(cfg["Subnet"]) }.compact end.flatten end end |
.inspect_networks_batched(ids_or_names) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 40 def inspect_networks_batched(ids_or_names) result = {} ids_or_names.each_slice(50) do |chunk| out, _e, st = Open3.capture3("docker", "network", "inspect", *chunk) next unless st.success? JSON.parse(out).each do |net| subs = (net.dig("IPAM","Config") || []).map { |c| c["Subnet"] }.compact cons = (net["Containers"] || {}).size key = net["Id"] || net["Name"] result[key] = { subnets: subs, containers_count: cons } result[net["Name"]] ||= result[key] end end result rescue {} end |
.list_plugin_networks ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 58 def list_plugin_networks out, _err, st = Open3.capture3( "docker", "network", "ls", "--filter", "label=com.vagrant.plugin=docker_networks_manager", "--format", "{{.ID}}\t{{.Name}}\t{{.Driver}}\t{{.Scope}}" ) return [] unless st.success? rows = out.lines.map do |line| id, name, driver, scope = line.strip.split("\t", 4) { id: id, name: name, driver: driver, scope: scope } end details = inspect_networks_batched(rows.map { |r| r[:name] }) rows.each do |r| subs = details.dig(r[:name], :subnets) || [] r[:subnets] = subs.empty? ? "-" : subs.join(", ") end rows rescue [] end |
.list_plugin_networks_detailed ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 82 def list_plugin_networks_detailed out, _err, st = Open3.capture3( "docker", "network", "ls", "--filter", "label=com.vagrant.plugin=docker_networks_manager", "--format", "{{.ID}}\t{{.Name}}\t{{.Driver}}\t{{.Scope}}" ) return [] unless st.success? rows = out.lines.map { |line| id, name, driver, scope = line.strip.split("\t", 4) { id: id, name: name, driver: driver, scope: scope } } details = inspect_networks_batched(rows.map { |r| r[:name] }) rows.each do |r| r[:subnets] = details.dig(r[:name], :subnets) || [] r[:containers] = details.dig(r[:name], :containers_count) || 0 end rows end |
.normalize_cidr(cidr) ⇒ Object
113 114 115 116 117 118 119 120 121 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 113 def normalize_cidr(cidr) ip_str, mask_str = cidr.to_s.split("/", 2) return nil unless ip_str && mask_str && mask_str =~ /^\d+$/ && (0..32).include?(mask_str.to_i) ip = IPAddr.new(ip_str) rescue nil return nil unless ip&.ipv4? "#{ip.mask(mask_str.to_i)}/#{mask_str.to_i}" rescue nil end |
.read_network_labels(name) ⇒ Object
34 35 36 37 38 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 34 def read_network_labels(name) out, _err, st = Open3.capture3("docker", "network", "inspect", name, "--format", "{{json .Labels}}") return {} unless st.success? JSON.parse(out.to_s.strip) rescue {} end |
.sh!(*args) ⇒ Object
12 13 14 15 16 17 18 19 20 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 12 def sh!(*args) if ENV["VDNM_VERBOSE"] == "1" printable = ["docker", *args].map(&:to_s).shelljoin $stderr.puts("[VDNM] #{printable}") system("docker", *args) else system("docker", *args, out: File::NULL, err: :out) end end |
.valid_subnet?(cidr) ⇒ Boolean
103 104 105 106 107 108 109 110 111 |
# File 'lib/vagrant-docker-networks-manager/util.rb', line 103 def valid_subnet?(cidr) ip_str, mask_str = cidr.to_s.split("/", 2) return false unless ip_str && mask_str && mask_str =~ /^\d+$/ && (0..32).include?(mask_str.to_i) ip = IPAddr.new(ip_str) rescue nil return false unless ip && ip.ipv4? (ip.mask(mask_str.to_i).to_s == ip_str) rescue false end |