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.
