Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fact ipmitool fru #75

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions lib/facter/ipmitool.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

Facter.add(:ipmitool, type: :aggregate) do
# https://puppet.com/docs/puppet/latest/fact_overview.html
confine kernel: 'Linux'
confine is_virtual: false
# TODO: consider confining based on which
# this has the side affect that the ipmitool fact and ipmitool_mc_info facts would be Nil
# if ipmi is not present instead of the curent values of
# ipmitool: {"fru"=>{}, "mc_info"=>{"IPMI_Puppet_Service_Recommend"=>"stopped"}}
# ipmitool_mc_info: {"IPMI_Puppet_Service_Recommend"=>"stopped"}
# confine do
# Facter::Util::Resolution.which('ipmitool')
# end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if this is something worth pursuing or if you just want me to drop the comment.


ipmitool_present = Facter::Util::Resolution.which('ipmitool')
chunk(:fru) do
retval = { fru: {} }
if ipmitool_present
ipmitool_output = Facter::Util::Resolution.exec('ipmitool fru print 0 2>/dev/null')
ipmitool_output.each_line do |line|
next unless line.include?(':')

info = line.split(':', 2)
next if info[1].strip.empty?

key = info[0].strip.tr("\s", '_').downcase
retval[:fru][key] = info[1].strip
end
end
retval
end

chunk(:mc_info) do
retval = { mc_info: { 'IPMI_Puppet_Service_Recommend' => 'stopped' } }
if ipmitool_present
ipmitool_output = Facter::Util::Resolution.exec('ipmitool mc info 2>/dev/null')

ipmitool_output.each_line do |line|
info = line.split(':')
retval[:mc_info][info[0].strip] = info[1].strip if info.length == 2 && (info[1].strip != '')
end
retval[:mc_info]['IPMI_Puppet_Service_Recommend'] = 'running' if retval[:mc_info].fetch('Device Available', 'no') == 'yes'
end
retval
end
end
17 changes: 2 additions & 15 deletions lib/facter/ipmitool_mc_info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,8 @@
Facter.add(:ipmitool_mc_info) do
# https://puppet.com/docs/puppet/latest/fact_overview.html
confine kernel: 'Linux'

retval = {}
retval['IPMI_Puppet_Service_Recommend'] = 'stopped'

if Facter::Util::Resolution.which('ipmitool')
ipmitool_output = Facter::Util::Resolution.exec('ipmitool mc info 2>/dev/null')

ipmitool_output.each_line do |line|
info = line.split(':')
retval[info[0].strip] = info[1].strip if info.length == 2 && (info[1].strip != '')
end
retval['IPMI_Puppet_Service_Recommend'] = 'running' if retval.fetch('Device Available', 'no') == 'yes'
end

setcode do
retval
ipmitool_value = Facter.value('ipmitool')
ipmitool_value.nil? ? { 'IPMI_Puppet_Service_Recommend' => 'stopped' } : ipmitool_value[:mc_info]
end
end
105 changes: 105 additions & 0 deletions spec/unit/facter/ipmitool.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# frozen_string_literal: true

require 'spec_helper'
require 'facter'

describe 'ipmitool', type: :fact do
subject(:fact) { Facter.fact(:ipmitool) }

before do
# perform any action that should be run before every test
Facter.clear
Facter.fact(:kernel).stubs(:value).returns('Linux')
Facter.fact(:is_virtual).stubs(:value).returns(false)
end

let(:fru_output) do
<<~OUTPUT
Board Mfg Date : Tue Mar 3 21:43:00 2015
Board Mfg : DELL
Board Product : PowerEdge R220
Board Serial : 000000
Board Part Number : 0DRXF5A04
Product Manufacturer : DELL
Product Name : Test
Product Extra : 000000
OUTPUT
end
let(:mc_output) do
<<~SAMPLE
Device ID : 32
Device Revision : 1
Firmware Revision : 2.49
IPMI Version : 2.0
Manufacturer ID : 10876
Manufacturer Name : Supermicro
Product ID : 43707 (0xaabb)
Product Name : Unknown (0xAABB)
Device Available : yes
Provides Device SDRs : no
Additional Device Support :
Sensor Device
SDR Repository Device
SEL Device
FRU Inventory Device
IPMB Event Receiver
IPMB Event Generator
Chassis Device
Aux Firmware Rev Info :
0x00
0x00
0x00
0x00
SAMPLE
end

