diff options
-rw-r--r-- | lib/facter/interfaces.rb | 2 | ||||
-rw-r--r-- | lib/facter/ipaddress.rb | 33 | ||||
-rw-r--r-- | lib/facter/ipaddress6.rb | 68 | ||||
-rw-r--r-- | lib/facter/util/ip.rb | 3 | ||||
-rw-r--r-- | spec/fixtures/ifconfig/bsd_ifconfig_all_with_multiple_interfaces | 18 | ||||
-rw-r--r-- | spec/fixtures/ifconfig/darwin_ifconfig_all_with_multiple_interfaces | 23 | ||||
-rw-r--r-- | spec/fixtures/ifconfig/linux_ifconfig_all_with_multiple_interfaces | 19 | ||||
-rw-r--r-- | spec/fixtures/ifconfig/sunos_ifconfig_all_with_multiple_interfaces | 10 | ||||
-rw-r--r-- | spec/spec_helper.rb | 7 | ||||
-rwxr-xr-x | spec/unit/ipaddress6_spec.rb | 36 |
10 files changed, 185 insertions, 34 deletions
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/ipaddress.rb b/lib/facter/ipaddress.rb index a08f26b..08a5dc8 100644 --- a/lib/facter/ipaddress.rb +++ b/lib/facter/ipaddress.rb @@ -19,7 +19,7 @@ Facter.add(:ipaddress) do end Facter.add(:ipaddress) do - confine :kernel => %w{FreeBSD OpenBSD} + confine :kernel => %w{FreeBSD OpenBSD Darwin} setcode do ip = nil output = %x{/sbin/ifconfig} @@ -59,37 +59,6 @@ Facter.add(:ipaddress) do end Facter.add(:ipaddress) do - confine :kernel => %w{darwin} - setcode do - ip = nil - iface = "" - output = %x{/usr/sbin/netstat -rn} - if output =~ /^default\s*\S*\s*\S*\s*\S*\s*\S*\s*(\S*).*/ - iface = $1 - else - warn "Could not find a default route. Using first non-loopback interface" - end - if(iface != "") - output = %x{/sbin/ifconfig #{iface}} - else - output = %x{/sbin/ifconfig} - end - - output.split(/^\S/).each { |str| - if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/ - tmp = $1 - unless tmp =~ /^127\./ - ip = tmp - break - end - end - } - - ip - end -end - -Facter.add(:ipaddress) do confine :kernel => %w{AIX} setcode do ip = nil diff --git a/lib/facter/ipaddress6.rb b/lib/facter/ipaddress6.rb new file mode 100644 index 0000000..547d636 --- /dev/null +++ b/lib/facter/ipaddress6.rb @@ -0,0 +1,68 @@ +# Cody Herriges <c.a.herriges@gmail.com> +# +# Used the ipaddress fact that is already part of +# Facter as a template. + +# 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 + output = Facter::Util::Resolution.exec('/sbin/ifconfig -a') + ip = nil + + output.scan(/inet6 ((?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/).each do |str| + str = str.to_s + unless str =~ /fe80.*/ or str == "::1" + ip = str + break + end + end + + ip + end +end + diff --git a/lib/facter/util/ip.rb b/lib/facter/util/ip.rb index 62d50a4..23eeb9c 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, :"gnu/kfreebsd"], :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})/ }, diff --git a/spec/fixtures/ifconfig/bsd_ifconfig_all_with_multiple_interfaces b/spec/fixtures/ifconfig/bsd_ifconfig_all_with_multiple_interfaces new file mode 100644 index 0000000..d5bff49 --- /dev/null +++ b/spec/fixtures/ifconfig/bsd_ifconfig_all_with_multiple_interfaces @@ -0,0 +1,18 @@ +bge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 + options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM> + ether 00:0b:db:93:09:67 + inet 131.252.208.203 netmask 0xffffff00 broadcast 131.252.208.255 + inet6 fe80::20b:dbff:fe93:967%bge0 prefixlen 64 scopeid 0x1 + inet6 2610:10:20:208:20b:dbff:fe93:967 prefixlen 64 autoconf + media: Ethernet autoselect (1000baseT <full-duplex>) + status: active +bge1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500 + options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM> + ether 00:0b:db:93:09:68 + media: Ethernet autoselect (none) + status: no carrier +lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384 + options=3<RXCSUM,TXCSUM> + inet 127.0.0.1 netmask 0xff000000 + inet6 ::1 prefixlen 128 + inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3 diff --git a/spec/fixtures/ifconfig/darwin_ifconfig_all_with_multiple_interfaces b/spec/fixtures/ifconfig/darwin_ifconfig_all_with_multiple_interfaces new file mode 100644 index 0000000..a55999c --- /dev/null +++ b/spec/fixtures/ifconfig/darwin_ifconfig_all_with_multiple_interfaces @@ -0,0 +1,23 @@ +lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 + inet6 ::1 prefixlen 128 + inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 + inet 127.0.0.1 netmask 0xff000000 +gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280 +stf0: flags=0<> mtu 1280 +en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 + ether 00:23:32:d5:ee:34 + inet6 fe80::223:32ff:fed5:ee34%en0 prefixlen 64 scopeid 0x4 + inet6 2610:10:20:209:223:32ff:fed5:ee34 prefixlen 64 autoconf + inet 131.252.209.140 netmask 0xffffff00 broadcast 131.252.209.255 + media: autoselect (100baseTX <full-duplex>) + status: active +en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 + ether 00:11:33:22:55:44 + inet6 fe80::211:33ff:fe22:5544%en1 prefixlen 64 scopeid 0x5 + inet 131.252.246.129 netmask 0xfffffe00 broadcast 131.252.247.255 + media: autoselect + status: active +fw0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 4078 + lladdr 00:23:32:ff:fe:d5:ee:34 + media: autoselect <full-duplex> + status: inactive diff --git a/spec/fixtures/ifconfig/linux_ifconfig_all_with_multiple_interfaces b/spec/fixtures/ifconfig/linux_ifconfig_all_with_multiple_interfaces new file mode 100644 index 0000000..d944694 --- /dev/null +++ b/spec/fixtures/ifconfig/linux_ifconfig_all_with_multiple_interfaces @@ -0,0 +1,19 @@ +eth0 Link encap:Ethernet HWaddr 00:12:3f:be:22:01 + inet addr:131.252.209.153 Bcast:131.252.209.255 Mask:255.255.255.0 + inet6 addr: 2610:10:20:209:212:3fff:febe:2201/64 Scope:Global + inet6 addr: fe80::212:3fff:febe:2201/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:20793317 errors:0 dropped:0 overruns:0 frame:0 + TX packets:19583281 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:1723593481 (1.7 GB) TX bytes:283377282 (283.3 MB) + Interrupt:16 + +lo Link encap:Local Loopback + inet addr:127.0.0.1 Mask:255.0.0.0 + inet6 addr: ::1/128 Scope:Host + UP LOOPBACK RUNNING MTU:16436 Metric:1 + RX packets:31809 errors:0 dropped:0 overruns:0 frame:0 + TX packets:31809 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:0 + RX bytes:2075836 (2.0 MB) TX bytes:2075836 (2.0 MB) diff --git a/spec/fixtures/ifconfig/sunos_ifconfig_all_with_multiple_interfaces b/spec/fixtures/ifconfig/sunos_ifconfig_all_with_multiple_interfaces new file mode 100644 index 0000000..c30efe0 --- /dev/null +++ b/spec/fixtures/ifconfig/sunos_ifconfig_all_with_multiple_interfaces @@ -0,0 +1,10 @@ +lo0: flags=2001000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4,VIRTUAL> mtu 8232 index 1 + inet 127.0.0.1 netmask ff000000 +bge0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2 + inet 131.252.209.59 netmask ffffff00 broadcast 131.252.209.255 +lo0: flags=2002000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv6,VIRTUAL> mtu 8252 index 1 + inet6 ::1/128 +bge0: flags=2000841<UP,RUNNING,MULTICAST,IPv6> mtu 1500 index 2 + inet6 fe80::203:baff:fe27:a7c/10 +bge0:1: flags=2080841<UP,RUNNING,MULTICAST,ADDRCONF,IPv6> mtu 1500 index 2 + inet6 2610:10:20:209:203:baff:fe27:a7c/64 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d9db445..28e7b72 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -14,5 +14,10 @@ require 'facter' Dir["#{dir}/monkey_patches/*.rb"].map { |file| require file } RSpec.configure do |config| - config.mock_with :mocha + config.mock_with :mocha + + # Ensure that we don't accidentally cache between test cases. + config.before :each do + Facter.clear + end end diff --git a/spec/unit/ipaddress6_spec.rb b/spec/unit/ipaddress6_spec.rb new file mode 100755 index 0000000..d507023 --- /dev/null +++ b/spec/unit/ipaddress6_spec.rb @@ -0,0 +1,36 @@ +#!/usr/bin/env ruby + +$basedir = File.expand_path(File.dirname(__FILE__) + '/..') +require File.join($basedir, 'spec_helper') + +require 'facter' + +def ifconfig_fixture(filename) + ifconfig = File.new(File.join($basedir, 'fixtures', 'ifconfig', filename)).read +end + +describe "IPv6 address fact" do + it "should return ipaddress6 information for Darwin" do + Facter::Util::Resolution.stubs(:exec).with('uname -s').returns('Darwin') + Facter::Util::Resolution.stubs(:exec).with('/sbin/ifconfig -a'). + returns(ifconfig_fixture('darwin_ifconfig_all_with_multiple_interfaces')) + + Facter.value(:ipaddress6).should == "2610:10:20:209:223:32ff:fed5:ee34" + end + + it "should return ipaddress6 information for Linux" do + Facter::Util::Resolution.stubs(:exec).with('uname -s').returns('Linux') + Facter::Util::Resolution.stubs(:exec).with('/sbin/ifconfig'). + returns(ifconfig_fixture('linux_ifconfig_all_with_multiple_interfaces')) + + Facter.value(:ipaddress6).should == "2610:10:20:209:212:3fff:febe:2201" + end + + it "should return ipaddress6 information for Solaris" do + Facter::Util::Resolution.stubs(:exec).with('uname -s').returns('SunOS') + Facter::Util::Resolution.stubs(:exec).with('/usr/sbin/ifconfig -a'). + returns(ifconfig_fixture('sunos_ifconfig_all_with_multiple_interfaces')) + + Facter.value(:ipaddress6).should == "2610:10:20:209:203:baff:fe27:a7c" + end +end |