Skip to content

Commit

Permalink
Large refactor for IPMI facts:
Browse files Browse the repository at this point in the history
* Use which method for checking if ipmitools present
* Run command with exec helper
* Simplify loop for channels (IPMI standard channels are 1-11)
* Adds specs to check for correctness
  • Loading branch information
petems committed Jun 30, 2016
1 parent 529a736 commit d7bafed
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 14 deletions.
21 changes: 7 additions & 14 deletions lib/facter/ipmi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,12 @@ class IPMIChannel
public
def initialize channel_nr
@channel_nr = channel_nr
@has_facts = false
end

def load_facts
ipmitool_output = `env - $(which ipmitool 2>/dev/null) lan print #{@channel_nr} 2>&1`
parse_ipmitool_output ipmitool_output
if ipmitool_output =~ /Invalid channel/ then
return false
elsif not @has_facts
Facter.debug(ipmitool_output)
return false
else
return true
if Facter::Util::Resolution.which('ipmitool')
ipmitool_output = Facter::Util::Resolution.exec("ipmitool lan print #{@channel_nr} 2>&1")
parse_ipmitool_output ipmitool_output
end
end

Expand Down Expand Up @@ -80,8 +73,8 @@ def add_ipmi_fact name, value
end
end

channel_nr = 1
while true
break unless IPMIChannel.new(channel_nr).load_facts
channel_nr += 1
channel_array = (1..11).to_a
channel_array.each do | channel |
@channel_nr = channel
IPMIChannel.new(@channel_nr).load_facts
end
179 changes: 179 additions & 0 deletions spec/unit/facter/ipmi_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
require "spec_helper"

describe Facter::Util::Fact do
before {
Facter.clear
File.stubs(:executable?) # Stub all other calls
Facter::Util::Resolution.stubs(:exec) # Catch all other calls
}

describe "ipmi" do
context 'returns details when ipmitool present' do
context 'ipmi_* facts taken from channel 1' do
before do
ipmitool_output = <<-EOS
Set in Progress : Set Complete
Auth Type Support :
Auth Type Enable : Callback :
: User :
: Operator :
: Admin :
: OEM :
IP Address Source : DHCP Address
IP Address : 192.168.0.37
Subnet Mask : 255.255.255.0
MAC Address : 3c:a8:2a:9f:9a:92
SNMP Community String :
BMC ARP Control : ARP Responses Enabled, Gratuitous ARP Disabled
Default Gateway IP : 192.168.0.1
802.1q VLAN ID : Disabled
802.1q VLAN Priority : 0
RMCP+ Cipher Suites : 0,1,2,3
Cipher Suite Priv Max : XuuaXXXXXXXXXXX
: X=Cipher Suite Unused
: c=CALLBACK
: u=USER
: o=OPERATOR
: a=ADMIN
: O=OEM
Bad Password Threshold : Not Available
EOS
Facter::Util::Resolution.expects(:which).at_least(1).with("ipmitool").returns('/usr/bin/ipmitool')
Facter::Util::Resolution.expects(:exec).at_least(1).with("ipmitool lan print 1 2>&1").returns(ipmitool_output)
(2..11).to_a.each do | mocked_channel |
Facter::Util::Resolution.expects(:exec).at_least(1).with("ipmitool lan print #{mocked_channel} 2>&1").returns("Invalid channel: #{mocked_channel}")
end
Facter.fact(:kernel).stubs(:value).returns("Linux")
end
let(:facts) { {:kernel => 'Linux'} }
it do
expect(Facter.value(:ipmi_ipaddress)).to eq("192.168.0.37")
end
it do
expect(Facter.value(:ipmi_ipaddress_source)).to eq("DHCP Address")
end
it do
expect(Facter.value(:ipmi_subnet_mask)).to eq("255.255.255.0")
end
it do
expect(Facter.value(:ipmi_macaddress)).to eq("3c:a8:2a:9f:9a:92")
end
it do
expect(Facter.value(:ipmi_gateway)).to eq("192.168.0.1")
end
end

