งูต้นฉบับกำลังรวบการ์ดเครือข่ายที่ติดกันเป็นมัดเดียวอย่างพอดี

Python collapse_addresses: รวม CIDR ที่ติดกันโดยไม่ขยายเป็นทุก IP

พี่โชว์Engineering

ACL ที่สะสมมานานมักมี CIDR ซ้อนกันหรือมีสองครึ่งที่รวมเป็น network ใหญ่ได้ครับ ipaddress.collapse_addresses รับ network/address iterable แล้วคืนชุดที่ครอบคลุมพื้นที่เดิมโดยตัดส่วนซ้ำและรวมช่วงที่ติดกันได้

WHY: ลดกฎโดยไม่แจกแจงทุก address

สอง /25 ที่เรียงติดและอยู่บน boundary เดียวกันรวมเป็น /24 ได้ เหมือนรวมโต๊ะสองแถวเป็นโซนเดียว แต่ช่วงที่ดูติดกันด้วยตาอาจรวมไม่ได้หาก prefix alignment ไม่พอดี ฟังก์ชันช่วยทำ binary boundary ให้ถูกโดยไม่สร้าง IP ทุกตัวในหน่วยความจำ

from ipaddress import IPv4Network, IPv6Network, collapse_addresses
import unittest


def compact_ipv4(values):
    networks = [IPv4Network(value) for value in values]
    return [str(network) for network in collapse_addresses(networks)]


class CollapseTests(unittest.TestCase):
    def test_adjacent_halves_become_one_network(self):
        self.assertEqual(
            compact_ipv4(["10.0.0.0/25", "10.0.0.128/25", "10.0.0.0/26"]),
            ["10.0.0.0/24"],
        )

    def test_disjoint_networks_remain_separate(self):
        self.assertEqual(
            compact_ipv4(["10.0.0.0/25", "10.0.1.0/25"]),
            ["10.0.0.0/25", "10.0.1.0/25"],
        )

    def test_ip_versions_must_not_be_mixed(self):
        with self.assertRaises(TypeError):
            list(collapse_addresses([IPv4Network("10.0.0.0/24"), IPv6Network("2001:db8::/64")]))


if __name__ == "__main__":
    unittest.main()

Policy ไม่ได้ยุบตาม network เสมอ

ผลลัพธ์รักษา “ชุด address ที่ครอบคลุม” แต่ไม่ได้รักษา metadata ของกฎ เช่น owner, expiry, reason หรือ action ถ้า /25 แรกเป็น allow และอีกครึ่งเป็น deny ห้ามรวมแม้ช่วง address ต่อกัน ต้อง group ตาม semantics ก่อน collapse แล้วตรวจว่า policy เดียวกันจริง

แยก IPv4 กับ IPv6 ก่อน เพราะการปนกันยก TypeError และ parse ด้วย strict=True เมื่อ input ควรเป็น network address จริง หากต้องยอม host bits ให้ระบุ strict=False อย่างตั้งใจและ log normalization

Recap

  • รวมเฉพาะ network ที่มี policy/metadata เดียวกัน
  • แยก IPv4 และ IPv6 ก่อน collapse
  • ใช้ strict parsing ที่ boundary ถ้า host bits คือ error
  • เปรียบเทียบ coverage ก่อนและหลังใน test