From c839f749683566e0a822a228806137740c5cbffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20L=C3=B6nnemark?= <ketl@nsc.liu.se> Date: Thu, 10 Nov 2022 16:41:23 +0100 Subject: [PATCH] Convert resolve_ipnets to Puppet 4.x API In Puppet 7, extra methods within a function definition block are no longer permitted when using the 3.x API. Attempting to use such functions aborts catalog compilation with: Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Internal Server Error: org.jruby.exceptions.SecurityError: (SecurityError) Illegal method definition of method 'example_function' in source .../example-module/lib/puppet/parser/functions/example_function.rb on line XXX in legacy function. See https://puppet.com/docs/puppet/latest/functions_refactor_legacy.html for more information We fix the error by updating the only function that has extra methods to use the 4.x API. This change drops support for Puppet 3. https://puppet.com/docs/puppet/7/functions_refactor_legacy.html https://puppet.com/docs/puppet/5.5/functions_legacy.html https://puppet.com/docs/puppet/7/functions_ruby_overview.html --- .../{parser => }/functions/resolve_ipnets.rb | 154 +++++++++--------- 1 file changed, 75 insertions(+), 79 deletions(-) rename lib/puppet/{parser => }/functions/resolve_ipnets.rb (53%) diff --git a/lib/puppet/parser/functions/resolve_ipnets.rb b/lib/puppet/functions/resolve_ipnets.rb similarity index 53% rename from lib/puppet/parser/functions/resolve_ipnets.rb rename to lib/puppet/functions/resolve_ipnets.rb index ee08068..3c4f5b5 100644 --- a/lib/puppet/parser/functions/resolve_ipnets.rb +++ b/lib/puppet/functions/resolve_ipnets.rb @@ -4,7 +4,79 @@ require 'ipaddr' -module Puppet::Parser::Functions +# Lookup IP addresses for network specifications. +# +# - **Parameters** (in order): +# +# :netspecs: A network specification string, or a list of those. +# +# :flags*: (Optional) Zero, one or more flags detailing the behaviour +# of resolve_ipnets(). Each flag is a string. The following flags +# are supported: +# +# :"ipv4": Force lookup of hostnames as IPv4 addresses. +# +# :"ipv6": Force lookup of hostnames as IPv6 addresses. +# +# :"ignoreerrors": If an address cannot be resolved, return it +# unchanged. +# +# :"failerrors": Raise an error if an address cannot be resolved. +# This is the default behaviour. +# +# :"stable": Always return addresses in the same order, regardless +# of in which order the resolver returns them. The order relative +# to the hostnames in the input will be preserved, so if the input +# is ["host-a", "host-b"], then the addresses for host-a will come +# before those for host-b in the return value. +# NOTE: This breaks the address selection order (RFC 3484/6724) +# that the getaddrinfo(3) function implements. +# NOTE: The stable flag does not help aginst e.g. DNS servers +# responding with a different set of addresses each time. +# +# Both "ipv4" and "ipv6" may be specified at the same time, in which +# case both kinds of addresses will be returned, in the order the +# flags were specifed. The function will only return an error if +# neither family resolves. +# +# If no address family is specified, then the order of the addresses +# families will be as determined by the resolver. +# +# A network specification is on the form +# +# [family ":"] hostname ["/" netmask] +# +# where family is either "ipv4" for IPv4, or "ipv6" for IPv6 (just +# "v4" and "v6" also works, for backwards compatibility). For each +# such network, the hostname part will be resolved into an IP address. +# If a protocol family is specified, either explicitly in the network +# specification or as an optional flag parameter to resolve_ipnets(), +# an address of that type will be returned, otherwise some kind of +# default will be chosen. If the protocol family is specified both +# in the netspec and as a flag parameter, they must match, even when +# "ignoreerrors" is in effect. +# +# If the hostname part already is a numeric IP address of the wanted +# family, it will be returned canonicalized. +# +# If the hostname part is enclosed in square brackets ("[]"), it will +# be returned unchanged (but with the brackets removed). This can be +# useful if you want some of the addresses resolved and some not. +# +# If the netmask part is given, that will be included in the result +# unchanged and uninterpreted (including the separating slash), without +# any error checking. The protocol family part is always removed. +# +# The return value will always be a flat list of IP addresses with +# duplicates removed, each address represented as a string (e.g, +# "192.168.1.17" or "2001:db8:4711::1:17/96"). Note that each input +# hostname can result in multiple addresses (although when Ruby 1.8.5 +# is used, only a single address is returned per hostname). +# +# Compatibility note: Older versions returned a value that had the +# same structure as the netspecs parameter; only a single address per +# hostname was returned; and duplicates were not removed. +Puppet::Functions.create_function(:resolve_ipnets) do RESOLVE_IPNETS__IPFAMILIES = { :__ANY__ => Socket::AF_UNSPEC, # Internal use @@ -97,84 +169,8 @@ module Puppet::Parser::Functions end return ipaddrs.collect {|ip| ip + maskspec } end - module_function :resolve_ipnets__netspec - - newfunction(:resolve_ipnets, :type => :rvalue, :doc => '\ - Lookup IP addresses for network specifications. - - - **Parameters** (in order): - - :netspecs: A network specification string, or a list of those. - - :flags*: (Optional) Zero, one or more flags detailing the behaviour - of resolve_ipnets(). Each flag is a string. The following flags - are supported: - - :"ipv4": Force lookup of hostnames as IPv4 addresses. - - :"ipv6": Force lookup of hostnames as IPv6 addresses. - - :"ignoreerrors": If an address cannot be resolved, return it - unchanged. - - :"failerrors": Raise an error if an address cannot be resolved. - This is the default behaviour. - - :"stable": Always return addresses in the same order, regardless - of in which order the resolver returns them. The order relative - to the hostnames in the input will be preserved, so if the input - is ["host-a", "host-b"], then the addresses for host-a will come - before those for host-b in the return value. - NOTE: This breaks the address selection order (RFC 3484/6724) - that the getaddrinfo(3) function implements. - NOTE: The stable flag does not help aginst e.g. DNS servers - responding with a different set of addresses each time. - - Both "ipv4" and "ipv6" may be specified at the same time, in which - case both kinds of addresses will be returned, in the order the - flags were specifed. The function will only return an error if - neither family resolves. - - If no address family is specified, then the order of the addresses - families will be as determined by the resolver. - - A network specification is on the form - - [family ":"] hostname ["/" netmask] - - where family is either "ipv4" for IPv4, or "ipv6" for IPv6 (just - "v4" and "v6" also works, for backwards compatibility). For each - such network, the hostname part will be resolved into an IP address. - If a protocol family is specified, either explicitly in the network - specification or as an optional flag parameter to resolve_ipnets(), - an address of that type will be returned, otherwise some kind of - default will be chosen. If the protocol family is specified both - in the netspec and as a flag parameter, they must match, even when - "ignoreerrors" is in effect. - - If the hostname part already is a numeric IP address of the wanted - family, it will be returned canonicalized. - - If the hostname part is enclosed in square brackets ("[]"), it will - be returned unchanged (but with the brackets removed). This can be - useful if you want some of the addresses resolved and some not. - - If the netmask part is given, that will be included in the result - unchanged and uninterpreted (including the separating slash), without - any error checking. The protocol family part is always removed. - - The return value will always be a flat list of IP addresses with - duplicates removed, each address represented as a string (e.g, - "192.168.1.17" or "2001:db8:4711::1:17/96"). Note that each input - hostname can result in multiple addresses (although when Ruby 1.8.5 - is used, only a single address is returned per hostname). - - Compatibility note: Older versions returned a value that had the - same structure as the netspecs parameter; only a single address per - hostname was returned; and duplicates were not removed. - ') \ - do |args| + def resolve_ipnets(*args) if args.length < 1 raise(Puppet::ParseError, ("resolve_ipnets(): " + @@ -203,7 +199,7 @@ module Puppet::Parser::Functions end res = [] [netspecs].flatten.each do |netspec| - res += Puppet::Parser::Functions::resolve_ipnets__netspec( + res += resolve_ipnets__netspec( netspec, ipfamilies, on_error, do_partsort) end return res.uniq -- GitLab