FYI, this patch is associated with ticket #2270 (
http://projects.puppetlabs.com/issues/2270)

On Sat, Feb 5, 2011 at 7:16 AM, Cody Herriges <[email protected]>wrote:

>  The following patch provides an ipaddress6 fact to report IP addresses
>  that follow the IPv6 standard, RFC 2460.  Basic code structure was modeled
>  after the already current ipaddress facts available in facter core and are
>  not intended to make large behaviour changes to the way facter functions
> when
>  discovering IP addresses.  Intial support is only for FreeBSD, Linux,
> SunOS,
>  and Darwin.  The only platforms I had available for testing at the time,
> more
>  support coming soon.
>
>  Another minor change in the patch is a replacement of %x with the
>  Facter::Util::Resolution.exec method for ease of rspec mocking.
> ---
>  lib/facter/interfaces.rb |    2 +-
>  lib/facter/ipaddress6.rb |  130
> ++++++++++++++++++++++++++++++++++++++++++++++
>  lib/facter/util/ip.rb    |   19 ++++---
>  3 files changed, 142 insertions(+), 9 deletions(-)
>  create mode 100644 lib/facter/ipaddress6.rb
>
> diff --git a/lib/facter/interfaces.rb b/lib/facter/interfaces.rb
> index 1239215..4fbaef1 100644
> --- a/lib/facter/interfaces.rb
> +++ b/lib/facter/interfaces.rb
> @@ -22,7 +22,7 @@ Facter::Util::IP.get_interfaces.each do |interface|
>     # Make a fact for each detail of each interface.  Yay.
>     #   There's no point in confining these facts, since we wouldn't be
> able to create
>     # them if we weren't running on a supported platform.
> -    %w{ipaddress macaddress netmask}.each do |label|
> +    %w{ipaddress ipaddress6 macaddress netmask}.each do |label|
>         Facter.add(label + "_" + Facter::Util::IP.alphafy(interface)) do
>             setcode do
>                 Facter::Util::IP.get_interface_value(interface, label)
> diff --git a/lib/facter/ipaddress6.rb b/lib/facter/ipaddress6.rb
> new file mode 100644
> index 0000000..30d0e74
> --- /dev/null
> +++ b/lib/facter/ipaddress6.rb
> @@ -0,0 +1,130 @@
> +# Cody Herriges <[email protected]>
> +#
> +# Used the ipaddress fact that is already part of
> +# Facter as a template.
> +
> +
> +# Uses ruby's own resolv class which queries DNS and /etc/hosts.
> +# The closest thing to a default/primary IPv6 addresses is
> +# assumed to be the AAAA that you have published via DNS or
> +# an /etc/host entry.
> +Facter.add(:ipaddress6, :timeout => 2) do
> +  setcode do
> +    require 'resolv'
> +
> +    begin
> +      if fqdn = Facter.value(:fqdn)
> +        ip = nil
> +        Resolv.getaddresses(fqdn).each { |str|
> +          str = str.to_s
> +          if str =~ /(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4}/ and str
> != "::1"
> +            ip = str
> +          end
> +        }
> +
> +      ip
> +
> +      else
> +        nil
> +      end
> +      rescue Resolv::ResolvError
> +        nil
> +      rescue NoMethodError # i think this is a bug in resolv.rb?
> +        nil
> +    end
> +  end
> +end
> +
> +# Uses the OS' host command to do a DNS lookup.
> +Facter.add(:ipaddress6, :timeout => 2) do
> +  setcode do
> +  if fqdn = Facter.value(:fqdn)
> +    ip = nil
> +    host = nil
> +    if host = Facter::Util::Resolution.exec("host -t AAAA #{fqdn}")
> +
>  host.scan(/((?>[0-9,a-f,A-F]{0,4}\:{1,2})+[0-9,a-f,A-F]{0,4}&)/).each {
> |str|
> +      str = str.to_s
> +      unless str =~ /fe80.*/ or str == "::1"
> +       ip = str
> +      end
> +    }
> +    else
> +      nil
> +    end
> +    ip
> +  else
> +    nil
> +  end
> +  end
> +end
> +
> +# OS dependant code that parses the output of various networking
> +# tools and currently not very intelligent. Returns the first
> +# non-loopback and non-linklocal address found in the ouput unless
> +# a default route can be mapped to a routeable interface. Guessing
> +# an interface is currently only possible with BSD type systems
> +# to many assumptions have to be made on other platforms to make
> +# this work with the current code. Most code ported or modeled
> +# after the ipaddress fact for the sake of similar functionality
> +# and familiar mechanics.
> +Facter.add(:ipaddress6) do
> +  confine :kernel => :linux
> +  setcode do
> +    ip = nil
> +    output = Facter::Util::Resolution.exec("/sbin/ifconfig")
> +
> +    output.scan(/inet6 addr:
> ((?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/).each { |str|
> +      str = str.to_s
> +      unless str =~ /fe80.*/ or str == "::1"
> +        ip = str
> +      end
> +    }
> +
> +    ip
> +
> +  end
> +end
> +
> +Facter.add(:ipaddress6) do
> +  confine :kernel => %w{SunOS}
> +  setcode do
> +    output = Facter::Util::Resolution.exec("/usr/sbin/ifconfig -a")
> +    ip = nil
> +
> +    output.scan(/inet6
> ((?>[0-9,a-f,A-F]*\:{0,2})+[0-9,a-f,A-F]{0,4})/).each { |str|
> +      str = str.to_s
> +      unless str =~ /fe80.*/ or str == "::1"
> +        ip = str
> +      end
> +    }
> +
> +    ip
> +
> +  end
> +end
> +
> +Facter.add(:ipaddress6) do
> +  confine :kernel => %w{Darwin FreeBSD OpenBSD}
> +  setcode do
> +    interout = Facter::Util::Resolution.exec("/usr/sbin/netstat -rn -f
> inet6")
> +    interface =
> interout.scan(/^default\s+fe80\S+\s+[A-Z]+\s+\d\s+\d+\s+([a-z]+\d)/).to_s
> +    if interface != ''
> +      output = Facter::Util::Resolution.exec("/sbin/ifconfig
> #{interface}")
> +    else
> +      puts "Unable to find a default route interface, using first
> non-loopback address"
> +      output = Facter::Util::Resolution.exec("/sbin/ifconfig -a")
> +    end
> +    ip = nil
> +
> +    output.scan(/inet6
> ((?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/).each { |str|
> +      str = str.to_s
> +      unless str =~ /fe80.*/ or str == "::1"
> +        ip = str
> +      end
> +      }
> +
> +      ip
> +
> +  end
> +end
> +
> diff --git a/lib/facter/util/ip.rb b/lib/facter/util/ip.rb
> index 366303c..50fae51 100644
> --- a/lib/facter/util/ip.rb
> +++ b/lib/facter/util/ip.rb
> @@ -6,17 +6,20 @@ module Facter::Util::IP
>     REGEX_MAP = {
>         :linux => {
>             :ipaddress  => /inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
> +            :ipaddress6 => /inet6 addr:
> ((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
>             :macaddress =>
> /(?:ether|HWaddr)\s+(\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/,
>             :netmask    => /Mask:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
>         },
>         :bsd   => {
>             :aliases    => [:openbsd, :netbsd, :freebsd, :darwin],
>             :ipaddress  => /inet\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
> +            :ipaddress6 => /inet6
> ((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
>             :macaddress =>
> /(?:ether|lladdr)\s+(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/,
>             :netmask    => /netmask\s+0x(\w{8})/
>         },
>         :sunos => {
>             :ipaddress  => /inet\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
> +            :ipaddress6 => /inet6
> ((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
>             :macaddress =>
> /(?:ether|lladdr)\s+(\w?\w:\w?\w:\w?\w:\w?\w:\w?\w:\w?\w)/,
>             :netmask    => /netmask\s+(\w{8})/
>         },
> @@ -62,11 +65,11 @@ module Facter::Util::IP
>     def self.get_all_interface_output
>         case Facter.value(:kernel)
>         when 'Linux', 'OpenBSD', 'NetBSD', 'FreeBSD', 'Darwin'
> -            output = %x{/sbin/ifconfig -a}
> +            output = Facter::Util::Resolution.exec("/sbin/ifconfig -a")
>         when 'SunOS'
> -            output = %x{/usr/sbin/ifconfig -a}
> +            output = Facter::Util::Resolution.exec("/usr/sbin/ifconfig
> -a")
>         when 'HP-UX'
> -            output = %x{/bin/netstat -i}
> +            output = Facter::Util::Resolution.exec("/bin/netstat -i")
>         end
>         output
>     end
> @@ -75,13 +78,13 @@ module Facter::Util::IP
>         output = ""
>         case Facter.value(:kernel)
>         when 'Linux', 'OpenBSD', 'NetBSD', 'FreeBSD', 'Darwin'
> -            output = %x{/sbin/ifconfig #{interface}}
> +            output = Facter::Util::Resolution.exec("/sbin/ifconfig
> #{interface}")
>         when 'SunOS'
> -            output = %x{/usr/sbin/ifconfig #{interface}}
> +            output = Facter::Util::Resolution.exec("/usr/sbin/ifconfig
> #{interface}")
>         when 'HP-UX'
>            mac = ""
> -           ifc = %x{/usr/sbin/ifconfig #{interface}}
> -           %x{/usr/sbin/lanscan}.scan(/(\dx\S+).*UP\s+(\w+\d+)/).each {|i|
> mac = i[0] if i.include?(interface) }
> +           ifc = Facter::Util::Resolution.exec("/usr/sbin/ifconfig
> #{interface}")
> +
> Facter::Util::Resolution.exec("/usr/sbin/lanscan").scan(/(\dx\S+).*UP\s+(\w+\d+)/).each
> {|i| mac = i[0] if i.include?(interface) }
>            mac = mac.sub(/0x(\S+)/,'\1').scan(/../).join(":")
>            output = ifc + "\n" + mac
>         end
> @@ -105,7 +108,7 @@ module Facter::Util::IP
>             return nil
>         end
>         regex = /SLAVE[,>].* (bond[0-9]+)/
> -            ethbond = regex.match(%x{/sbin/ip link show #{interface}})
> +            ethbond = regex.match(Facter::Util::Resolution.exec("/sbin/ip
> link show #{interface}"))
>         if ethbond
>             device = ethbond[1]
>         else
> --
> 1.7.4
>
> --
> You received this message because you are subscribed to the Google Groups
> "Puppet Developers" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/puppet-dev?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to