Skip to content

Commit 0e514b8

Browse files
author
Jeff McCune
committedDec 18, 2012
(#15001) Add spec examples for ipaddress fact
Without this patch we don't have an example behaviors for the ipaddress fact. This patch addresses the problem by adding two examples for the facts parsing the output of ifconfig. These examples slightly refactor the ipaddress fact confined to Linux in order to take advantage of the stubbed method returning the output of the ifconfig command. Fixture data for ifconfig output is included for Ubuntu 12.04 and Fedora 17. The notable difference with Fedora 17 is that Net Tools 1.60 removes the "addr" substring from the interface description.
1 parent ae34893 commit 0e514b8

File tree

5 files changed

+82
-12
lines changed

5 files changed

+82
-12
lines changed
 

‎lib/facter/ipaddress.rb

+7-12
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,18 @@
2222
# checking this is a useful IP address.
2323
#
2424

25+
require 'facter/util/ip'
26+
2527
Facter.add(:ipaddress) do
2628
confine :kernel => :linux
2729
setcode do
2830
ip = nil
29-
output = %x{/sbin/ifconfig 2>/dev/null}
30-
31-
output.split(/^\S/).each { |str|
32-
if str =~ /inet (?:addr:)?([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
33-
tmp = $1
34-
unless tmp =~ /^127\./
35-
ip = tmp
36-
break
37-
end
31+
if output = Facter::Util::IP.get_ifconfig
32+
regexp = /inet (?:addr:)?([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
33+
if match = regexp.match(output)
34+
match[1] unless /^127/.match(match[1])
3835
end
39-
}
40-
41-
ip
36+
end
4237
end
4338
end
4439

‎lib/facter/util/ip.rb

+8
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ def self.get_all_interface_output
9696
output
9797
end
9898

99+
##
100+
# get_ifconfig simply delegates to the ifconfig command.
101+
#
102+
# @return [String] the output of `/sbin/ifconfig 2>/dev/null` or nil
103+
def self.get_ifconfig
104+
Facter::Util::Resolution.exec("/sbin/ifconfig 2>/dev/null")
105+
end
106+
99107
##
100108
# hpux_netstat_in is a delegate method that allows us to stub netstat -in
101109
# without stubbing exec.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
em1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
2+
inet 131.252.209.153 netmask 255.255.255.0 broadcast 192.168.76.255
3+
inet6 2610:10:20:209:212:3fff:febe:2201 prefixlen 128 scopeid 0x0<global>
4+
inet6 fe80::221:ccff:fe4b:297d prefixlen 64 scopeid 0x20<link>
5+
ether 00:21:cc:4b:29:7d txqueuelen 1000 (Ethernet)
6+
RX packets 27222144 bytes 31247414760 (29.1 GiB)
7+
RX errors 0 dropped 0 overruns 0 frame 0
8+
TX packets 10259038 bytes 7784519352 (7.2 GiB)
9+
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
10+
device interrupt 20 memory 0xd2600000-d2620000
11+
12+
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 16436
13+
inet 127.0.0.1 netmask 255.0.0.0
14+
inet6 ::1 prefixlen 128 scopeid 0x10<host>
15+
loop txqueuelen 0 (Local Loopback)
16+
RX packets 257371 bytes 37104110 (35.3 MiB)
17+
RX errors 0 dropped 0 overruns 0 frame 0
18+
TX packets 257371 bytes 37104110 (35.3 MiB)
19+
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
eth0 Link encap:Ethernet HWaddr 42:01:0a:57:50:6e
2+
inet addr:10.87.80.110 Bcast:10.87.80.110 Mask:255.255.255.255
3+
UP BROADCAST RUNNING MULTICAST MTU:1460 Metric:1
4+
RX packets:1609444 errors:0 dropped:0 overruns:0 frame:0
5+
TX packets:1479569 errors:0 dropped:0 overruns:0 carrier:0
6+
collisions:0 txqueuelen:1000
7+
RX bytes:673812693 (673.8 MB) TX bytes:221186872 (221.1 MB)
8+
9+
lo Link encap:Local Loopback
10+
inet addr:127.0.0.1 Mask:255.0.0.0
11+
UP LOOPBACK RUNNING MTU:16436 Metric:1
12+
RX packets:5435415 errors:0 dropped:0 overruns:0 frame:0
13+
TX packets:5435415 errors:0 dropped:0 overruns:0 carrier:0
14+
collisions:0 txqueuelen:0
15+
RX bytes:734540224 (734.5 MB) TX bytes:734540224 (734.5 MB)
16+

‎spec/unit/ipaddress_spec.rb

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#! /usr/bin/env ruby
2+
3+
require 'spec_helper'
4+
require 'facter/util/ip'
5+
6+
shared_examples_for "ifconfig output" do |platform, address, fixture|
7+
it "correctly on #{platform}" do
8+
Facter::Util::IP.stubs(:get_ifconfig).returns(my_fixture_read(fixture))
9+
subject.value.should == address
10+
end
11+
end
12+
13+
RSpec.configure do |config|
14+
config.alias_it_should_behave_like_to :example_behavior_for, "parses"
15+
end
16+
17+
describe "The ipaddress fact" do
18+
subject do
19+
Facter.collection.loader.load(:ipaddress)
20+
Facter.fact(:ipaddress)
21+
end
22+
context "on Linux" do
23+
before :each do
24+
Facter.fact(:kernel).stubs(:value).returns("Linux")
25+
end
26+
27+
example_behavior_for "ifconfig output",
28+
"Ubuntu 12.04", "10.87.80.110", "ifconfig_ubuntu_1204.txt"
29+
example_behavior_for "ifconfig output",
30+
"Fedora 17", "131.252.209.153", "ifconfig_net_tools_1.60.txt"
31+
end
32+
end

2 commit comments

Comments
 (2)

jgn commented on Mar 15, 2013

@jgn

I've been trying to isolate a problem on one of my systems, and the refactoring here for linux seems wrong.

Here is the documentation (at http://docs.puppetlabs.com/facter/1.6/core_facts.html#ipaddress):

On the Unixes does an ifconfig, and returns the first non 127.0.0.0/8 subnetted IP it finds.

Here is an example of the output from my ifconfig command:

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:9031461 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9031461 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:3205490447 (2.9 GiB)  TX bytes:3205490447 (2.9 GiB)

venet0    Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:127.0.0.1  P-t-P:127.0.0.1  Bcast:0.0.0.0  Mask:255.255.255.255
          UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1
          RX packets:38161277 errors:0 dropped:0 overruns:0 frame:0
          TX packets:24601924 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:3847964603 (3.5 GiB)  TX bytes:5770630041 (5.3 GiB)

venet0:1  Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.0.222.20  P-t-P:10.0.222.20  Bcast:10.0.222.20  Mask:255.255.255.255
          UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1

Notice that the value of ipaddress that is supposed to be captured is: 10.0.222.20

Now look at the refactoring of the ipaddress fact for Linux.

BEFORE, it split the output and checked every line for a regexp match; and then ignored matches for the loop back address (127...).

AFTER, there is no split.

This means that ONLY the first match would EVER be considered. There is no way that the refactored code can get to the inet address on venet0:1 (in my example).

Here's an example irb session following the code:

irb(main):001:0> output = `ifconfig`; nil
irb(main):002:0> regexp = /inet (?:addr:)?([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
irb(main):003:0> match = regexp.match(output)
=> #<MatchData "inet addr:127.0.0.1" 1:"127.0.0.1">
irb(main):004:0> match[1] unless /^127/.match(match[1])
=> nil

You will see this failure more clearly if you add another fixture for ipconfig output (for example, used what I've pasted in above).

In your fixture, the very first interface has a non-127.0.0.1 address. Here's the fixture:

eth0      Link encap:Ethernet  HWaddr 42:01:0a:57:50:6e
          inet addr:10.87.80.110  Bcast:10.87.80.110  Mask:255.255.255.255
          UP BROADCAST RUNNING MULTICAST  MTU:1460  Metric:1
          RX packets:1609444 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1479569 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:673812693 (673.8 MB)  TX bytes:221186872 (221.1 MB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:5435415 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5435415 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:734540224 (734.5 MB)  TX bytes:734540224 (734.5 MB)

jeffmccune commented on Mar 20, 2013

@jeffmccune

@jgn Thanks for taking the time to troubleshoot this issue. Would you mind submitting a pull request that fixes this problem for you? If not, could you file an issue at http://projects.puppetlabs.com/projects/facter and add me as a watcher?

Thanks,
-Jeff

Please sign in to comment.