From 48e20dedec509921c30c694ea67841ea71904931 Mon Sep 17 00:00:00 2001 From: Wolf Noble Date: Wed, 24 Apr 2013 11:08:57 -0500 Subject: [PATCH 1/3] addition of refactored network_namespaced facts for issue 29 https://github.com/adrienthebo/puppet-network/issues/29 --- lib/facter/network.rb | 35 +++++++++++++++++++++++++++++++++++ lib/facter/util/network.rb | 20 ++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 lib/facter/network.rb create mode 100644 lib/facter/util/network.rb diff --git a/lib/facter/network.rb b/lib/facter/network.rb new file mode 100644 index 00000000..6e46a918 --- /dev/null +++ b/lib/facter/network.rb @@ -0,0 +1,35 @@ +require 'facter' +require 'facter/util/network' +require 'open-uri' +require 'timeout' + +#Public IP +Facter.add("network_public_ip") do + setcode do + url='http://ip-echo.appspot.com' + if Facter::Util::Network.can_connect?(1,url) + open(url, 'User-Agent' => 'Ruby/Facter').read.to_s + end + end +end +#Gateway +my_gw = nil +Facter.add("network_nexthop_ip") do + confine :kernel => :linux + gw_address = Facter::Util::Resolution.exec('/sbin/ip route show 0/0') + if gw_address + my_gw = gw_address.split(/\s+/)[2].match(/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/).to_s + end + setcode { my_gw } +end +if my_gw + fun = Facter::Util::Resolution.exec("/sbin/ip route get #{my_gw}").split("\n")[0] + if fun + Facter.add("network_primary_interface") do + setcode { fun.split(/\s+/)[2].to_s } + end + Facter.add("network_primary_ip") do + setcode { fun.split(/\s+/)[4].to_s } + end + end +end \ No newline at end of file diff --git a/lib/facter/util/network.rb b/lib/facter/util/network.rb new file mode 100644 index 00000000..029ca1ac --- /dev/null +++ b/lib/facter/util/network.rb @@ -0,0 +1,20 @@ +require 'open-uri' +require 'timeout' +#Namespacing +module Facter +module Util +module Network + +def self.can_connect?(wait_sec,url) + Timeout::timeout(wait_sec) do + open(url) + #yay! we can connect! + return true + end + rescue Timeout::Error + # Something raised an exception. It might be good to only catch Timeout::TimeoutError # or whatever the Timeout.timeout call will raise. + return false + end + end +end +end \ No newline at end of file From 586cbc43e0f36b8040dbeca916bc23151511df74 Mon Sep 17 00:00:00 2001 From: Wolf Noble Date: Wed, 1 May 2013 18:21:44 -0500 Subject: [PATCH 2/3] refactor of network_namespaced facts for issue 29 rewrite again to make each fact independent, to allow for unit test coverage. updated timeout to 2 seconds. --- lib/facter/network.rb | 48 ++++++++++++++++++---------- lib/facter/util/network.rb | 20 ------------ spec/unit/network_facts_spec.rb | 56 +++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 36 deletions(-) delete mode 100644 lib/facter/util/network.rb create mode 100644 spec/unit/network_facts_spec.rb diff --git a/lib/facter/network.rb b/lib/facter/network.rb index 6e46a918..74794636 100644 --- a/lib/facter/network.rb +++ b/lib/facter/network.rb @@ -1,35 +1,51 @@ require 'facter' -require 'facter/util/network' require 'open-uri' require 'timeout' #Public IP Facter.add("network_public_ip") do setcode do - url='http://ip-echo.appspot.com' - if Facter::Util::Network.can_connect?(1,url) - open(url, 'User-Agent' => 'Ruby/Facter').read.to_s + Timeout::timeout(2) do + open('http://ip-echo.appspot.com', 'User-Agent' => 'Ruby/Facter').read.match(/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/).to_s end end end + #Gateway -my_gw = nil Facter.add("network_nexthop_ip") do + my_gw = nil confine :kernel => :linux - gw_address = Facter::Util::Resolution.exec('/sbin/ip route show 0/0') - if gw_address - my_gw = gw_address.split(/\s+/)[2].match(/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/).to_s + setcode do + gw_address = Facter::Util::Resolution.exec('/sbin/ip route show 0/0') + if gw_address + my_gw = gw_address.split(/\s+/)[2].match(/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/).to_s + end + my_gw end - setcode { my_gw } end -if my_gw - fun = Facter::Util::Resolution.exec("/sbin/ip route get #{my_gw}").split("\n")[0] - if fun - Facter.add("network_primary_interface") do - setcode { fun.split(/\s+/)[2].to_s } + +#Primary interface +Facter.add("network_primary_interface") do + confine :kernel => :linux + setcode do + gw_address = Facter::Util::Resolution.exec('/sbin/ip route show 0/0') + if gw_address + my_gw = gw_address.split(/\s+/)[2].match(/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/).to_s + fun = Facter::Util::Resolution.exec("/sbin/ip route get #{my_gw}").split("\n")[0] + fun.split(/\s+/)[2].to_s end - Facter.add("network_primary_ip") do - setcode { fun.split(/\s+/)[4].to_s } + end +end + +#Primary IP +Facter.add("network_primary_ip") do + confine :kernel => :linux + setcode do + gw_address = Facter::Util::Resolution.exec('/sbin/ip route show 0/0') + if gw_address + my_gw = gw_address.split(/\s+/)[2].match(/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/).to_s + fun = Facter::Util::Resolution.exec("/sbin/ip route get #{my_gw}").split("\n")[0] + fun.split(/\s+/)[4].to_s end end end \ No newline at end of file diff --git a/lib/facter/util/network.rb b/lib/facter/util/network.rb deleted file mode 100644 index 029ca1ac..00000000 --- a/lib/facter/util/network.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'open-uri' -require 'timeout' -#Namespacing -module Facter -module Util -module Network - -def self.can_connect?(wait_sec,url) - Timeout::timeout(wait_sec) do - open(url) - #yay! we can connect! - return true - end - rescue Timeout::Error - # Something raised an exception. It might be good to only catch Timeout::TimeoutError # or whatever the Timeout.timeout call will raise. - return false - end - end -end -end \ No newline at end of file diff --git a/spec/unit/network_facts_spec.rb b/spec/unit/network_facts_spec.rb new file mode 100644 index 00000000..c4de8afd --- /dev/null +++ b/spec/unit/network_facts_spec.rb @@ -0,0 +1,56 @@ +#!/usr/bin/env rspec +require 'spec_helper' +require 'open-uri' + describe 'network_facts' do + describe 'network_public_ip fact' do + before do + Facter::Util::Resolution.any_instance.stubs(:open).returns(stub(:read => '1.1.1.1')) + end + it "should be our public ip" do + Facter.fact(:network_public_ip).value.should == '1.1.1.1' + end + end + end + describe 'network_nexthop_ip' do + before do + Facter.fact(:kernel).stubs(:value).returns('linux') + end + context 'on a Linux host' do + before do + Facter::Util::Resolution.stubs(:exec).with('/sbin/ip route show 0/0').returns('default via 1.2.3.4 dev eth0') + end + it 'should exec ip and determine the next hop' do + Facter.fact(:network_nexthop_ip).value.should == '1.2.3.4' + end + end + end + describe 'network_primary_interface' do + before do + Facter.fact(:kernel).stubs(:value).returns('linux') + end + context 'on a Linux host' do + before do + Facter::Util::Resolution.stubs(:exec).with('/sbin/ip route show 0/0').returns('default via 1.2.3.4 dev eth0') + Facter::Util::Resolution.stubs(:exec).with('/sbin/ip route get 1.2.3.4').returns('1.2.3.4 dev eth0 src 1.2.3.99\n + cache mtu 1500 advmss 1460 hoplimit 64') + end + it 'should exec ip and determine the primary interface' do + Facter.fact(:network_primary_interface).value.should == 'eth0' + end + end + end + describe 'network_primary_ip' do + before do + Facter.fact(:kernel).stubs(:value).returns('linux') + end + context 'on a Linux host' do + before do + Facter::Util::Resolution.stubs(:exec).with('/sbin/ip route show 0/0').returns('default via 1.2.3.4 dev eth0') + Facter::Util::Resolution.stubs(:exec).with('/sbin/ip route get 1.2.3.4').returns("1.2.3.4 dev eth0 src 1.2.3.99\n + cache mtu 1500 advmss 1460 hoplimit 64") + end + it 'should exec ip and determine the primary ip address' do + Facter.fact(:network_primary_ip).value.should == '1.2.3.99' + end + end + end \ No newline at end of file From ff63f542d6cf45b214614b8b0799640d60bd3afc Mon Sep 17 00:00:00 2001 From: Wolf Noble Date: Thu, 2 May 2013 12:41:06 -0500 Subject: [PATCH 3/3] added comments to express what the facts should provide --- lib/facter/network.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/facter/network.rb b/lib/facter/network.rb index 74794636..6b226529 100644 --- a/lib/facter/network.rb +++ b/lib/facter/network.rb @@ -3,6 +3,7 @@ require 'timeout' #Public IP +# Expected output: The public ipaddress of this node. Facter.add("network_public_ip") do setcode do Timeout::timeout(2) do @@ -12,6 +13,7 @@ end #Gateway +# Expected output: The ip address of the nexthop/default router Facter.add("network_nexthop_ip") do my_gw = nil confine :kernel => :linux @@ -25,6 +27,7 @@ end #Primary interface +# Expected output: The specific interface name that the node uses to communicate with the nexthop Facter.add("network_primary_interface") do confine :kernel => :linux setcode do @@ -38,6 +41,7 @@ end #Primary IP +# Expected output: The ipaddress confugred on the interface that communicates with the nexthop Facter.add("network_primary_ip") do confine :kernel => :linux setcode do