aggregator.rb

Heads up: This description was created by AI and might not be 100% accurate.

This Ruby code snippet demonstrates functions for summarizing IP addresses into CIDR blocks, converting CIDR blocks to ACL entries, and generating netmasks from mask values. It utilizes the IPAddr class for IP address manipulation and range calculations. The code includes functions like summarize_ips, cidrs_to_acl, mask_to_netmask, cidr_to_acl, largest_block, and range_to_cidrs to achieve this.

Ruby code snippet

def summarize_ips(ip_list, min_mask: 0)
  ips = ip_list.uniq.map { IPAddr.new(_1) }.sort_by(&:to_i)

  ips.chunk_while { |a, b| b.to_i == a.to_i + 1 }
     .flat_map { |c| range_to_cidrs(c.first, c.last, min_mask: min_mask) }
end
#=> :summarize_ips

def cidrs_to_acl(entries)
  entries.map { |e| cidr_to_acl(e) }
end
#=> :cidrs_to_acl

def mask_to_netmask(mask)
  [(0xffffffff << (32 - mask)) & 0xffffffff]
    .pack('N').unpack('C4').join('.')
end
#=> :mask_to_netmask

def cidr_to_acl(entry)
  ip, mask = entry
  return "host #{ip}" if mask == 32

  "#{ip} #{mask_to_netmask(mask)}"
end
#=> :cidr_to_acl

def largest_block(start_ip, end_ip, min_mask)
  mask = 32
  best = [start_ip.to_s, 32]

  while mask >= min_mask
      block = IPAddr.new("#{start_ip}/#{mask}")
  
      break unless block.to_range.first == start_ip
      break if block.to_range.last > end_ip
  
      best = [start_ip.to_s, mask]
      mask -= 1
  end

  best
end
#=> :largest_block

def range_to_cidrs(start_ip, end_ip, min_mask:)
  res = []
  cur = start_ip

  while cur <= end_ip
      ip_str, mask = largest_block(cur, end_ip, min_mask)
      res << [ip_str, mask]
      block = IPAddr.new("#{cur}/#{mask}")
      cur = IPAddr.new(block.to_range.last.to_i + 1, Socket::AF_INET)
  end

  res
end
#=> :range_to_cidrs

ips = ['192.168.1.0', '192.168.1.1']
#=> ["192.168.1.0", "192.168.1.1"]
raw = summarize_ips(ips)
#=> [["192.168.1.0", 31]]
cidrs_to_acl(raw)
#=> ["192.168.1.0 255.255.255.254"]

Executed with Ruby 3.4.8.