context 'with no ipmitool' do
before do
Facter::Util::Resolution.expects(:which).at_least(1).with('ipmitool').returns(nil)
Facter::Util::Resolution.expects(:exec).with('ipmitool mc info 2>/dev/null').never
Facter::Util::Resolution.expects(:exec).with('ipmitool fru print 0 2>/dev/null').never
end

it do
expect(fact.value).to eq({ 'fru' => {}, 'mc_info' => { 'IPMI_Puppet_Service_Recommend' => 'stopped' } })
end
end

context 'with detailed output' do
before do
Facter::Util::Resolution.expects(:which).with('ipmitool').returns(true)
Facter::Util::Resolution.expects(:exec).with('ipmitool mc info 2>/dev/null').returns(mc_output)
Facter::Util::Resolution.expects(:exec).with('ipmitool fru print 0 2>/dev/null').returns(fru_output)
end

it do
expect(fact.value).to eq(
{
'mc_info' => {
'Device ID' => '32',
'Device Revision' => '1',
'Firmware Revision' => '2.49',
'IPMI Version' => '2.0',
'IPMI_Puppet_Service_Recommend' => 'running',
'Manufacturer ID' => '10876',
'Manufacturer Name' => 'Supermicro',
'Product ID' => '43707 (0xaabb)',
'Product Name' => 'Unknown (0xAABB)',
'Device Available' => 'yes',
'Provides Device SDRs' => 'no',
},
'fru' => {
'board_mfg_date' => 'Tue Mar 3 21:43:00 2015',
'board_mfg' => 'DELL',
'board_product' => 'PowerEdge R220',
'board_serial' => '000000',
'board_part_number' => '0DRXF5A04',
'product_manufacturer' => 'DELL',
'product_name' => 'Test',
'product_extra' => '000000',
}
}
)
end
end
end
54 changes: 21 additions & 33 deletions spec/unit/facter/ipmitool_mc_info_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,12 @@
before do
# perform any action that should be run before every test
Facter.clear
Facter.fact(:kernel).stubs(:value).returns('Linux')
end

let(:detailed_output) do
<<~SAMPLE
Device ID : 32
Device Revision : 1
Firmware Revision : 2.49
IPMI Version : 2.0
Manufacturer ID : 10876
Manufacturer Name : Supermicro
Product ID : 43707 (0xaabb)
Product Name : Unknown (0xAABB)
Device Available : yes
Provides Device SDRs : no
Additional Device Support :
Sensor Device
SDR Repository Device
SEL Device
FRU Inventory Device
IPMB Event Receiver
IPMB Event Generator
Chassis Device
Aux Firmware Rev Info :
0x00
0x00
0x00
0x00
SAMPLE
end

context 'with no ipmitool' do
context 'with no ipmitool fact' do
before do
Facter::Util::Resolution.expects(:which).at_least(1).with('ipmitool').returns(nil)
Facter::Util::Resolution.expects(:exec).with('ipmitool mc info 2>/dev/null').never
Facter.fact(:ipmitool).stubs(:value).returns(nil)
end

it do
Expand All @@ -53,8 +25,24 @@

context 'with detailed output' do
before do
Facter::Util::Resolution.expects(:which).with('ipmitool').returns('ipmitool')
Facter::Util::Resolution.expects(:exec).with('ipmitool mc info 2>/dev/null').returns(detailed_output)
Facter.fact(:ipmitool).stubs(:value).returns(
{
fru: {},
mc_info: {
'Device ID' => '32',
'Device Revision' => '1',
'Firmware Revision' => '2.49',
'IPMI Version' => '2.0',
'IPMI_Puppet_Service_Recommend' => 'running',
'Manufacturer ID' => '10876',
'Manufacturer Name' => 'Supermicro',
'Product ID' => '43707 (0xaabb)',
'Product Name' => 'Unknown (0xAABB)',
'Device Available' => 'yes',
'Provides Device SDRs' => 'no',
}
}
)
end

it do
Expand Down
Loading