logicminds / rubyipmi

Command line wrapper for ipmitool and freeipmi
GNU Lesser General Public License v2.1
35 stars 32 forks source link

Make host optional #24

Closed mrichar1 closed 7 years ago

mrichar1 commented 9 years ago

Both ipmitool and freeipmi support the use of /dev/ipmi to access the ipmi interface for the host that the command is being run on - i.e no host is specified on the command-line (-H/-h option).

Would it be possible to make the host argument to the connect method optional, so that these tools would then connect in this way instead of using a remote host?

logicminds commented 9 years ago

It is possible but it requires the use of openipmi as a driver since you can only execute the command on the host you want to control. So this would not scale well since you need to log into every host you want to control. What is your use case though? If your trying to configure servers you should try https://github.com/logicminds/bmclib.

mrichar1 commented 9 years ago

We're using sensu as our monitoring system integrated into our ocnfig management system. We define metrics and monitoring checks based on host configuration - thus all hosts which are configured with an ipmi interface should automatically gather sensor information for themselves. Doing it this way, rather than from a single central location means that we don't need to maintain a list of servers to be queried, and we can have a single check which all hosts run, replacing $host etc with their own information.

This would of course still work with the --host option, by setting the machine's own interface as the value... however in our case our ipmi interface is on a different network to our servers and firewalled such that only users on admin hosts (or those granted access to /dev/ipmi locally) can connect to the ipmi interface. Hence the request for access via /dev/ipmi.

I hope that makes sense!

logicminds commented 9 years ago

That sounds awesome. Would you be able to write some docs up on how to configure all this and share with the sensu community? Additionally I would like to see this use case in the rubyipmi readme file. I am a little slammed right now but I can probably add this within the next few weeks.

mrichar1 commented 9 years ago

The ipmi metrics check was only recently added to the sensu community plugins: https://github.com/sensu/sensu-community-plugins/blob/master/plugins/ipmi/check-sensor.rb

Like most sensu checks it's self-documenting, and (assuming you are already using sensu and understand how to set up checks and metrics) it's trivial to add a new check using this metric.

I'll see about writing up a gist or something explaining what we're doing in more detail as and when I get it working in production. Thanks again for writing rubyipmi though, as without it this check wouldn't exist!

logicminds commented 9 years ago

@mrichar1 I haven't had a chance to create integration tests but I did finish the code and wrote enough unit tests to catch dumb mistakes. Give this branch a try and see if it works. Let me know of any improvements if any. If your satisfied I'll go ahead and merge as my integration tests need a giant overhaul and I won't have enough time right now.

Basically the new way to create a object is even simpler when openipmi is used. No parameters are required.

conn = Rubyipmi.connect
conn.chassis.power.status
mrichar1 commented 9 years ago

I've just tried out this code, and am having a few problems - not sure if it's me or the code though. I've tired it using irb as both an ordinary user, and with sudo, in case the issue was with permissions to /dev/ipmi0 - both give the same results:

> conn = Rubyipmi.connect
=> #<Rubyipmi::Freeipmi::Connection:0x000000017878b8 @debug=false, @options={"privilege-level"=>nil, "driver-type"=>"OPENIPMI"}>

> conn.power.status
NoMethodError: undefined method `power' for #Rubyipmi::Freeipmi::Connection:0x000000017878b8>
    from (irb):9
    from /opt/sensu/embedded/bin/irb:12:in `<main>'

If I change the provider, it doesn't make any difference:

> conn = Rubyipmi.connect(nil, nil, nil, 'ipmitool')
=> #<Rubyipmi::Ipmitool::Connection:0x000000014149d8 @debug=false, @options={"L"=>nil, "I"=>"open"}>

> conn.power.status
NoMethodError: undefined method `power' for #<Rubyipmi::Ipmitool::Connection:0x000000014149d8>
    from (irb):13
    from /opt/sensu/embedded/bin/irb:12:in `<main>'

Any ideas what is happening? thanks!

logicminds commented 9 years ago

There is an error in my docs. Should be conn.chassis.power.status.

mrichar1 commented 9 years ago

Closer, but still not quite right...

ipmitool seems to work if you set a privilege level to something other than nil:

> conn = Rubyipmi.connect(nil, nil, nil, 'ipmitool')
=> #<Rubyipmi::Ipmitool::Connection:0x00000000c2ed68 @debug=false, @options={"L"=>nil, "I"=>"open"}>
> conn.chassis.power.status
=> nil

> conn = Rubyipmi.connect(nil, nil, nil, 'ipmitool', privilege: 'USER')
=> #<Rubyipmi::Ipmitool::Connection:0x00000000c2ed68 @debug=false, @options={"L"=>'USER', "I"=>"open"}>
> conn.chassis.power.status
=> on

This also works for other calls, e.g. 'conn.sensors.list'

freeipmi is more interesting:

> conn = Rubyipmi.connect(nil, nil, nil, 'freeipmi')
=> #<Rubyipmi::Freeipmi::Connection:0x00000000c054e0 @debug=false, @options={"privilege-level"=>nil, "driver-type"=>"OPENIPMI"}>
> conn.chassis.power.status
=> "missing argument for option \"username\" on line 1"

> conn = Rubyipmi.connect('test', 'test', nil, 'freeipmi')
=> #<Rubyipmi::Freeipmi::Connection:0x00000001ac3900 @debug=false, @options={"username"=>"test", "password"=>"test", "privilege-level"=>nil, "driver-type"=>"OPENIPMI"}>
> conn.chassis.power.status
=> "invalid privilege level"

> conn = Rubyipmi.connect('test', 'test', nil, 'freeipmi', privilege: "USER")
=> #<Rubyipmi::Freeipmi::Connection:0x00000001ad8490 @debug=false, @options={"username"=>"test", "password"=>"test", "privilege-level"=>"USER", "driver-type"=>"OPENIPMI"}>
> conn.chassis.power.status
=> "invalid driver type"

I've tried auto, open, lan15 and lan20 as driver values without success.

logicminds commented 9 years ago

Can you provide the command line equilevent so I can ensure all the correct options are being supplied. What version of freeipmi are you using.

Also the fifth argument is expecting a hash

conn = Rubyipmi.connect('test', 'test', nil, 'freeipmi', {:privilege =>"USER"})
mrichar1 commented 9 years ago

freeipmi-1.2.1-3 (el6) is the package I'm using - I generally use ipmitool, but installed freeipmi for testing, so am not really familiar with it...

It looks like some of the sub-commands accept in-band (e.g. open) and out-band (e.g. lan15) driver-type args, but some (e.g. ipmi-power) only accept out-band:

> ipmi-sensors -D open |head -n 5
ID  | Name             | Type                     | Reading    | Units | Event
1   | Temp             | Temperature              | N/A        | C     | N/A
2   | Temp             | Temperature              | N/A        | C     | N/A
3   | Temp             | Temperature              | N/A        | C     | N/A
4   | Temp             | Temperature              | N/A        | C     | N/A

> ipmi-power -D open
invalid driver type

However, it looks like (this version at least) ipmi-power can't do 'local' queries:

> ipmi-power --stat
must specify target hostname(s) in non-interactive mode

I've just looked at the man pages for the latest version of freeipmi at http://svn.savannah.gnu.org/viewvc/trunk/man/?root=freeipmi and they still only reference out-band drivers, implying that this will never work.

Not sure how you'd best deal with this!

logicminds commented 9 years ago

Just getting around to testing this on real hardware. This will need some additional work and testing. I will make this part of 0.10.0 release.

logicminds commented 7 years ago

available in 0.10