context 'returns all channels when multiple channels' do
before do
ipmitool_2_output = <<-EOS
Set in Progress : Set Complete
Auth Type Support :
Auth Type Enable : Callback :
: User :
: Operator :
: Admin :
: OEM :
IP Address Source : DHCP Address
IP Address : 192.168.0.22
Subnet Mask : 255.255.255.0
MAC Address : c6:92:00:22:79:f3
SNMP Community String :
BMC ARP Control : ARP Responses Enabled, Gratuitous ARP Disabled
Default Gateway IP : 192.168.0.2
802.1q VLAN ID : Disabled
802.1q VLAN Priority : 0
RMCP+ Cipher Suites : 0,1,2,3
Cipher Suite Priv Max : XuuaXXXXXXXXXXX
: X=Cipher Suite Unused
: c=CALLBACK
: u=USER
: o=OPERATOR
: a=ADMIN
: O=OEM
Bad Password Threshold : Not Available
EOS
ipmitool_3_output = <<-EOS
Set in Progress : Set Complete
Auth Type Support :
Auth Type Enable : Callback :
: User :
: Operator :
: Admin :
: OEM :
IP Address Source : DHCP Address
IP Address : 192.168.0.33
Subnet Mask : 255.255.255.0
MAC Address : 1a:16:97:fb:64:d8
SNMP Community String :
BMC ARP Control : ARP Responses Enabled, Gratuitous ARP Disabled
Default Gateway IP : 192.168.0.3
802.1q VLAN ID : Disabled
802.1q VLAN Priority : 0
RMCP+ Cipher Suites : 0,1,2,3
Cipher Suite Priv Max : XuuaXXXXXXXXXXX
: X=Cipher Suite Unused
: c=CALLBACK
: u=USER
: o=OPERATOR
: a=ADMIN
: O=OEM
Bad Password Threshold : Not Available
EOS
Facter::Util::Resolution.expects(:which).at_least(1).with("ipmitool").returns('/usr/bin/ipmitool')
Facter::Util::Resolution.expects(:exec).at_least(1).with("ipmitool lan print 2 2>&1").returns(ipmitool_2_output)
Facter::Util::Resolution.expects(:exec).at_least(1).with("ipmitool lan print 3 2>&1").returns(ipmitool_3_output)
Facter::Util::Resolution.expects(:exec).at_least(1).with("ipmitool lan print 1 2>&1").returns("Invalid channel: 1")
(4..11).to_a.each do | mocked_channel |
Facter::Util::Resolution.expects(:exec).at_least(1).with("ipmitool lan print #{mocked_channel} 2>&1").returns("Invalid channel: #{mocked_channel}")
end
Facter.fact(:kernel).stubs(:value).returns("Linux")
end
let(:facts) { {:kernel => 'Linux'} }
context 'ipmi2_* facts correct' do
it do
expect(Facter.value(:ipmi2_gateway)).to eq("192.168.0.2")
end
it do
expect(Facter.value(:ipmi2_ipaddress)).to eq("192.168.0.22")
end
it do
expect(Facter.value(:ipmi2_ipaddress_source)).to eq("DHCP Address")
end
it do
expect(Facter.value(:ipmi2_subnet_mask)).to eq("255.255.255.0")
end
it do
expect(Facter.value(:ipmi2_macaddress)).to eq("c6:92:00:22:79:f3")
end
end
context 'ipmi3_* facts correct' do
it do
expect(Facter.value(:ipmi3_gateway)).to eq("192.168.0.3")
end
it do
expect(Facter.value(:ipmi3_ipaddress)).to eq("192.168.0.33")
end
it do
expect(Facter.value(:ipmi3_ipaddress_source)).to eq("DHCP Address")
end
it do
expect(Facter.value(:ipmi3_subnet_mask)).to eq("255.255.255.0")
end
it do
expect(Facter.value(:ipmi3_macaddress)).to eq("1a:16:97:fb:64:d8")
end
end
end
end
end

context 'returns nil when ipmitool not present' do
before do
Facter.fact(:kernel).stubs(:value).returns("Linux")
end
it do
Facter::Util::Resolution.expects(:which).at_least(1).with("ipmitool").returns(false)
expect(Facter.value(:ipmi_ipaddress)).to be_nil
end
end
end

0 comments on commit d7bafed

Please sign in to comment.