Module: Ruby::Rego::Builtins::Net
- Extended by:
- RegistryHelpers
- Defined in:
- lib/ruby/rego/builtins/net.rb,
lib/ruby/rego/builtins/net/cidr_merge.rb,
lib/ruby/rego/builtins/net/contains_matches.rb
Overview
net.cidr_contains_matches — the cidr-vs-address containment cross-product. Lives apart from the net.* core so that file stays under RubyCritic’s complexity budget. Reopens Net; bare references to shared helpers (parse_cidr, parse_addr, normalize, raise_invalid_addr) resolve via the reopened module’s lexical scope.
Constant Summary collapse
- MAX_EXPAND_SIZE =
cidr_expand has no bound in OPA (it relies on Go’s runtime); expanding a CIDR with more than this many addresses yields undefined here. A /12 (IPv4) is ~1M.
1_000_000- NET_FUNCTIONS =
{ "net.cidr_contains" => { arity: 2, handler: :cidr_contains }, "net.cidr_contains_matches" => { arity: 2, handler: :cidr_contains_matches }, "net.cidr_expand" => { arity: 1, handler: :cidr_expand }, "net.cidr_intersects" => { arity: 2, handler: :cidr_intersects }, "net.cidr_is_valid" => { arity: 1, handler: :cidr_is_valid }, "net.cidr_merge" => { arity: 1, handler: :cidr_merge } }.freeze
- IPV4_BITS =
32- IPV6_BITS =
128- V4_MAPPED_OFFSET =
Offset of the IPv4-mapped IPv6 block (::ffff:0:0/96); IPv4 ranges live here in the unified merge space so a containing IPv6 range absorbs them as OPA does.
0xFFFF << 32
Class Method Summary collapse
-
.cidr_contains(cidr_value, other_value) ⇒ Ruby::Rego::BooleanValue
True when
cidr(a CIDR) containsother(an IP or CIDR). -
.cidr_contains_matches(cidrs, addrs) ⇒ Set<Array>
The set of
[cidr_key, addr_key]pairs for which a CIDR in the first collection contains an address/CIDR in the second. -
.cidr_expand(value) ⇒ Set<String>
Expands a CIDR into the set of every address it contains (host bits are masked to the network first, matching OPA).
-
.cidr_intersects(cidr1_value, cidr2_value) ⇒ Ruby::Rego::BooleanValue
True when the two CIDRs overlap.
-
.cidr_is_valid(value) ⇒ Ruby::Rego::BooleanValue
True when
valueis a string in valid CIDR notation (prefix length required). -
.cidr_merge(value) ⇒ Set<String>
Merges a list (array or set) of IP addresses and CIDRs into the smallest set of CIDRs covering exactly the same addresses, matching OPA (a port of Cilium’s algorithm).
-
.register! ⇒ Ruby::Rego::Builtins::BuiltinRegistry
Methods included from RegistryHelpers
Class Method Details
.cidr_contains(cidr_value, other_value) ⇒ Ruby::Rego::BooleanValue
True when cidr (a CIDR) contains other (an IP or CIDR). Undefined if cidr
is not a valid CIDR, other is not a valid IP/CIDR, or either is non-string.
61 62 63 64 65 |
# File 'lib/ruby/rego/builtins/net.rb', line 61 def self.cidr_contains(cidr_value, other_value) cidr = normalize(cidr_arg(cidr_value, "net.cidr_contains")) other = normalize(addr_arg(other_value, "net.cidr_contains")) BooleanValue.new(cidr.include?(other)) end |
.cidr_contains_matches(cidrs, addrs) ⇒ Set<Array>
The set of [cidr_key, addr_key] pairs for which a CIDR in the first collection
contains an address/CIDR in the second. Each operand may be an array (key is the
index), object (key is the key), set or scalar (key is the element itself). A
first-collection element must be a valid CIDR, a second-collection element a valid
IP or CIDR; any non-string or unparseable element yields undefined.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/ruby/rego/builtins/net/contains_matches.rb', line 20 def self.cidr_contains_matches(cidrs, addrs) context = "net.cidr_contains_matches" networks = entries(cidrs) return Set.new if networks.empty? # OPA structurally checks every cidr-side element (it must be a string or a # non-empty array) even with no addresses, but only value-parses — and touches the # address side at all — once the address side is non-empty. validate_structure(networks, context) addresses = entries(addrs) return Set.new if addresses.empty? containment_pairs( networks.map { |key, element| [key, normalize(cidr_from(element, context))] }, addresses.map { |key, element| [key, normalize(addr_from(element, context))] } ) end |
.cidr_expand(value) ⇒ Set<String>
Expands a CIDR into the set of every address it contains (host bits are masked to the network first, matching OPA). The argument must be a valid CIDR (a prefix is required); a non-string, an invalid CIDR, or a block larger than MAX_EXPAND_SIZE yields undefined.
99 100 101 102 103 |
# File 'lib/ruby/rego/builtins/net.rb', line 99 def self.(value) cidr = cidr_arg(value, "net.cidr_expand") (cidr, "net.cidr_expand") Set.new(cidr.to_range.map { |address| normalize(address).to_s }) end |
.cidr_intersects(cidr1_value, cidr2_value) ⇒ Ruby::Rego::BooleanValue
True when the two CIDRs overlap. Aligned CIDR blocks are either nested or disjoint, so they intersect iff one contains the other. Both arguments must be valid CIDRs (a bare IP is undefined), matching OPA.
74 75 76 77 78 |
# File 'lib/ruby/rego/builtins/net.rb', line 74 def self.cidr_intersects(cidr1_value, cidr2_value) first = normalize(cidr_arg(cidr1_value, "net.cidr_intersects")) second = normalize(cidr_arg(cidr2_value, "net.cidr_intersects")) BooleanValue.new(first.include?(second) || second.include?(first)) end |
.cidr_is_valid(value) ⇒ Ruby::Rego::BooleanValue
True when value is a string in valid CIDR notation (prefix length required).
Total over runtime values: a non-string yields false, matching OPA.
:reek:NilCheck
86 87 88 89 90 |
# File 'lib/ruby/rego/builtins/net.rb', line 86 def self.cidr_is_valid(value) return BooleanValue.new(false) unless value.is_a?(StringValue) BooleanValue.new(!parse_cidr(value.value).nil?) end |
.cidr_merge(value) ⇒ Set<String>
Merges a list (array or set) of IP addresses and CIDRs into the smallest set of CIDRs
covering exactly the same addresses, matching OPA (a port of Cilium’s algorithm). A
bare IPv4 address takes its classful default mask; a bare IPv6 address is undefined
(a prefix is required), as is a non-string element, an unparseable element, or a
non-collection operand. IPv4 ranges are merged in their ::ffff: IPv6-mapped block, so
a containing IPv6 range (e.g. ::/0) absorbs them just as OPA does. A CIDR is masked to
its network; a bare address keeps its host form unless it is merged with another.
31 32 33 |
# File 'lib/ruby/rego/builtins/net/cidr_merge.rb', line 31 def self.cidr_merge(value) Set.new(merge_group(merge_operands(value, "net.cidr_merge"))) end |
.register! ⇒ Ruby::Rego::Builtins::BuiltinRegistry
47 48 49 50 51 |
# File 'lib/ruby/rego/builtins/net.rb', line 47 def self.register! registry = BuiltinRegistry.instance register_configured_functions(registry, NET_FUNCTIONS) registry end |