diff --git a/lib/puppet/parser/functions/resolve_ipnets.rb b/lib/puppet/parser/functions/resolve_ipnets.rb index 61f408e1ed670ce0a312bb01f69e7a297e275da4..3405867c5020af922b20991fa09ae555bddb15e0 100644 --- a/lib/puppet/parser/functions/resolve_ipnets.rb +++ b/lib/puppet/parser/functions/resolve_ipnets.rb @@ -7,7 +7,8 @@ require 'ipaddr' module Puppet::Parser::Functions def resolve_ipnets__netspec( - addr, ipfamilies, on_error, do_partsort, forcemask) + addr, ipfamilies, on_error, do_partsort, forcemask, + truncate_to_network) familyname_sockaf_map = { :__ANY__ => Socket::AF_UNSPEC, # Internal use @@ -36,7 +37,7 @@ module Puppet::Parser::Functions end if m = /^\[(.*)\]$/.match(hostname) # "[" address "]" - if forcemask && maskspec == "" + if (forcemask && maskspec == "") || truncate_to_network raise(Puppet::ParseError, ("resolve_ipnets(): Can't force a netmask on bracketed" + " address, #{addr}")) @@ -71,6 +72,9 @@ module Puppet::Parser::Functions "Unsupported IP address, #{hostname}")) end end + if truncate_to_network && maskspec != "" + ip = ip.mask(maskspec[1..-1]) + end return [ip.to_s + maskspec] end end @@ -114,7 +118,12 @@ module Puppet::Parser::Functions else family_maskspec = maskspec end - ipaddrs += ips[family].collect {|ip| ip + family_maskspec } + ipaddrs += ips[family].collect { |ip| + if truncate_to_network && family_maskspec != "" + ip = IPAddr.new(ip + family_maskspec).to_s + end + ip + family_maskspec + } end if ipaddrs.length == 0 # Note: this will only show the last error message @@ -144,6 +153,12 @@ module Puppet::Parser::Functions Always add a host mask (/32 or /128) to the result if no mask was specified in the input. + "trunc_to_net" + Truncate the resolved address to the network address based + on the specified netmask. If e.g. "example.org" resolves + to 198.51.100.123, then "example.org/28" will result in + 198.51.100.112/28 with this flag in effect. + "ignoreerrors" If an address cannot be resolved, return it unchanged. @@ -215,6 +230,7 @@ module Puppet::Parser::Functions netspecs,*flags = args ipfamilies = [] forcemask = false + truncate_to_network = false on_error = :fail do_partsort = false # Sort addresses for each input netspec [flags].flatten.each do |f| @@ -223,6 +239,8 @@ module Puppet::Parser::Functions ipfamilies << f when 'forcemask' forcemask = true + when 'trunc_to_net' + truncate_to_network = true when 'ignoreerrors' on_error = :ignore when 'failerrors' @@ -239,7 +257,8 @@ module Puppet::Parser::Functions res = [] [netspecs].flatten.each do |netspec| res += Puppet::Parser::Functions::resolve_ipnets__netspec( - netspec, ipfamilies, on_error, do_partsort, forcemask) + netspec, ipfamilies, on_error, do_partsort, forcemask, + truncate_to_network) end return res.uniq end