BMC / IPMI support in smart-proxy

I have added BMC support to smart proxy so that we can control a system's bmc/ipmi interface through http calls.

The smart proxy will have support for both freeipmi and ipmitool as its important to support both ipmi providers. However, currently only freeipmi is supported, but ipmitool will be trivial to add later.

Essentially if you want to control a system you would use the following calls:

http://smartproxy:8443/bmc/ipmidevice/function/action

Example:

curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/led/off
curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/led/on
curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/power/on
curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/power/off
curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/power/cycle
curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/power/soft
curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/boot/pxe
curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/boot/disk

I still have a few more items to complete before making a pull request and was hoping I can get some eyes on the code to spot any potential issues.

Also I am thinking about requiring some sort encryption on the password. What are your thoughts on encrypting the password?
Also I am not sure how to handle errors, how do I log errors, should I throw exceptions?
How do I ensure the user has the required gems installed and error out if something is missing while providing helpful hits to what to install?
The BMC functionality will require freeipmi ruby wrapper gem and freeipmi command line tools. Or if using ipmitool the ipmitool command line tools and ipmitool ruby wrapper.

smart proxy code: https://github.com/logicminds/smart-proxy/commit/baee452c3c242b0e377cb0565e1f82c31c8fc82e

freeipmi ruby wrapper : https://github.com/logicminds/ruby-freeipmi

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

> I have added BMC support to smart proxy so that we can control a system's
> bmc/ipmi interface through http calls.
>
Awesome!!!

>
> The smart proxy will have support for both freeipmi and ipmitool as its
> important to support both ipmi providers. However, currently only freeipmi
> is supported, but ipmitool will be trivial to add later.
>
> Essentially if you want to control a system you would use the following
> calls:
>
> http://smartproxy:8443/bmc/ipmidevice/function/action
>

this looks good, what about getting the current state?

>
>
> Example:
>
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
> /bmc/192.168.1.41/led/off
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
> /bmc/192.168.1.41/led/on
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
> /bmc/192.168.1.41/power/on
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
> /bmc/192.168.1.41/power/off
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
> /bmc/192.168.1.41/power/cycle
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
> /bmc/192.168.1.41/power/soft
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
> /bmc/192.168.1.41/boot/pxe
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
> /bmc/192.168.1.41/boot/disk
>
> Do you think it makes more sense to support it via PUT (or even PATCH) as
http verbs instead of all in GET ?

> I still have a few more items to complete before making a pull request and
> was hoping I can get some eyes on the code to spot any potential issues.
>

>
> Also I am thinking about requiring some sort encryption on the password.
> What are your thoughts on encrypting the password?
>
Where? on foreman side? smart proxy ?

> Also I am not sure how to handle errors, how do I log errors, should I
> throw exceptions?
>

Currently, with other provides we do
return error code 4XX or 5XX errors
provide inside the json response an hash with errors

>
>
How do I ensure the user has the required gems installed and error out if
> something is missing while providing helpful hits to what to install?
> The BMC functionality will require freeipmi ruby wrapper gem and freeipmi
> command line tools. Or if using ipmitool the ipmitool command line tools
> and ipmitool ruby wrapper.
>

There are two ways to handle this issue:

  1. Using begin rescue
    e.g.

begin
require 'gem'
rescue LoadError

oops, dont have the GEM, ignoring functionality

end

  1. using Bundler

in the past, we were trying to avoid bundler, mostly because it can't run
on older platforms (e.g. require rubygems etc that dont exists on RHEL4
etc).
however, I think that if we add the bundler part with the same way we do #1
above, then it would have a few more benefits:

  1. we get all the gems we need for people who uses bundler
  2. we can use bundler groups, and have the same concepts like packaging for
    foreman
  3. we can easily add the gems for windows (which has been an burden so far).

afair, there is an existing ticket for the proxy with bundler, maybe just
need to apply the rescue LoadError logic to it and we are more or less done.

> smart proxy code:
> https://github.com/logicminds/smart-proxy/commit/baee452c3c242b0e377cb0565e1f82c31c8fc82e
>

Code looks really good :slight_smile:

Ohad

··· On Sat, Aug 4, 2012 at 4:26 AM, Corey Osman wrote:

freeipmi ruby wrapper : https://github.com/logicminds/ruby-freeipmi

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

Hi Corey,

Thank you for working on this. I was just ponding this issue this
morning and then I checked the dev list. :slight_smile:

The major use case for me right now is I have a few dozen systems that
seem to have gotten a marginal batch of memory and I occasionally have
nodes go down due to memory issues. My day dream is to some day be able
via foreman to powercycle a node via IPMI and set it to boot into
memtest86+.

> I have added BMC support to smart proxy so that we can control a
> system's bmc/ipmi interface through http calls.
>
> The smart proxy will have support for both freeipmi and ipmitool as its
> important to support both ipmi providers. However, currently only
> freeipmi is supported, but ipmitool will be trivial to add later.
>
> Essentially if you want to control a system you would use the following
> calls:
>
> http://smartproxy:8443/bmc/ipmidevice/function/action
>
> Example:
>
> curl -d "username=admin&password=secret123"
> http://172.16.220.132:8443/bmc/192.168.1.41/led/off
> curl -d "username=admin&password=secret123"
> http://172.16.220.132:8443/bmc/192.168.1.41/led/on
> curl -d "username=admin&password=secret123"
> http://172.16.220.132:8443/bmc/192.168.1.41/power/on
> curl -d "username=admin&password=secret123"
> http://172.16.220.132:8443/bmc/192.168.1.41/power/off
> curl -d "username=admin&password=secret123"
> http://172.16.220.132:8443/bmc/192.168.1.41/power/cycle
> curl -d "username=admin&password=secret123"
> http://172.16.220.132:8443/bmc/192.168.1.41/power/soft
> curl -d "username=admin&password=secret123"
> http://172.16.220.132:8443/bmc/192.168.1.41/boot/pxe
> curl -d "username=admin&password=secret123"
> http://172.16.220.132:8443/bmc/192.168.1.41/boot/disk

I don't think this is a problem per se but it might be a little bit more
intuitive if the command paths match up a little closer to the IPMI
command set instead of a particular tools command names. Granted, the
ipmi spec isn't as nicely a hierarchy with short command names as it
could be. I believe all of the example commands above are part of the
chassis command subset.

Looking at section 28 of last rev of the 2.0 spec.

http://download.intel.com/design/servers/ipmi/IPMI2_0E4_Markup_061209.pdf

That might be something like:

in particular, there is no LED command, the identify method is left up

to the implementation
http://<proxy>//bmc/<bmc IP>/chassis/identify/off
http://<proxy>//bmc/<bmc IP>/chassis/identify/on

maybe "control" is a better name than power; the spec is frustrating

http://<proxy>//bmc/<bmc IP>/chassis/power/down # on / off maybe be
better but the spec says up/down
http://<proxy>//bmc/<bmc IP>/chassis/power/up
http://<proxy>//bmc/<bmc IP>/chassis/power/cycle

I think the minimum needed boot devices are pxe/disk/bios

there are a ton of different boot options, ipmitool has separate

bootdev and bootparam options although thou the spec appears to be just
one giant pile of boot option flags
http://<proxy>//bmc/<bmc IP>/chassis/boot or bootdev?/<boot device>

It's sort of a day dream that someday foreman could could set the bmc's
IP address statically after it boots from dhcp so it would be nice to
keep the top level namespace clean so things like ./lan can be added
down the road.

I'd also suggest that the mutator functions not be HTTP GET commands.
In a general sense, it's nice to have the option of allowing more broad
access to status only functions via get commands and then setting up
separate access/auth settings for mutators by restricting PUT/etc. commands.

>
> I still have a few more items to complete before making a pull request
> and was hoping I can get some eyes on the code to spot any potential issues.

I'm looking at it now. Is user/pass/host enough information to work
with most BMCs? I honestly don't know but I the authtype & ciphersuite
options to ipmitool make me suspicious. Might be worth checking.

Thanks again for working on this. Let me know when your ready for testers.

-Josh

··· On 08/03/2012 06:26 PM, Corey Osman wrote:

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

> Hi Corey,
>
> Thank you for working on this. I was just ponding this issue this
> morning and then I checked the dev list. :slight_smile:
>
> The major use case for me right now is I have a few dozen systems that
> seem to have gotten a marginal batch of memory and I occasionally have
> nodes go down due to memory issues. My day dream is to some day be able
> via foreman to powercycle a node via IPMI and set it to boot into
> memtest86+.
>
>
>> I have added BMC support to smart proxy so that we can control a
>> system's bmc/ipmi interface through http calls.
>>
>> The smart proxy will have support for both freeipmi and ipmitool as its
>> important to support both ipmi providers. However, currently only
>> freeipmi is supported, but ipmitool will be trivial to add later.
>>
>> Essentially if you want to control a system you would use the following
>> calls:
>>
>> http://smartproxy:8443/bmc/ipmidevice/function/action
>>
>> Example:
>>
>> curl -d "username=admin&password=secret123"
>> http://172.16.220.132:8443/bmc/192.168.1.41/led/off
>> curl -d "username=admin&password=secret123"
>> http://172.16.220.132:8443/bmc/192.168.1.41/led/on
>> curl -d "username=admin&password=secret123"
>> http://172.16.220.132:8443/bmc/192.168.1.41/power/on
>> curl -d "username=admin&password=secret123"
>> http://172.16.220.132:8443/bmc/192.168.1.41/power/off
>> curl -d "username=admin&password=secret123"
>> http://172.16.220.132:8443/bmc/192.168.1.41/power/cycle
>> curl -d "username=admin&password=secret123"
>> http://172.16.220.132:8443/bmc/192.168.1.41/power/soft
>> curl -d "username=admin&password=secret123"
>> http://172.16.220.132:8443/bmc/192.168.1.41/boot/pxe
>> curl -d "username=admin&password=secret123"
>> http://172.16.220.132:8443/bmc/192.168.1.41/boot/disk
>
> I don't think this is a problem per se but it might be a little bit more
> intuitive if the command paths match up a little closer to the IPMI
> command set instead of a particular tools command names. Granted, the
> ipmi spec isn't as nicely a hierarchy with short command names as it
> could be. I believe all of the example commands above are part of the
> chassis command subset.
>
> Looking at section 28 of last rev of the 2.0 spec.
>
> http://www.intel.com/design/servers/ipmi/spec.htm
> http://download.intel.com/design/servers/ipmi/IPMI2_0E4_Markup_061209.pdf
>
> That might be something like:
>
> # in particular, there is no LED command, the identify method is left up
> to the implementation
> http://<proxy>//bmc/<bmc IP>/chassis/identify/off
> http://<proxy>//bmc/<bmc IP>/chassis/identify/on
> # maybe "control" is a better name than power; the spec is frustrating
> http://<proxy>//bmc/<bmc IP>/chassis/power/down # on / off maybe be
> better but the spec says up/down
> http://<proxy>//bmc/<bmc IP>/chassis/power/up
> http://<proxy>//bmc/<bmc IP>/chassis/power/cycle
> # I think the minimum needed boot devices are pxe/disk/bios
> # there are a ton of different boot options, ipmitool has separate
> bootdev and bootparam options although thou the spec appears to be just
> one giant pile of boot option flags
> http://<proxy>//bmc/<bmc IP>/chassis/boot or bootdev?/<boot device>
>
> It's sort of a day dream that someday foreman could could set the bmc's
> IP address statically after it boots from dhcp so it would be nice to
> keep the top level namespace clean so things like ./lan can be added
> down the road.

The goal is to use these commands in my mobile app remoteadmin. Imagine powering off a server with your phone.

>
> I'd also suggest that the mutator functions not be HTTP GET commands.
> In a general sense, it's nice to have the option of allowing more broad
> access to status only functions via get commands and then setting up
> separate access/auth settings for mutators by restricting PUT/etc. commands.

Excellent suggestion. I guess my thought was to "dumb down" some of the commands. My ruby-freeipmi follows more of the hierarchy than the smart-proxy implementation. However, this is super easy to change.

what if I add a GET for bmc/host/chassis/power/on and bmc/host/chassis/power/off

that returns true/false if power is on/off vs calling bmc/host/chassis/power/status?

I'll refactor the code to reflect the ipmi spec more closely.

>
>>
>> I still have a few more items to complete before making a pull request
>> and was hoping I can get some eyes on the code to spot any potential issues.
>
> I'm looking at it now. Is user/pass/host enough information to work
> with most BMCs? I honestly don't know but I the authtype & ciphersuite
> options to ipmitool make me suspicious. Might be worth checking.

I am not quite sure what those options do yet. Any ideas? Are you using any of them now?

··· On Aug 6, 2012, at 11:45 AM, Joshua hoblitt wrote: > On 08/03/2012 06:26 PM, Corey Osman wrote:

Thanks again for working on this. Let me know when your ready for testers.

-Josh

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

>
>
> I have added BMC support to smart proxy so that we can control a system's bmc/ipmi interface through http calls.
> Awesome!!!
>
> The smart proxy will have support for both freeipmi and ipmitool as its important to support both ipmi providers. However, currently only freeipmi is supported, but ipmitool will be trivial to add later.
>
> Essentially if you want to control a system you would use the following calls:
>
> http://smartproxy:8443/bmc/ipmidevice/function/action
>
> this looks good, what about getting the current state?

Yea, I can add the state for each function.

>
>
>
> Example:
>
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/led/off
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/led/on
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/power/on
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/power/off
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/power/cycle
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/power/soft
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/boot/pxe
> curl -d "username=admin&password=secret123" http://172.16.220.132:8443/bmc/192.168.1.41/boot/disk
>
> Do you think it makes more sense to support it via PUT (or even PATCH) as http verbs instead of all in GET ?

Its actually a POST statement. I can do PUT as well if that seems more restful. Not sure about patch though, I would be afraid that some 3rd parties tools might not be able to support PATCH.

>
> I still have a few more items to complete before making a pull request and was hoping I can get some eyes on the code to spot any potential issues.
>
>
> Also I am thinking about requiring some sort encryption on the password. What are your thoughts on encrypting the password?
> Where? on foreman side? smart proxy ?

On the smart proxy side so that at least some level of security is enforced, if people don't use https.

··· On Aug 4, 2012, at 11:43 PM, Ohad Levy wrote: > On Sat, Aug 4, 2012 at 4:26 AM, Corey Osman wrote:

Also I am not sure how to handle errors, how do I log errors, should I throw exceptions?

Currently, with other provides we do
return error code 4XX or 5XX errors
provide inside the json response an hash with errors

How do I ensure the user has the required gems installed and error out if something is missing while providing helpful hits to what to install?
The BMC functionality will require freeipmi ruby wrapper gem and freeipmi command line tools. Or if using ipmitool the ipmitool command line tools and ipmitool ruby wrapper.

There are two ways to handle this issue:

  1. Using begin rescue
    e.g.

begin
require ‘gem’
rescue LoadError

oops, dont have the GEM, ignoring functionality

end

  1. using Bundler

in the past, we were trying to avoid bundler, mostly because it can’t run on older platforms (e.g. require rubygems etc that dont exists on RHEL4 etc).
however, I think that if we add the bundler part with the same way we do #1 above, then it would have a few more benefits:

  1. we get all the gems we need for people who uses bundler
  2. we can use bundler groups, and have the same concepts like packaging for foreman
  3. we can easily add the gems for windows (which has been an burden so far).

afair, there is an existing ticket for the proxy with bundler, maybe just need to apply the rescue LoadError logic to it and we are more or less done.

smart proxy code: https://github.com/logicminds/smart-proxy/commit/baee452c3c242b0e377cb0565e1f82c31c8fc82e

Code looks really good :slight_smile:

Ohad

freeipmi ruby wrapper : https://github.com/logicminds/ruby-freeipmi

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

>
>
>
> Thanks,
>
> Corey Osman
> corey@logicminds.biz
> 678-348-0582 (Pacific Time)
>
> Green IT and Data Center Automation Specialist
>
>
>
>
>
>
>
>
>
>
>> I have added BMC support to smart proxy so that we can control a system's
>> bmc/ipmi interface through http calls.
>>
> Awesome!!!
>
>>
>> The smart proxy will have support for both freeipmi and ipmitool as its
>> important to support both ipmi providers. However, currently only freeipmi
>> is supported, but ipmitool will be trivial to add later.
>>
>> Essentially if you want to control a system you would use the following
>> calls:
>>
>> http://smartproxy:8443/bmc/ipmidevice/function/action
>>
>
> this looks good, what about getting the current state?
>
>
> Yea, I can add the state for each function.
>
>
>
>>
>>
>> Example:
>>
>> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
>> /bmc/192.168.1.41/led/off
>> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
>> /bmc/192.168.1.41/led/on
>> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
>> /bmc/192.168.1.41/power/on
>> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
>> /bmc/192.168.1.41/power/off
>> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
>> /bmc/192.168.1.41/power/cycle
>> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
>> /bmc/192.168.1.41/power/soft
>> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
>> /bmc/192.168.1.41/boot/pxe
>> curl -d "username=admin&password=secret123" http://172.16.220.132:8443
>> /bmc/192.168.1.41/boot/disk
>>
>> Do you think it makes more sense to support it via PUT (or even PATCH) as
> http verbs instead of all in GET ?
>
>
> Its actually a POST statement. I can do PUT as well if that seems more
> restful. Not sure about patch though, I would be afraid that some 3rd
> parties tools might not be able to support PATCH.
>
> OK, I think PUT is the right answer for now, since there are workarounds
to send PUT via POST (thats how most browses do it anyway).

I would assume that GET would be the current state (as for above).

>
>
>> I still have a few more items to complete before making a pull request
>> and was hoping I can get some eyes on the code to spot any potential issues.
>>
>
>
>>
>> Also I am thinking about requiring some sort encryption on the password.
>> What are your thoughts on encrypting the password?
>>
> Where? on foreman side? smart proxy ?
>
>
> On the smart proxy side so that at least some level of security is
> enforced, if people don't use https.
>

Hmm… so it means you want to store the U/PW for every BMC device on the
proxy itself ?

Ohad

··· On Tue, Aug 7, 2012 at 12:08 AM, Corey Osman wrote: > On Aug 4, 2012, at 11:43 PM, Ohad Levy wrote: > On Sat, Aug 4, 2012 at 4:26 AM, Corey Osman wrote:

Also I am not sure how to handle errors, how do I log errors, should I
throw exceptions?

Currently, with other provides we do
return error code 4XX or 5XX errors
provide inside the json response an hash with errors

How do I ensure the user has the required gems installed and error out

if something is missing while providing helpful hits to what to install?
The BMC functionality will require freeipmi ruby wrapper gem and freeipmi
command line tools. Or if using ipmitool the ipmitool command line tools
and ipmitool ruby wrapper.

There are two ways to handle this issue:

  1. Using begin rescue
    e.g.

begin
require ‘gem’
rescue LoadError

oops, dont have the GEM, ignoring functionality

end

  1. using Bundler

in the past, we were trying to avoid bundler, mostly because it can’t run
on older platforms (e.g. require rubygems etc that dont exists on RHEL4
etc).
however, I think that if we add the bundler part with the same way we do
#1 above, then it would have a few more benefits:

  1. we get all the gems we need for people who uses bundler
  2. we can use bundler groups, and have the same concepts
    like packaging for foreman
  3. we can easily add the gems for windows (which has been an burden so
    far).

afair, there is an existing ticket for the proxy with bundler, maybe just
need to apply the rescue LoadError logic to it and we are more or less done.

smart proxy code:
https://github.com/logicminds/smart-proxy/commit/baee452c3c242b0e377cb0565e1f82c31c8fc82e

Code looks really good :slight_smile:

Ohad

freeipmi ruby wrapper : https://github.com/logicminds/ruby-freeipmi

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

I decided to add support for both ipmitool and freeipmi since ipmitool doesn't perform CRC checks and some devices will return bad data that freeipmi checks and returns errors.

Originally I created a ruby-freeipmi library which I then combined into a new library with ipmitool. This new library is called rubyipmi ( GitHub - logicminds/rubyipmi: Command line wrapper for ipmitool and freeipmi ). Currently rubyipmi only supports a few major functions ( power, lan, bmc, boot) which should be everything foreman needs. As time goes on I hope to add more functions that will be outside the scope of foreman (sensors, user controls, …).

The cool think about rubyipmi is that it will automatically find the ipmi provider (ipmitool, freeipmi) you have installed if you don't specify the provider type.

I would suggest that both providers be installed on the smart-proxy as ipmi device support with be a hit/miss with each provider.

Smart proxy bmc support is fully functional with a few exceptions:

– I have not added support to set the bmc lan device. Although rubyipmi supports setting the bmc lan device, I need to do lots of testing in order to catch any potential issues with setting network parameters.
– Is given ip pingable? Whoops, don't create a IP collision.
– Will subnet and gateway address result in a bmc device not being able to talk to anyone?
– What happens when you set the gateway without changing the IP?
– What happens when you set the subnet without changing the IP and gateway?

– Security:
Currently username/password is only supported. Additionally, freeipmi allows one to configure a freeipmi.conf with credentials which gets around passing credentials. However, I see further security issues when freeipmi has credentials supplied in the freeipmi.conf file.
The main problem here is that not all bmc devices will support the same security measures. However, 100% will allow username/password, while others will also support ssl certs, ssh keys, radius, and ldap. Eventually, we will want foreman to provision each host to automatically setup security using ssl and or username/password using openipmi.

– Configuration from the actual host
There is an option to configure the ipmi device from the actual host OS. This would require a special driver openipmi. I believe this type of action should be done at provision time or during a puppet run. However, one could set the bmc lan parameters and users from this method without an IP or username/password.

If its a puppet module, then there would need to be a fact that displays the bmc device ip. Foreman could then showcase the bmc ip and allow the foreman UI to control IPMI functions through smart-proxy.

I decided to program the api with a little bit of feedback built in.

For example:

A GET will retrieve the value of some bmc device function that simply reads data
A PUT will perform a function on the bmc device

If you can't remember how to make a call then the api will return some help

Example

GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===> {"actions":["on","off","status"]}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===> {"result":false,"action":"on"}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/off?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===> {"result":true,"action":"off"}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/status?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===> {"result":"off","action":"status"}

GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===> {"functions":["bootdevices"]}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevices?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===> {"devices":["pxe","disk","cdrom","bios"]}

GET http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===> {"actions":["ip","subnet","mac","gateway"]}
GET http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/ip?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===> {"result":"192.168.1.41","action":"ip"}
GET http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/mac?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ====> {"result":"00:17:a4:49:ab:70","action":"mac"}

Want to turn a system on?
curl -X PUT -d "username=admin&password=secret&bmc_provider=ipmitool" http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on ===> {"result":true,"action":"on"}

Want to boot to pxe?
curl -X PUT -d "username=admin&password=secret&bmc_provider=ipmitool&reboot=true" http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevice/pxe ===> {"result":true,"action":"pxe"}

Want to cycle power?
curl -X PUT -d "username=admin&password=secret&bmc_provider=ipmitool" http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/cycle ===> {"result":true,"action":"cycle"}

Forgot what actions you have when using PUT?
curl -X PUT -d "username=admin&password=secret&bmc_provider=ipmitool" http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===> {"actions":["on","off","cycle","soft"]}

Want to turn the identify light on?
curl -X PUT -d "username=admin&password=secret&bmc_provider=ipmitool" http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on ===> {"result":true,"action":"on"}

Did you goof up with some command?
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===> {"error":"The action: on is not a valid action"}

How to test the ipmi branch:

git clone GitHub - logicminds/smart-proxy: RESTful proxies for DNS, DHCP, TFTP, BMC and Puppet
cd smart-proxy
git checkout ipmi (must checkout the ipmi branch)
gem install rubyipmi — on your smartproxy, currently 0.3.3
install freeipmi or ipmitool or both

Add the following lines to your smart proxy settings

··· --------------------------------------------------------------------- # enable BMC management (Bare metal power and bios controls) # Ensure that you have freeipmi or ipmitool command line tools installed # You will also need the rubyipmi gem :bmc: true # Available bmc providers: freeipmi, ipmitool (optional) #:bmc_default_provider: freeipmi

How to run the rake tests:

  1. enable bmc in the settings
  2. rake test TEST=test/bmc_api_test.rb ipmiuser=username ipmipass=password ipmihost=hostorip ipmiprovider=ipmitool
  3. rake test TEST=test/bmc_test.rb ipmiuser=username ipmipass=password ipmihost=hostorip ipmiprovider=ipmitool

If tests fail try the other provider. If you continue to have issues, email me. Another important step is to keep your bmc firmware updated since this could fix ipmi errors.

Feedback?

Thanks,

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

On Aug 6, 2012, at 11:32 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Tue, Aug 7, 2012 at 12:08 AM, Corey Osman corey@logicminds.biz wrote:

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

On Aug 4, 2012, at 11:43 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Sat, Aug 4, 2012 at 4:26 AM, Corey Osman corey@logicminds.biz wrote:
I have added BMC support to smart proxy so that we can control a system’s bmc/ipmi interface through http calls.
Awesome!!!

The smart proxy will have support for both freeipmi and ipmitool as its important to support both ipmi providers. However, currently only freeipmi is supported, but ipmitool will be trivial to add later.

Essentially if you want to control a system you would use the following calls:

http://smartproxy:8443/bmc/ipmidevice/function/action

this looks good, what about getting the current state?

Yea, I can add the state for each function.

Example:

curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/led/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/led/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/cycle
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/soft
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/boot/pxe
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/boot/disk

Do you think it makes more sense to support it via PUT (or even PATCH) as http verbs instead of all in GET ?

Its actually a POST statement. I can do PUT as well if that seems more restful. Not sure about patch though, I would be afraid that some 3rd parties tools might not be able to support PATCH.

OK, I think PUT is the right answer for now, since there are workarounds to send PUT via POST (thats how most browses do it anyway).

I would assume that GET would be the current state (as for above).

I still have a few more items to complete before making a pull request and was hoping I can get some eyes on the code to spot any potential issues.

Also I am thinking about requiring some sort encryption on the password. What are your thoughts on encrypting the password?
Where? on foreman side? smart proxy ?

On the smart proxy side so that at least some level of security is enforced, if people don’t use https.

Hmm… so it means you want to store the U/PW for every BMC device on the proxy itself ?

Ohad

Also I am not sure how to handle errors, how do I log errors, should I throw exceptions?

Currently, with other provides we do
return error code 4XX or 5XX errors
provide inside the json response an hash with errors

How do I ensure the user has the required gems installed and error out if something is missing while providing helpful hits to what to install?
The BMC functionality will require freeipmi ruby wrapper gem and freeipmi command line tools. Or if using ipmitool the ipmitool command line tools and ipmitool ruby wrapper.

There are two ways to handle this issue:

  1. Using begin rescue
    e.g.

begin
require ‘gem’
rescue LoadError

oops, dont have the GEM, ignoring functionality

end

  1. using Bundler

in the past, we were trying to avoid bundler, mostly because it can’t run on older platforms (e.g. require rubygems etc that dont exists on RHEL4 etc).
however, I think that if we add the bundler part with the same way we do #1 above, then it would have a few more benefits:

  1. we get all the gems we need for people who uses bundler
  2. we can use bundler groups, and have the same concepts like packaging for foreman
  3. we can easily add the gems for windows (which has been an burden so far).

afair, there is an existing ticket for the proxy with bundler, maybe just need to apply the rescue LoadError logic to it and we are more or less done.

smart proxy code: https://github.com/logicminds/smart-proxy/commit/baee452c3c242b0e377cb0565e1f82c31c8fc82e

Code looks really good :slight_smile:

Ohad

freeipmi ruby wrapper : https://github.com/logicminds/ruby-freeipmi

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

> I decided to add support for both ipmitool and freeipmi since ipmitool
> doesn't perform CRC checks and some devices will return bad data that
> freeipmi checks and returns errors.
>
> Originally I created a ruby-freeipmi library which I then combined into a
> new library with ipmitool. This new library is called rubyipmi (
> GitHub - logicminds/rubyipmi: Command line wrapper for ipmitool and freeipmi ). Currently rubyipmi only
> supports a few major functions ( power, lan, bmc, boot) which should be
> everything foreman needs. As time goes on I hope to add more functions
> that will be outside the scope of foreman (sensors, user controls, …).
>
> The cool think about rubyipmi is that it will automatically find the ipmi
> provider (ipmitool, freeipmi) you have installed if you don't specify the
> provider type.
>

will you allow to force a provider? or it should be auto detected always?

>
> I would suggest that both providers be installed on the smart-proxy as
> ipmi device support with be a hit/miss with each provider.
>
>
> Smart proxy bmc support is fully functional with a few exceptions:
>
> – I have not added support to set the bmc lan device. Although rubyipmi
> supports setting the bmc lan device, I need to do lots of testing in order
> to catch any potential issues with setting network parameters.
> – Is given ip pingable? Whoops, don't create a IP collision.
> – Will subnet and gateway address result in a bmc device not being able
> to talk to anyone?
> – What happens when you set the gateway without changing the IP?
> – What happens when you set the subnet without changing the IP and
> gateway?
>
> I'm not 100% sure if this within scope of the api, afterall, you could use
the impitool to do the same (and the whole point is to make it accessible
via a rest api), imho, such logic should be done elsewhere.

– Security:
> Currently username/password is only supported. Additionally, freeipmi
> allows one to configure a freeipmi.conf with credentials which gets around
> passing credentials. However, I see further security issues when freeipmi
> has credentials supplied in the freeipmi.conf file.
> The main problem here is that not all bmc devices will support the same
> security measures. However, 100% will allow username/password, while
> others will also support ssl certs, ssh keys, radius, and ldap.
> Eventually, we will want foreman to provision each host to automatically
> setup security using ssl and or username/password using openipmi.
>
> I would leave the current proxy ACL (allowed hostlist + SSL verification)

  • I think its good enough for first run, granted, that the API user would
    need to provide the username / password.

>
> – Configuration from the actual host
> There is an option to configure the ipmi device from the actual host OS.
> This would require a special driver openipmi. I believe this type of
> action should be done at provision time or during a puppet run. However,
> one could set the bmc lan parameters and users from this method without an
> IP or username/password.
>
> If its a puppet module, then there would need to be a fact that displays
> the bmc device ip. Foreman could then showcase the bmc ip and allow the
> foreman UI to control IPMI functions through smart-proxy.
>
> So this is the case when the proxy bmc wants to manage it self? I could
see this really useful when using a bare metal os.

>
>
> I decided to program the api with a little bit of feedback built in.
>
> For example:
>
> A GET will retrieve the value of some bmc device function that simply
> reads data
> A PUT will perform a function on the bmc device
>
> If you can't remember how to make a call then the api will return some help
>
> Example
>
> GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===>
> {"actions":["on","off","status"]}
> GET
> http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===>
> {"result":false,"action":"on"}
>
this has a negative side effect, where you would be posting your U/P and it
would be capture in logs.
maybe we should consider using http basic auth instead?

> GET
> http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/off?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===>
> {"result":true,"action":"off"}
> GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/status?
> username=admin&password=secret&bmc_provider=ipmitool ===>
> {"result":"off","action":"status"}
>
> GET
> http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===>
> {"functions":["bootdevices"]}
> GET
> http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevices?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===>
> {"devices":["pxe","disk","cdrom","bios"]}
>
> GET
> http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ===>
> {"actions":["ip","subnet","mac","gateway"]}
> GET
> http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/ip?username=admin&amp;password=secret&amp;bmc_provider=ipmitool
> ===> {"result":"192.168.1.41","action":"ip"}
> GET
> http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/mac?username=admin&amp;password=secret&amp;bmc_provider=ipmitool ====>
> {"result":"00:17:a4:49:ab:70","action":"mac"}
>
>
> Want to turn a system on?
> curl -X PUT -d "username=admin&password=secret&bmc_provider=ipmitool"
> http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on ===> {"result":true,"action":"on"}
>
> Want to boot to pxe?
> curl -X PUT -d
> "username=admin&password=secret&bmc_provider=ipmitool&reboot=true"
> http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevice/pxe ===> {"result":true,"action":"pxe"}
>
> Want to cycle power?
> curl -X PUT -d "username=admin&password=secret&bmc_provider=ipmitool"
> http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/cycle ===> {"result":true,"action":"cycle"}
>
> Forgot what actions you have when using PUT?
> curl -X PUT -d "username=admin&password=secret&bmc_provider=ipmitool"
> http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===> {"actions":["on","off","cycle","soft"]}
>
> Want to turn the identify light on?
> curl -X PUT -d "username=admin&password=secret&bmc_provider=ipmitool"
> http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on ===> {"result":true,"action":"on"}
>
> Did you goof up with some command?
> GET
> http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on?username=admin&amp;password=secret&amp;bmc_provider=ipmitool===&gt; {"error":"The
> action: on is not a valid action"}
>
>
> How to test the ipmi branch:
>
> git clone GitHub - logicminds/smart-proxy: RESTful proxies for DNS, DHCP, TFTP, BMC and Puppet
> cd smart-proxy
> git checkout ipmi (must checkout the ipmi branch)
> gem install rubyipmi — on your smartproxy, currently 0.3.3
> install freeipmi or ipmitool or both
>
> Add the following lines to your smart proxy settings
> ---------------------------------------------------------------------
> # enable BMC management (Bare metal power and bios controls)
> # Ensure that you have freeipmi or ipmitool command line tools installed
> # You will also need the rubyipmi gem
> :bmc: true
> # Available bmc providers: freeipmi, ipmitool (optional)
> #:bmc_default_provider: freeipmi
>
> How to run the rake tests:
>
> 1. enable bmc in the settings
> 2. rake test TEST=test/bmc_api_test.rb ipmiuser=username ipmipass=password
> ipmihost=hostorip ipmiprovider=ipmitool
> 3. rake test TEST=test/bmc_test.rb ipmiuser=username ipmipass=password
> ipmihost=hostorip ipmiprovider=ipmitool
>
> If tests fail try the other provider. If you continue to have issues,
> email me. Another important step is to keep your bmc firmware updated
> since this could fix ipmi errors.
>
> Feedback?
>
> awesome!

Ohad

··· On Thu, Aug 16, 2012 at 2:51 AM, Corey Osman wrote:

Thanks,

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

On Aug 6, 2012, at 11:32 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Tue, Aug 7, 2012 at 12:08 AM, Corey Osman corey@logicminds.biz wrote:

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

On Aug 4, 2012, at 11:43 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Sat, Aug 4, 2012 at 4:26 AM, Corey Osman corey@logicminds.biz wrote:

I have added BMC support to smart proxy so that we can control a
system’s bmc/ipmi interface through http calls.

Awesome!!!

The smart proxy will have support for both freeipmi and ipmitool as its
important to support both ipmi providers. However, currently only freeipmi
is supported, but ipmitool will be trivial to add later.

Essentially if you want to control a system you would use the following
calls:

http://smartproxy:8443/bmc/ipmidevice/function/action

this looks good, what about getting the current state?

Yea, I can add the state for each function.

Example:

curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/led/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/led/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/cycle
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/soft
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/boot/pxe
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/boot/disk

Do you think it makes more sense to support it via PUT (or even PATCH)
as http verbs instead of all in GET ?

Its actually a POST statement. I can do PUT as well if that seems more
restful. Not sure about patch though, I would be afraid that some 3rd
parties tools might not be able to support PATCH.

OK, I think PUT is the right answer for now, since there are workarounds
to send PUT via POST (thats how most browses do it anyway).

I would assume that GET would be the current state (as for above).

I still have a few more items to complete before making a pull request
and was hoping I can get some eyes on the code to spot any potential issues.

Also I am thinking about requiring some sort encryption on the password.
What are your thoughts on encrypting the password?

Where? on foreman side? smart proxy ?

On the smart proxy side so that at least some level of security is
enforced, if people don’t use https.

Hmm… so it means you want to store the U/PW for every BMC device on the
proxy itself ?

Ohad

Also I am not sure how to handle errors, how do I log errors, should
I throw exceptions?

Currently, with other provides we do
return error code 4XX or 5XX errors
provide inside the json response an hash with errors

How do I ensure the user has the required gems installed and error out

if something is missing while providing helpful hits to what to install?
The BMC functionality will require freeipmi ruby wrapper gem and
freeipmi command line tools. Or if using ipmitool the ipmitool command
line tools and ipmitool ruby wrapper.

There are two ways to handle this issue:

  1. Using begin rescue
    e.g.

begin
require ‘gem’
rescue LoadError

oops, dont have the GEM, ignoring functionality

end

  1. using Bundler

in the past, we were trying to avoid bundler, mostly because it can’t
run on older platforms (e.g. require rubygems etc that dont exists on RHEL4
etc).
however, I think that if we add the bundler part with the same way we do
#1 above, then it would have a few more benefits:

  1. we get all the gems we need for people who uses bundler
  2. we can use bundler groups, and have the same concepts
    like packaging for foreman
  3. we can easily add the gems for windows (which has been an burden so
    far).

afair, there is an existing ticket for the proxy with bundler, maybe just
need to apply the rescue LoadError logic to it and we are more or less done.

smart proxy code:
https://github.com/logicminds/smart-proxy/commit/baee452c3c242b0e377cb0565e1f82c31c8fc82e

Code looks really good :slight_smile:

Ohad

freeipmi ruby wrapper : https://github.com/logicminds/ruby-freeipmi

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

I tested it on DELL PowerEdge servers.
It worked fine.
Really excited to see it integrated on Foreman.
What would be also awesome is to get VNC console directly on Foreman.

Thank you Corey for your really great job !

Romain

··· 2012/8/16 Ohad Levy

On Thu, Aug 16, 2012 at 2:51 AM, Corey Osman corey@logicminds.biz wrote:

I decided to add support for both ipmitool and freeipmi since ipmitool
doesn’t perform CRC checks and some devices will return bad data that
freeipmi checks and returns errors.

Originally I created a ruby-freeipmi library which I then combined into a
new library with ipmitool. This new library is called rubyipmi (
GitHub - logicminds/rubyipmi: Command line wrapper for ipmitool and freeipmi ). Currently rubyipmi only
supports a few major functions ( power, lan, bmc, boot) which should be
everything foreman needs. As time goes on I hope to add more functions
that will be outside the scope of foreman (sensors, user controls, …).

The cool think about rubyipmi is that it will automatically find the ipmi
provider (ipmitool, freeipmi) you have installed if you don’t specify the
provider type.

will you allow to force a provider? or it should be auto detected always?

I would suggest that both providers be installed on the smart-proxy as
ipmi device support with be a hit/miss with each provider.

Smart proxy bmc support is fully functional with a few exceptions:

– I have not added support to set the bmc lan device. Although rubyipmi
supports setting the bmc lan device, I need to do lots of testing in order
to catch any potential issues with setting network parameters.
– Is given ip pingable? Whoops, don’t create a IP collision.
– Will subnet and gateway address result in a bmc device not being able
to talk to anyone?
– What happens when you set the gateway without changing the IP?
– What happens when you set the subnet without changing the IP and
gateway?

I’m not 100% sure if this within scope of the api, afterall, you could
use the impitool to do the same (and the whole point is to make it
accessible via a rest api), imho, such logic should be done elsewhere.

– Security:

Currently username/password is only supported. Additionally, freeipmi
allows one to configure a freeipmi.conf with credentials which gets around
passing credentials. However, I see further security issues when freeipmi
has credentials supplied in the freeipmi.conf file.
The main problem here is that not all bmc devices will support the same
security measures. However, 100% will allow username/password, while
others will also support ssl certs, ssh keys, radius, and ldap.
Eventually, we will want foreman to provision each host to automatically
setup security using ssl and or username/password using openipmi.

I would leave the current proxy ACL (allowed hostlist + SSL verification)

  • I think its good enough for first run, granted, that the API user would
    need to provide the username / password.

– Configuration from the actual host
There is an option to configure the ipmi device from the actual host OS.
This would require a special driver openipmi. I believe this type of
action should be done at provision time or during a puppet run. However,
one could set the bmc lan parameters and users from this method without an
IP or username/password.

If its a puppet module, then there would need to be a fact that displays
the bmc device ip. Foreman could then showcase the bmc ip and allow the
foreman UI to control IPMI functions through smart-proxy.

So this is the case when the proxy bmc wants to manage it self? I could
see this really useful when using a bare metal os.

I decided to program the api with a little bit of feedback built in.

For example:

A GET will retrieve the value of some bmc device function that simply
reads data
A PUT will perform a function on the bmc device

If you can’t remember how to make a call then the api will return some
help

Example

GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===>
{“actions”:[“on”,“off”,“status”]}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on?username=admin&password=secret&bmc_provider=ipmitool ===>
{“result”:false,“action”:“on”}

this has a negative side effect, where you would be posting your U/P and
it would be capture in logs.
maybe we should consider using http basic auth instead?

GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/off?username=admin&password=secret&bmc_provider=ipmitool ===>
{“result”:true,“action”:“off”}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/status?
username=admin&password=secret&bmc_provider=ipmitool ===>
{“result”:“off”,“action”:“status”}

GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config?username=admin&password=secret&bmc_provider=ipmitool ===>
{“functions”:[“bootdevices”]}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevices?username=admin&password=secret&bmc_provider=ipmitool ===>
{“devices”:[“pxe”,“disk”,“cdrom”,“bios”]}

GET
http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/?username=admin&password=secret&bmc_provider=ipmitool ===>
{“actions”:[“ip”,“subnet”,“mac”,“gateway”]}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/ip?username=admin&password=secret&bmc_provider=ipmitool
===> {“result”:“192.168.1.41”,“action”:“ip”}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/mac?username=admin&password=secret&bmc_provider=ipmitool ====>
{“result”:“00:17:a4:49:ab:70”,“action”:“mac”}

Want to turn a system on?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on ===> {“result”:true,“action”:“on”}

Want to boot to pxe?
curl -X PUT -d
“username=admin&password=secret&bmc_provider=ipmitool&reboot=true”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevice/pxe ===> {“result”:true,“action”:“pxe”}

Want to cycle power?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/cycle ===> {“result”:true,“action”:“cycle”}

Forgot what actions you have when using PUT?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===> {“actions”:[“on”,“off”,“cycle”,“soft”]}

Want to turn the identify light on?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on ===> {“result”:true,“action”:“on”}

Did you goof up with some command?
GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on?username=admin&password=secret&bmc_provider=ipmitool===> {“error”:“The
action: on is not a valid action”}

How to test the ipmi branch:

git clone GitHub - logicminds/smart-proxy: RESTful proxies for DNS, DHCP, TFTP, BMC and Puppet
cd smart-proxy
git checkout ipmi (must checkout the ipmi branch)
gem install rubyipmi — on your smartproxy, currently 0.3.3
install freeipmi or ipmitool or both

Add the following lines to your smart proxy settings

enable BMC management (Bare metal power and bios controls)

Ensure that you have freeipmi or ipmitool command line tools installed

You will also need the rubyipmi gem

:bmc: true

Available bmc providers: freeipmi, ipmitool (optional)

#:bmc_default_provider: freeipmi

How to run the rake tests:

  1. enable bmc in the settings
  2. rake test TEST=test/bmc_api_test.rb ipmiuser=username
    ipmipass=password ipmihost=hostorip ipmiprovider=ipmitool
  3. rake test TEST=test/bmc_test.rb ipmiuser=username ipmipass=password
    ipmihost=hostorip ipmiprovider=ipmitool

If tests fail try the other provider. If you continue to have issues,
email me. Another important step is to keep your bmc firmware updated
since this could fix ipmi errors.

Feedback?

awesome!

Ohad

Thanks,

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

On Aug 6, 2012, at 11:32 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Tue, Aug 7, 2012 at 12:08 AM, Corey Osman corey@logicminds.bizwrote:

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

On Aug 4, 2012, at 11:43 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Sat, Aug 4, 2012 at 4:26 AM, Corey Osman corey@logicminds.bizwrote:

I have added BMC support to smart proxy so that we can control a
system’s bmc/ipmi interface through http calls.

Awesome!!!

The smart proxy will have support for both freeipmi and ipmitool as its
important to support both ipmi providers. However, currently only freeipmi
is supported, but ipmitool will be trivial to add later.

Essentially if you want to control a system you would use the following
calls:

http://smartproxy:8443/bmc/ipmidevice/function/action

this looks good, what about getting the current state?

Yea, I can add the state for each function.

Example:

curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/led/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/led/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/cycle
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/soft
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/boot/pxe
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/boot/disk

Do you think it makes more sense to support it via PUT (or even PATCH)
as http verbs instead of all in GET ?

Its actually a POST statement. I can do PUT as well if that seems more
restful. Not sure about patch though, I would be afraid that some 3rd
parties tools might not be able to support PATCH.

OK, I think PUT is the right answer for now, since there are workarounds
to send PUT via POST (thats how most browses do it anyway).

I would assume that GET would be the current state (as for above).

I still have a few more items to complete before making a pull
request and was hoping I can get some eyes on the code to spot any
potential issues.

Also I am thinking about requiring some sort encryption on the
password. What are your thoughts on encrypting the password?

Where? on foreman side? smart proxy ?

On the smart proxy side so that at least some level of security is
enforced, if people don’t use https.

Hmm… so it means you want to store the U/PW for every BMC device on the
proxy itself ?

Ohad

Also I am not sure how to handle errors, how do I log errors, should
I throw exceptions?

Currently, with other provides we do
return error code 4XX or 5XX errors
provide inside the json response an hash with errors

How do I ensure the user has the required gems installed and error

out if something is missing while providing helpful hits to what to install?
The BMC functionality will require freeipmi ruby wrapper gem and
freeipmi command line tools. Or if using ipmitool the ipmitool command
line tools and ipmitool ruby wrapper.

There are two ways to handle this issue:

  1. Using begin rescue
    e.g.

begin
require ‘gem’
rescue LoadError

oops, dont have the GEM, ignoring functionality

end

  1. using Bundler

in the past, we were trying to avoid bundler, mostly because it can’t
run on older platforms (e.g. require rubygems etc that dont exists on RHEL4
etc).
however, I think that if we add the bundler part with the same way we do
#1 above, then it would have a few more benefits:

  1. we get all the gems we need for people who uses bundler
  2. we can use bundler groups, and have the same concepts
    like packaging for foreman
  3. we can easily add the gems for windows (which has been an burden so
    far).

afair, there is an existing ticket for the proxy with bundler, maybe
just need to apply the rescue LoadError logic to it and we are more or less
done.

smart proxy code:
https://github.com/logicminds/smart-proxy/commit/baee452c3c242b0e377cb0565e1f82c31c8fc82e

Code looks really good :slight_smile:

Ohad

freeipmi ruby wrapper : https://github.com/logicminds/ruby-freeipmi

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

I've spend a few good hours on this today, attached is my changes to your
commit.

I was unable to get all tests running reliably on both ipmitool and
freeipmi, it might be some internal caching of the gem alongside with tests.

What do you think?

Thanks,
Ohad

··· On Fri, Aug 17, 2012 at 12:38 PM, Romain Vrignaud wrote:

I tested it on DELL PowerEdge servers.
It worked fine.
Really excited to see it integrated on Foreman.
What would be also awesome is to get VNC console directly on Foreman.

Thank you Corey for your really great job !

Romain

2012/8/16 Ohad Levy ohadlevy@gmail.com

On Thu, Aug 16, 2012 at 2:51 AM, Corey Osman corey@logicminds.bizwrote:

I decided to add support for both ipmitool and freeipmi since ipmitool
doesn’t perform CRC checks and some devices will return bad data that
freeipmi checks and returns errors.

Originally I created a ruby-freeipmi library which I then combined into
a new library with ipmitool. This new library is called rubyipmi (
GitHub - logicminds/rubyipmi: Command line wrapper for ipmitool and freeipmi ). Currently rubyipmi only
supports a few major functions ( power, lan, bmc, boot) which should be
everything foreman needs. As time goes on I hope to add more functions
that will be outside the scope of foreman (sensors, user controls, …).

The cool think about rubyipmi is that it will automatically find the
ipmi provider (ipmitool, freeipmi) you have installed if you don’t specify
the provider type.

will you allow to force a provider? or it should be auto detected
always?

I would suggest that both providers be installed on the smart-proxy as
ipmi device support with be a hit/miss with each provider.

Smart proxy bmc support is fully functional with a few exceptions:

– I have not added support to set the bmc lan device. Although
rubyipmi supports setting the bmc lan device, I need to do lots of testing
in order to catch any potential issues with setting network parameters.
– Is given ip pingable? Whoops, don’t create a IP collision.
– Will subnet and gateway address result in a bmc device not being able
to talk to anyone?
– What happens when you set the gateway without changing the IP?
– What happens when you set the subnet without changing the IP and
gateway?

I’m not 100% sure if this within scope of the api, afterall, you could
use the impitool to do the same (and the whole point is to make it
accessible via a rest api), imho, such logic should be done elsewhere.

– Security:

Currently username/password is only supported. Additionally, freeipmi
allows one to configure a freeipmi.conf with credentials which gets around
passing credentials. However, I see further security issues when freeipmi
has credentials supplied in the freeipmi.conf file.
The main problem here is that not all bmc devices will support the
same security measures. However, 100% will allow username/password, while
others will also support ssl certs, ssh keys, radius, and ldap.
Eventually, we will want foreman to provision each host to automatically
setup security using ssl and or username/password using openipmi.

I would leave the current proxy ACL (allowed hostlist +
SSL verification) - I think its good enough for first run, granted, that
the API user would need to provide the username / password.

– Configuration from the actual host
There is an option to configure the ipmi device from the actual host OS.
This would require a special driver openipmi. I believe this type of
action should be done at provision time or during a puppet run. However,
one could set the bmc lan parameters and users from this method without an
IP or username/password.

If its a puppet module, then there would need to be a fact that displays
the bmc device ip. Foreman could then showcase the bmc ip and allow the
foreman UI to control IPMI functions through smart-proxy.

So this is the case when the proxy bmc wants to manage it self? I could
see this really useful when using a bare metal os.

I decided to program the api with a little bit of feedback built in.

For example:

A GET will retrieve the value of some bmc device function that simply
reads data
A PUT will perform a function on the bmc device

If you can’t remember how to make a call then the api will return some
help

Example

GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===>
{“actions”:[“on”,“off”,“status”]}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on?username=admin&password=secret&bmc_provider=ipmitool ===>
{“result”:false,“action”:“on”}

this has a negative side effect, where you would be posting your U/P and
it would be capture in logs.
maybe we should consider using http basic auth instead?

GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/off?username=admin&password=secret&bmc_provider=ipmitool ===>
{“result”:true,“action”:“off”}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/status?
username=admin&password=secret&bmc_provider=ipmitool ===>
{“result”:“off”,“action”:“status”}

GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config?username=admin&password=secret&bmc_provider=ipmitool ===>
{“functions”:[“bootdevices”]}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevices?username=admin&password=secret&bmc_provider=ipmitool ===>
{“devices”:[“pxe”,“disk”,“cdrom”,“bios”]}

GET
http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/?username=admin&password=secret&bmc_provider=ipmitool ===>
{“actions”:[“ip”,“subnet”,“mac”,“gateway”]}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/ip?username=admin&password=secret&bmc_provider=ipmitool
===> {“result”:“192.168.1.41”,“action”:“ip”}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/mac?username=admin&password=secret&bmc_provider=ipmitool ====>
{“result”:“00:17:a4:49:ab:70”,“action”:“mac”}

Want to turn a system on?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on ===> {“result”:true,“action”:“on”}

Want to boot to pxe?
curl -X PUT -d
“username=admin&password=secret&bmc_provider=ipmitool&reboot=true”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevice/pxe ===> {“result”:true,“action”:“pxe”}

Want to cycle power?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/cycle ===> {“result”:true,“action”:“cycle”}

Forgot what actions you have when using PUT?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===> {“actions”:[“on”,“off”,“cycle”,“soft”]}

Want to turn the identify light on?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on ===> {“result”:true,“action”:“on”}

Did you goof up with some command?
GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on?username=admin&password=secret&bmc_provider=ipmitool===> {“error”:“The
action: on is not a valid action”}

How to test the ipmi branch:

git clone GitHub - logicminds/smart-proxy: RESTful proxies for DNS, DHCP, TFTP, BMC and Puppet
cd smart-proxy
git checkout ipmi (must checkout the ipmi branch)
gem install rubyipmi — on your smartproxy, currently 0.3.3
install freeipmi or ipmitool or both

Add the following lines to your smart proxy settings

enable BMC management (Bare metal power and bios controls)

Ensure that you have freeipmi or ipmitool command line tools installed

You will also need the rubyipmi gem

:bmc: true

Available bmc providers: freeipmi, ipmitool (optional)

#:bmc_default_provider: freeipmi

How to run the rake tests:

  1. enable bmc in the settings
  2. rake test TEST=test/bmc_api_test.rb ipmiuser=username
    ipmipass=password ipmihost=hostorip ipmiprovider=ipmitool
  3. rake test TEST=test/bmc_test.rb ipmiuser=username ipmipass=password
    ipmihost=hostorip ipmiprovider=ipmitool

If tests fail try the other provider. If you continue to have issues,
email me. Another important step is to keep your bmc firmware updated
since this could fix ipmi errors.

Feedback?

awesome!

Ohad

Thanks,

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

On Aug 6, 2012, at 11:32 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Tue, Aug 7, 2012 at 12:08 AM, Corey Osman corey@logicminds.bizwrote:

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

On Aug 4, 2012, at 11:43 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Sat, Aug 4, 2012 at 4:26 AM, Corey Osman corey@logicminds.bizwrote:

I have added BMC support to smart proxy so that we can control a
system’s bmc/ipmi interface through http calls.

Awesome!!!

The smart proxy will have support for both freeipmi and ipmitool as
its important to support both ipmi providers. However, currently only
freeipmi is supported, but ipmitool will be trivial to add later.

Essentially if you want to control a system you would use the
following calls:

http://smartproxy:8443/bmc/ipmidevice/function/action

this looks good, what about getting the current state?

Yea, I can add the state for each function.

Example:

curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/led/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/led/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/cycle
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/power/soft
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/boot/pxe
curl -d “username=admin&password=secret123” http://172.16.220.132:8443
/bmc/192.168.1.41/boot/disk

Do you think it makes more sense to support it via PUT (or even PATCH)
as http verbs instead of all in GET ?

Its actually a POST statement. I can do PUT as well if that seems more
restful. Not sure about patch though, I would be afraid that some 3rd
parties tools might not be able to support PATCH.

OK, I think PUT is the right answer for now, since there are
workarounds to send PUT via POST (thats how most browses do it anyway).

I would assume that GET would be the current state (as for above).

I still have a few more items to complete before making a pull
request and was hoping I can get some eyes on the code to spot any
potential issues.

Also I am thinking about requiring some sort encryption on the
password. What are your thoughts on encrypting the password?

Where? on foreman side? smart proxy ?

On the smart proxy side so that at least some level of security is
enforced, if people don’t use https.

Hmm… so it means you want to store the U/PW for every BMC device on the
proxy itself ?

Ohad

Also I am not sure how to handle errors, how do I log errors,
should I throw exceptions?

Currently, with other provides we do
return error code 4XX or 5XX errors
provide inside the json response an hash with errors

How do I ensure the user has the required gems installed and error

out if something is missing while providing helpful hits to what to install?
The BMC functionality will require freeipmi ruby wrapper gem and
freeipmi command line tools. Or if using ipmitool the ipmitool command
line tools and ipmitool ruby wrapper.

There are two ways to handle this issue:

  1. Using begin rescue
    e.g.

begin
require ‘gem’
rescue LoadError

oops, dont have the GEM, ignoring functionality

end

  1. using Bundler

in the past, we were trying to avoid bundler, mostly because it can’t
run on older platforms (e.g. require rubygems etc that dont exists on RHEL4
etc).
however, I think that if we add the bundler part with the same way we
do #1 above, then it would have a few more benefits:

  1. we get all the gems we need for people who uses bundler
  2. we can use bundler groups, and have the same concepts
    like packaging for foreman
  3. we can easily add the gems for windows (which has been an burden so
    far).

afair, there is an existing ticket for the proxy with bundler, maybe
just need to apply the rescue LoadError logic to it and we are more or less
done.

smart proxy code:
https://github.com/logicminds/smart-proxy/commit/baee452c3c242b0e377cb0565e1f82c31c8fc82e

Code looks really good :slight_smile:

Ohad

freeipmi ruby wrapper : https://github.com/logicminds/ruby-freeipmi

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

Did you test on a BMC device? Many tests will fail if not testing on a bmc device.

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

··· On Aug 26, 2012, at 7:39 AM, Ohad Levy wrote:

I’ve spend a few good hours on this today, attached is my changes to your commit.

I was unable to get all tests running reliably on both ipmitool and freeipmi, it might be some internal caching of the gem alongside with tests.

What do you think?

Thanks,
Ohad

On Fri, Aug 17, 2012 at 12:38 PM, Romain Vrignaud rvrignaud@gmail.com wrote:
I tested it on DELL PowerEdge servers.
It worked fine.
Really excited to see it integrated on Foreman.
What would be also awesome is to get VNC console directly on Foreman.

Thank you Corey for your really great job !

Romain

2012/8/16 Ohad Levy ohadlevy@gmail.com

On Thu, Aug 16, 2012 at 2:51 AM, Corey Osman corey@logicminds.biz wrote:
I decided to add support for both ipmitool and freeipmi since ipmitool doesn’t perform CRC checks and some devices will return bad data that freeipmi checks and returns errors.

Originally I created a ruby-freeipmi library which I then combined into a new library with ipmitool. This new library is called rubyipmi ( GitHub - logicminds/rubyipmi: Command line wrapper for ipmitool and freeipmi ). Currently rubyipmi only supports a few major functions ( power, lan, bmc, boot) which should be everything foreman needs. As time goes on I hope to add more functions that will be outside the scope of foreman (sensors, user controls, …).

The cool think about rubyipmi is that it will automatically find the ipmi provider (ipmitool, freeipmi) you have installed if you don’t specify the provider type.

will you allow to force a provider? or it should be auto detected always?

I would suggest that both providers be installed on the smart-proxy as ipmi device support with be a hit/miss with each provider.

Smart proxy bmc support is fully functional with a few exceptions:

– I have not added support to set the bmc lan device. Although rubyipmi supports setting the bmc lan device, I need to do lots of testing in order to catch any potential issues with setting network parameters.
– Is given ip pingable? Whoops, don’t create a IP collision.
– Will subnet and gateway address result in a bmc device not being able to talk to anyone?
– What happens when you set the gateway without changing the IP?
– What happens when you set the subnet without changing the IP and gateway?

I’m not 100% sure if this within scope of the api, afterall, you could use the impitool to do the same (and the whole point is to make it accessible via a rest api), imho, such logic should be done elsewhere.

– Security:
Currently username/password is only supported. Additionally, freeipmi allows one to configure a freeipmi.conf with credentials which gets around passing credentials. However, I see further security issues when freeipmi has credentials supplied in the freeipmi.conf file.
The main problem here is that not all bmc devices will support the same security measures. However, 100% will allow username/password, while others will also support ssl certs, ssh keys, radius, and ldap. Eventually, we will want foreman to provision each host to automatically setup security using ssl and or username/password using openipmi.

I would leave the current proxy ACL (allowed hostlist + SSL verification) - I think its good enough for first run, granted, that the API user would need to provide the username / password.

– Configuration from the actual host
There is an option to configure the ipmi device from the actual host OS. This would require a special driver openipmi. I believe this type of action should be done at provision time or during a puppet run. However, one could set the bmc lan parameters and users from this method without an IP or username/password.

If its a puppet module, then there would need to be a fact that displays the bmc device ip. Foreman could then showcase the bmc ip and allow the foreman UI to control IPMI functions through smart-proxy.

So this is the case when the proxy bmc wants to manage it self? I could see this really useful when using a bare metal os.

I decided to program the api with a little bit of feedback built in.

For example:

A GET will retrieve the value of some bmc device function that simply reads data
A PUT will perform a function on the bmc device

If you can’t remember how to make a call then the api will return some help

Example

GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===> {“actions”:[“on”,“off”,“status”]}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on?username=admin&password=secret&bmc_provider=ipmitool ===> {“result”:false,“action”:“on”}
this has a negative side effect, where you would be posting your U/P and it would be capture in logs.
maybe we should consider using http basic auth instead?

GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/off?username=admin&password=secret&bmc_provider=ipmitool ===> {“result”:true,“action”:“off”}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/status?username=admin&password=secret&bmc_provider=ipmitool ===> {“result”:“off”,“action”:“status”}

GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config?username=admin&password=secret&bmc_provider=ipmitool ===> {“functions”:[“bootdevices”]}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevices?username=admin&password=secret&bmc_provider=ipmitool ===> {“devices”:[“pxe”,“disk”,“cdrom”,“bios”]}

GET http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/?username=admin&password=secret&bmc_provider=ipmitool ===> {“actions”:[“ip”,“subnet”,“mac”,“gateway”]}
GET http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/ip?username=admin&password=secret&bmc_provider=ipmitool ===> {“result”:“192.168.1.41”,“action”:“ip”}
GET http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/mac?username=admin&password=secret&bmc_provider=ipmitool ====> {“result”:“00:17:a4:49:ab:70”,“action”:“mac”}

Want to turn a system on?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool” http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on ===> {“result”:true,“action”:“on”}

Want to boot to pxe?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool&reboot=true” http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevice/pxe ===> {“result”:true,“action”:“pxe”}

Want to cycle power?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool” http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/cycle ===> {“result”:true,“action”:“cycle”}

Forgot what actions you have when using PUT?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool” http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===> {“actions”:[“on”,“off”,“cycle”,“soft”]}

Want to turn the identify light on?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool” http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on ===> {“result”:true,“action”:“on”}

Did you goof up with some command?
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on?username=admin&password=secret&bmc_provider=ipmitool ===> {“error”:“The action: on is not a valid action”}

How to test the ipmi branch:

git clone GitHub - logicminds/smart-proxy: RESTful proxies for DNS, DHCP, TFTP, BMC and Puppet
cd smart-proxy
git checkout ipmi (must checkout the ipmi branch)
gem install rubyipmi — on your smartproxy, currently 0.3.3
install freeipmi or ipmitool or both

Add the following lines to your smart proxy settings

enable BMC management (Bare metal power and bios controls)

Ensure that you have freeipmi or ipmitool command line tools installed

You will also need the rubyipmi gem

:bmc: true

Available bmc providers: freeipmi, ipmitool (optional)

#:bmc_default_provider: freeipmi

How to run the rake tests:

  1. enable bmc in the settings
  2. rake test TEST=test/bmc_api_test.rb ipmiuser=username ipmipass=password ipmihost=hostorip ipmiprovider=ipmitool
  3. rake test TEST=test/bmc_test.rb ipmiuser=username ipmipass=password ipmihost=hostorip ipmiprovider=ipmitool

If tests fail try the other provider. If you continue to have issues, email me. Another important step is to keep your bmc firmware updated since this could fix ipmi errors.

Feedback?

awesome!

Ohad
Thanks,

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

On Aug 6, 2012, at 11:32 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Tue, Aug 7, 2012 at 12:08 AM, Corey Osman corey@logicminds.biz wrote:

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

On Aug 4, 2012, at 11:43 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Sat, Aug 4, 2012 at 4:26 AM, Corey Osman corey@logicminds.biz wrote:
I have added BMC support to smart proxy so that we can control a system’s bmc/ipmi interface through http calls.
Awesome!!!

The smart proxy will have support for both freeipmi and ipmitool as its important to support both ipmi providers. However, currently only freeipmi is supported, but ipmitool will be trivial to add later.

Essentially if you want to control a system you would use the following calls:

http://smartproxy:8443/bmc/ipmidevice/function/action

this looks good, what about getting the current state?

Yea, I can add the state for each function.

Example:

curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/led/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/led/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/cycle
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/soft
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/boot/pxe
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/boot/disk

Do you think it makes more sense to support it via PUT (or even PATCH) as http verbs instead of all in GET ?

Its actually a POST statement. I can do PUT as well if that seems more restful. Not sure about patch though, I would be afraid that some 3rd parties tools might not be able to support PATCH.

OK, I think PUT is the right answer for now, since there are workarounds to send PUT via POST (thats how most browses do it anyway).

I would assume that GET would be the current state (as for above).

I still have a few more items to complete before making a pull request and was hoping I can get some eyes on the code to spot any potential issues.

Also I am thinking about requiring some sort encryption on the password. What are your thoughts on encrypting the password?
Where? on foreman side? smart proxy ?

On the smart proxy side so that at least some level of security is enforced, if people don’t use https.

Hmm… so it means you want to store the U/PW for every BMC device on the proxy itself ?

Ohad

Also I am not sure how to handle errors, how do I log errors, should I throw exceptions?

Currently, with other provides we do
return error code 4XX or 5XX errors
provide inside the json response an hash with errors

How do I ensure the user has the required gems installed and error out if something is missing while providing helpful hits to what to install?
The BMC functionality will require freeipmi ruby wrapper gem and freeipmi command line tools. Or if using ipmitool the ipmitool command line tools and ipmitool ruby wrapper.

There are two ways to handle this issue:

  1. Using begin rescue
    e.g.

begin
require ‘gem’
rescue LoadError

oops, dont have the GEM, ignoring functionality

end

  1. using Bundler

in the past, we were trying to avoid bundler, mostly because it can’t run on older platforms (e.g. require rubygems etc that dont exists on RHEL4 etc).
however, I think that if we add the bundler part with the same way we do #1 above, then it would have a few more benefits:

  1. we get all the gems we need for people who uses bundler
  2. we can use bundler groups, and have the same concepts like packaging for foreman
  3. we can easily add the gems for windows (which has been an burden so far).

afair, there is an existing ticket for the proxy with bundler, maybe just need to apply the rescue LoadError logic to it and we are more or less done.

smart proxy code: https://github.com/logicminds/smart-proxy/commit/baee452c3c242b0e377cb0565e1f82c31c8fc82e

Code looks really good :slight_smile:

Ohad

freeipmi ruby wrapper : https://github.com/logicminds/ruby-freeipmi

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

<0001-refactoring.patch>

> Did you test on a BMC device? Many tests will fail if not testing on a
> bmc device.
>
ofcourse :slight_smile: most of the ipmitool tests pass (besides one) but on freeimpi
quite a few does.

I'll try having another look tomorrow on the ipmi gem itself.

Thanks,
Ohad

··· On Sun, Aug 26, 2012 at 8:00 PM, Corey Osman wrote:

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

On Aug 26, 2012, at 7:39 AM, Ohad Levy ohadlevy@gmail.com wrote:

I’ve spend a few good hours on this today, attached is my changes to your
commit.

I was unable to get all tests running reliably on both ipmitool and
freeipmi, it might be some internal caching of the gem alongside with tests.

What do you think?

Thanks,
Ohad

On Fri, Aug 17, 2012 at 12:38 PM, Romain Vrignaud rvrignaud@gmail.comwrote:

I tested it on DELL PowerEdge servers.
It worked fine.
Really excited to see it integrated on Foreman.
What would be also awesome is to get VNC console directly on Foreman.

Thank you Corey for your really great job !

Romain

2012/8/16 Ohad Levy ohadlevy@gmail.com

On Thu, Aug 16, 2012 at 2:51 AM, Corey Osman corey@logicminds.bizwrote:

I decided to add support for both ipmitool and freeipmi since ipmitool
doesn’t perform CRC checks and some devices will return bad data that
freeipmi checks and returns errors.

Originally I created a ruby-freeipmi library which I then combined into
a new library with ipmitool. This new library is called rubyipmi (
GitHub - logicminds/rubyipmi: Command line wrapper for ipmitool and freeipmi ). Currently rubyipmi only
supports a few major functions ( power, lan, bmc, boot) which should be
everything foreman needs. As time goes on I hope to add more functions
that will be outside the scope of foreman (sensors, user controls, …).

The cool think about rubyipmi is that it will automatically find the
ipmi provider (ipmitool, freeipmi) you have installed if you don’t specify
the provider type.

will you allow to force a provider? or it should be auto detected
always?

I would suggest that both providers be installed on the smart-proxy as
ipmi device support with be a hit/miss with each provider.

Smart proxy bmc support is fully functional with a few exceptions:

– I have not added support to set the bmc lan device. Although
rubyipmi supports setting the bmc lan device, I need to do lots of testing
in order to catch any potential issues with setting network parameters.
– Is given ip pingable? Whoops, don’t create a IP collision.
– Will subnet and gateway address result in a bmc device not being
able to talk to anyone?
– What happens when you set the gateway without changing the IP?
– What happens when you set the subnet without changing the IP and
gateway?

I’m not 100% sure if this within scope of the api, afterall, you could
use the impitool to do the same (and the whole point is to make it
accessible via a rest api), imho, such logic should be done elsewhere.

– Security:

Currently username/password is only supported. Additionally, freeipmi
allows one to configure a freeipmi.conf with credentials which gets around
passing credentials. However, I see further security issues when freeipmi
has credentials supplied in the freeipmi.conf file.
The main problem here is that not all bmc devices will support the
same security measures. However, 100% will allow username/password, while
others will also support ssl certs, ssh keys, radius, and ldap.
Eventually, we will want foreman to provision each host to automatically
setup security using ssl and or username/password using openipmi.

I would leave the current proxy ACL (allowed hostlist +
SSL verification) - I think its good enough for first run, granted, that
the API user would need to provide the username / password.

– Configuration from the actual host
There is an option to configure the ipmi device from the actual host
OS. This would require a special driver openipmi. I believe this type of
action should be done at provision time or during a puppet run. However,
one could set the bmc lan parameters and users from this method without an
IP or username/password.

If its a puppet module, then there would need to be a fact that
displays the bmc device ip. Foreman could then showcase the bmc ip and
allow the foreman UI to control IPMI functions through smart-proxy.

So this is the case when the proxy bmc wants to manage it self? I could
see this really useful when using a bare metal os.

I decided to program the api with a little bit of feedback built in.

For example:

A GET will retrieve the value of some bmc device function that simply
reads data
A PUT will perform a function on the bmc device

If you can’t remember how to make a call then the api will return some
help

Example

GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===>
{“actions”:[“on”,“off”,“status”]}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on?username=admin&password=secret&bmc_provider=ipmitool ===>
{“result”:false,“action”:“on”}

this has a negative side effect, where you would be posting your U/P and
it would be capture in logs.
maybe we should consider using http basic auth instead?

GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/off?username=admin&password=secret&bmc_provider=ipmitool ===>
{“result”:true,“action”:“off”}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/status?
username=admin&password=secret&bmc_provider=ipmitool ===>
{“result”:“off”,“action”:“status”}

GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config?username=admin&password=secret&bmc_provider=ipmitool ===>
{“functions”:[“bootdevices”]}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevices?username=admin&password=secret&bmc_provider=ipmitool ===>
{“devices”:[“pxe”,“disk”,“cdrom”,“bios”]}

GET
http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/?username=admin&password=secret&bmc_provider=ipmitool ===>
{“actions”:[“ip”,“subnet”,“mac”,“gateway”]}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/ip?username=admin&password=secret&bmc_provider=ipmitool
===> {“result”:“192.168.1.41”,“action”:“ip”}
GET
http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/mac?username=admin&password=secret&bmc_provider=ipmitool ====>
{“result”:“00:17:a4:49:ab:70”,“action”:“mac”}

Want to turn a system on?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on ===> {“result”:true,“action”:“on”}

Want to boot to pxe?
curl -X PUT -d
“username=admin&password=secret&bmc_provider=ipmitool&reboot=true”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevice/pxe ===> {“result”:true,“action”:“pxe”}

Want to cycle power?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/cycle ===> {“result”:true,“action”:“cycle”}

Forgot what actions you have when using PUT?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===> {“actions”:[“on”,“off”,“cycle”,“soft”]}

Want to turn the identify light on?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool”
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on ===> {“result”:true,“action”:“on”}

Did you goof up with some command?
GET
http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on?username=admin&password=secret&bmc_provider=ipmitool===> {“error”:“The
action: on is not a valid action”}

How to test the ipmi branch:

git clone GitHub - logicminds/smart-proxy: RESTful proxies for DNS, DHCP, TFTP, BMC and Puppet
cd smart-proxy
git checkout ipmi (must checkout the ipmi branch)
gem install rubyipmi — on your smartproxy, currently 0.3.3
install freeipmi or ipmitool or both

Add the following lines to your smart proxy settings

enable BMC management (Bare metal power and bios controls)

Ensure that you have freeipmi or ipmitool command line tools installed

You will also need the rubyipmi gem

:bmc: true

Available bmc providers: freeipmi, ipmitool (optional)

#:bmc_default_provider: freeipmi

How to run the rake tests:

  1. enable bmc in the settings
  2. rake test TEST=test/bmc_api_test.rb ipmiuser=username
    ipmipass=password ipmihost=hostorip ipmiprovider=ipmitool
  3. rake test TEST=test/bmc_test.rb ipmiuser=username ipmipass=password
    ipmihost=hostorip ipmiprovider=ipmitool

If tests fail try the other provider. If you continue to have issues,
email me. Another important step is to keep your bmc firmware updated
since this could fix ipmi errors.

Feedback?

awesome!

Ohad

Thanks,

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

On Aug 6, 2012, at 11:32 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Tue, Aug 7, 2012 at 12:08 AM, Corey Osman corey@logicminds.bizwrote:

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

On Aug 4, 2012, at 11:43 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Sat, Aug 4, 2012 at 4:26 AM, Corey Osman corey@logicminds.bizwrote:

I have added BMC support to smart proxy so that we can control a
system’s bmc/ipmi interface through http calls.

Awesome!!!

The smart proxy will have support for both freeipmi and ipmitool as
its important to support both ipmi providers. However, currently only
freeipmi is supported, but ipmitool will be trivial to add later.

Essentially if you want to control a system you would use the
following calls:

http://smartproxy:8443/bmc/ipmidevice/function/action

this looks good, what about getting the current state?

Yea, I can add the state for each function.

Example:

curl -d “username=admin&password=secret123” http://172.16.220.132:
8443/bmc/192.168.1.41/led/off
curl -d “username=admin&password=secret123” http://172.16.220.132:
8443/bmc/192.168.1.41/led/on
curl -d “username=admin&password=secret123” http://172.16.220.132:
8443/bmc/192.168.1.41/power/on
curl -d “username=admin&password=secret123” http://172.16.220.132:
8443/bmc/192.168.1.41/power/off
curl -d “username=admin&password=secret123” http://172.16.220.132:
8443/bmc/192.168.1.41/power/cycle
curl -d “username=admin&password=secret123” http://172.16.220.132:
8443/bmc/192.168.1.41/power/soft
curl -d “username=admin&password=secret123” http://172.16.220.132:
8443/bmc/192.168.1.41/boot/pxe
curl -d “username=admin&password=secret123” http://172.16.220.132:
8443/bmc/192.168.1.41/boot/disk

Do you think it makes more sense to support it via PUT (or even
PATCH) as http verbs instead of all in GET ?

Its actually a POST statement. I can do PUT as well if that seems
more restful. Not sure about patch though, I would be afraid that some 3rd
parties tools might not be able to support PATCH.

OK, I think PUT is the right answer for now, since there are
workarounds to send PUT via POST (thats how most browses do it anyway).

I would assume that GET would be the current state (as for above).

I still have a few more items to complete before making a pull
request and was hoping I can get some eyes on the code to spot any
potential issues.

Also I am thinking about requiring some sort encryption on the
password. What are your thoughts on encrypting the password?

Where? on foreman side? smart proxy ?

On the smart proxy side so that at least some level of security is
enforced, if people don’t use https.

Hmm… so it means you want to store the U/PW for every BMC device on
the proxy itself ?

Ohad

Also I am not sure how to handle errors, how do I log errors,
should I throw exceptions?

Currently, with other provides we do
return error code 4XX or 5XX errors
provide inside the json response an hash with errors

How do I ensure the user has the required gems installed and error

out if something is missing while providing helpful hits to what to install?
The BMC functionality will require freeipmi ruby wrapper gem and
freeipmi command line tools. Or if using ipmitool the ipmitool command
line tools and ipmitool ruby wrapper.

There are two ways to handle this issue:

  1. Using begin rescue
    e.g.

begin
require ‘gem’
rescue LoadError

oops, dont have the GEM, ignoring functionality

end

  1. using Bundler

in the past, we were trying to avoid bundler, mostly because it can’t
run on older platforms (e.g. require rubygems etc that dont exists on RHEL4
etc).
however, I think that if we add the bundler part with the same way we
do #1 above, then it would have a few more benefits:

  1. we get all the gems we need for people who uses bundler
  2. we can use bundler groups, and have the same concepts
    like packaging for foreman
  3. we can easily add the gems for windows (which has been an burden so
    far).

afair, there is an existing ticket for the proxy with bundler, maybe
just need to apply the rescue LoadError logic to it and we are more or less
done.

smart proxy code:
https://github.com/logicminds/smart-proxy/commit/baee452c3c242b0e377cb0565e1f82c31c8fc82e

Code looks really good :slight_smile:

Ohad

freeipmi ruby wrapper : https://github.com/logicminds/ruby-freeipmi

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

<0001-refactoring.patch>

Since there was some confusion over using netmask vs subnet vs subnet mask I just changed to netmask. I had to update the change in rubyipmi but I haven't push the changes to rubygems yet. I am in the middle of adding sensor support and haven't finished testing yet. Will probably finish tonight and update rubygems with the changes. Look for 0.4.0 release of rubyipmi that adds sensor support and changes subnet to netmask function.

Alternatively, you could change:
rubyipmi/freeipmi/lan/ subnet function to netmask
rubyipmi/ipmitool/lan/ subnet function to netmask

until I finalize the changes.

All tests are passing for me through ipmitool. Freeipmi I still have tests that fail due to HP ilo issues and the freeipmi lib, but this is expected.

What tests are failing for you?

Thanks,

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

··· On Aug 26, 2012, at 10:14 AM, Ohad Levy wrote:

On Sun, Aug 26, 2012 at 8:00 PM, Corey Osman corey@logicminds.biz wrote:
Did you test on a BMC device? Many tests will fail if not testing on a bmc device.
ofcourse :slight_smile: most of the ipmitool tests pass (besides one) but on freeimpi quite a few does.

I’ll try having another look tomorrow on the ipmi gem itself.

Thanks,
Ohad

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

On Aug 26, 2012, at 7:39 AM, Ohad Levy ohadlevy@gmail.com wrote:

I’ve spend a few good hours on this today, attached is my changes to your commit.

I was unable to get all tests running reliably on both ipmitool and freeipmi, it might be some internal caching of the gem alongside with tests.

What do you think?

Thanks,
Ohad

On Fri, Aug 17, 2012 at 12:38 PM, Romain Vrignaud rvrignaud@gmail.com wrote:
I tested it on DELL PowerEdge servers.
It worked fine.
Really excited to see it integrated on Foreman.
What would be also awesome is to get VNC console directly on Foreman.

Thank you Corey for your really great job !

Romain

2012/8/16 Ohad Levy ohadlevy@gmail.com

On Thu, Aug 16, 2012 at 2:51 AM, Corey Osman corey@logicminds.biz wrote:
I decided to add support for both ipmitool and freeipmi since ipmitool doesn’t perform CRC checks and some devices will return bad data that freeipmi checks and returns errors.

Originally I created a ruby-freeipmi library which I then combined into a new library with ipmitool. This new library is called rubyipmi ( GitHub - logicminds/rubyipmi: Command line wrapper for ipmitool and freeipmi ). Currently rubyipmi only supports a few major functions ( power, lan, bmc, boot) which should be everything foreman needs. As time goes on I hope to add more functions that will be outside the scope of foreman (sensors, user controls, …).

The cool think about rubyipmi is that it will automatically find the ipmi provider (ipmitool, freeipmi) you have installed if you don’t specify the provider type.

will you allow to force a provider? or it should be auto detected always?

I would suggest that both providers be installed on the smart-proxy as ipmi device support with be a hit/miss with each provider.

Smart proxy bmc support is fully functional with a few exceptions:

– I have not added support to set the bmc lan device. Although rubyipmi supports setting the bmc lan device, I need to do lots of testing in order to catch any potential issues with setting network parameters.
– Is given ip pingable? Whoops, don’t create a IP collision.
– Will subnet and gateway address result in a bmc device not being able to talk to anyone?
– What happens when you set the gateway without changing the IP?
– What happens when you set the subnet without changing the IP and gateway?

I’m not 100% sure if this within scope of the api, afterall, you could use the impitool to do the same (and the whole point is to make it accessible via a rest api), imho, such logic should be done elsewhere.

– Security:
Currently username/password is only supported. Additionally, freeipmi allows one to configure a freeipmi.conf with credentials which gets around passing credentials. However, I see further security issues when freeipmi has credentials supplied in the freeipmi.conf file.
The main problem here is that not all bmc devices will support the same security measures. However, 100% will allow username/password, while others will also support ssl certs, ssh keys, radius, and ldap. Eventually, we will want foreman to provision each host to automatically setup security using ssl and or username/password using openipmi.

I would leave the current proxy ACL (allowed hostlist + SSL verification) - I think its good enough for first run, granted, that the API user would need to provide the username / password.

– Configuration from the actual host
There is an option to configure the ipmi device from the actual host OS. This would require a special driver openipmi. I believe this type of action should be done at provision time or during a puppet run. However, one could set the bmc lan parameters and users from this method without an IP or username/password.

If its a puppet module, then there would need to be a fact that displays the bmc device ip. Foreman could then showcase the bmc ip and allow the foreman UI to control IPMI functions through smart-proxy.

So this is the case when the proxy bmc wants to manage it self? I could see this really useful when using a bare metal os.

I decided to program the api with a little bit of feedback built in.

For example:

A GET will retrieve the value of some bmc device function that simply reads data
A PUT will perform a function on the bmc device

If you can’t remember how to make a call then the api will return some help

Example

GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===> {“actions”:[“on”,“off”,“status”]}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on?username=admin&password=secret&bmc_provider=ipmitool ===> {“result”:false,“action”:“on”}
this has a negative side effect, where you would be posting your U/P and it would be capture in logs.
maybe we should consider using http basic auth instead?

GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/off?username=admin&password=secret&bmc_provider=ipmitool ===> {“result”:true,“action”:“off”}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/status?username=admin&password=secret&bmc_provider=ipmitool ===> {“result”:“off”,“action”:“status”}

GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config?username=admin&password=secret&bmc_provider=ipmitool ===> {“functions”:[“bootdevices”]}
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevices?username=admin&password=secret&bmc_provider=ipmitool ===> {“devices”:[“pxe”,“disk”,“cdrom”,“bios”]}

GET http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/?username=admin&password=secret&bmc_provider=ipmitool ===> {“actions”:[“ip”,“subnet”,“mac”,“gateway”]}
GET http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/ip?username=admin&password=secret&bmc_provider=ipmitool ===> {“result”:“192.168.1.41”,“action”:“ip”}
GET http://172.16.220.144:8443/bmc/192.168.1.41/bmc/lan/mac?username=admin&password=secret&bmc_provider=ipmitool ====> {“result”:“00:17:a4:49:ab:70”,“action”:“mac”}

Want to turn a system on?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool” http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/on ===> {“result”:true,“action”:“on”}

Want to boot to pxe?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool&reboot=true” http://172.16.220.144:8443/bmc/192.168.1.41/chassis/config/bootdevice/pxe ===> {“result”:true,“action”:“pxe”}

Want to cycle power?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool” http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/cycle ===> {“result”:true,“action”:“cycle”}

Forgot what actions you have when using PUT?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool” http://172.16.220.144:8443/bmc/192.168.1.41/chassis/power/ ===> {“actions”:[“on”,“off”,“cycle”,“soft”]}

Want to turn the identify light on?
curl -X PUT -d “username=admin&password=secret&bmc_provider=ipmitool” http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on ===> {“result”:true,“action”:“on”}

Did you goof up with some command?
GET http://172.16.220.144:8443/bmc/192.168.1.41/chassis/identify/on?username=admin&password=secret&bmc_provider=ipmitool ===> {“error”:“The action: on is not a valid action”}

How to test the ipmi branch:

git clone GitHub - logicminds/smart-proxy: RESTful proxies for DNS, DHCP, TFTP, BMC and Puppet
cd smart-proxy
git checkout ipmi (must checkout the ipmi branch)
gem install rubyipmi — on your smartproxy, currently 0.3.3
install freeipmi or ipmitool or both

Add the following lines to your smart proxy settings

enable BMC management (Bare metal power and bios controls)

Ensure that you have freeipmi or ipmitool command line tools installed

You will also need the rubyipmi gem

:bmc: true

Available bmc providers: freeipmi, ipmitool (optional)

#:bmc_default_provider: freeipmi

How to run the rake tests:

  1. enable bmc in the settings
  2. rake test TEST=test/bmc_api_test.rb ipmiuser=username ipmipass=password ipmihost=hostorip ipmiprovider=ipmitool
  3. rake test TEST=test/bmc_test.rb ipmiuser=username ipmipass=password ipmihost=hostorip ipmiprovider=ipmitool

If tests fail try the other provider. If you continue to have issues, email me. Another important step is to keep your bmc firmware updated since this could fix ipmi errors.

Feedback?

awesome!

Ohad
Thanks,

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

On Aug 6, 2012, at 11:32 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Tue, Aug 7, 2012 at 12:08 AM, Corey Osman corey@logicminds.biz wrote:

Thanks,

Corey Osman
corey@logicminds.biz
678-348-0582 (Pacific Time)

Green IT and Data Center Automation Specialist

On Aug 4, 2012, at 11:43 PM, Ohad Levy ohadlevy@gmail.com wrote:

On Sat, Aug 4, 2012 at 4:26 AM, Corey Osman corey@logicminds.biz wrote:
I have added BMC support to smart proxy so that we can control a system’s bmc/ipmi interface through http calls.
Awesome!!!

The smart proxy will have support for both freeipmi and ipmitool as its important to support both ipmi providers. However, currently only freeipmi is supported, but ipmitool will be trivial to add later.

Essentially if you want to control a system you would use the following calls:

http://smartproxy:8443/bmc/ipmidevice/function/action

this looks good, what about getting the current state?

Yea, I can add the state for each function.

Example:

curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/led/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/led/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/on
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/off
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/cycle
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/power/soft
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/boot/pxe
curl -d “username=admin&password=secret123” http://172.16.220.132:8443/bmc/192.168.1.41/boot/disk

Do you think it makes more sense to support it via PUT (or even PATCH) as http verbs instead of all in GET ?

Its actually a POST statement. I can do PUT as well if that seems more restful. Not sure about patch though, I would be afraid that some 3rd parties tools might not be able to support PATCH.

OK, I think PUT is the right answer for now, since there are workarounds to send PUT via POST (thats how most browses do it anyway).

I would assume that GET would be the current state (as for above).

I still have a few more items to complete before making a pull request and was hoping I can get some eyes on the code to spot any potential issues.

Also I am thinking about requiring some sort encryption on the password. What are your thoughts on encrypting the password?
Where? on foreman side? smart proxy ?

On the smart proxy side so that at least some level of security is enforced, if people don’t use https.

Hmm… so it means you want to store the U/PW for every BMC device on the proxy itself ?

Ohad

Also I am not sure how to handle errors, how do I log errors, should I throw exceptions?

Currently, with other provides we do
return error code 4XX or 5XX errors
provide inside the json response an hash with errors

How do I ensure the user has the required gems installed and error out if something is missing while providing helpful hits to what to install?
The BMC functionality will require freeipmi ruby wrapper gem and freeipmi command line tools. Or if using ipmitool the ipmitool command line tools and ipmitool ruby wrapper.

There are two ways to handle this issue:

  1. Using begin rescue
    e.g.

begin
require ‘gem’
rescue LoadError

oops, dont have the GEM, ignoring functionality

end

  1. using Bundler

in the past, we were trying to avoid bundler, mostly because it can’t run on older platforms (e.g. require rubygems etc that dont exists on RHEL4 etc).
however, I think that if we add the bundler part with the same way we do #1 above, then it would have a few more benefits:

  1. we get all the gems we need for people who uses bundler
  2. we can use bundler groups, and have the same concepts like packaging for foreman
  3. we can easily add the gems for windows (which has been an burden so far).

afair, there is an existing ticket for the proxy with bundler, maybe just need to apply the rescue LoadError logic to it and we are more or less done.

smart proxy code: https://github.com/logicminds/smart-proxy/commit/baee452c3c242b0e377cb0565e1f82c31c8fc82e

Code looks really good :slight_smile:

Ohad

freeipmi ruby wrapper : https://github.com/logicminds/ruby-freeipmi

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

<0001-refactoring.patch>

for ipmitool

  1. Error:
    test_should_power_on(BmcTest):
    RuntimeError: Set Chassis Power Control to Up/On failed: Invalid data
    field in request
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/basecommand.rb:28:in
    findfix&#39; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:inruncmd'
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:12:in
    command&#39; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:19:inon'
    ./lib/proxy/bmc/ipmi.rb:37:in poweron&#39; /home/olevy/git/proxy/test/bmc_test.rb:39:intest_should_power_on'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    __send__&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:inrun'

98 tests, 144 assertions, 0 failures, 1 errors

and for freeipmi

  1. Failure:
    test_api_can_get_power_off(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:44:in
    test_api_can_get_power_off&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    `run']:
    Last response was not ok.
    <false> is not true.

  2. Failure:
    test_api_can_get_power_on_status(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:37:in
    test_api_can_get_power_on_status&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    `run']:
    Last response was not ok.
    <false> is not true.

  3. Failure:
    test_api_can_put_power_action(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:30:in
    test_api_can_put_power_action&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    `run']:
    Last response was not ok.
    <false> is not true.

  4. Failure:
    test_api_can_set_pxe_boot_device(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:88:in
    test_api_can_set_pxe_boot_device&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    `run']:
    <""> expected to be =~
    </true|false/>.

  5. Failure:
    test_should_bootbios(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:59:in test_should_bootbios&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    `run']:
    <nil> is not true.

  6. Failure:
    test_should_bootcdrom(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:63:in test_should_bootcdrom&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    `run']:
    <nil> is not true.

  7. Failure:
    test_should_bootdisk(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:55:in test_should_bootdisk&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    `run']:
    <nil> is not true.

  8. Failure:
    test_should_bootpxe(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:51:in test_should_bootpxe&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    `run']:
    <nil> is not true.

  9. Error:
    test_should_power_cycle(BmcTest):
    RuntimeError: off
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in
    findfix&#39; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:inruncmd'
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in
    command&#39; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:inoff'
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff&#39; /home/olevy/git/proxy/test/bmc_test.rb:71:incleanup'
    /home/olevy/git/proxy/test/bmc_test.rb:47:in test_should_power_cycle&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    `run'

  10. Error:
    test_should_power_off(BmcTest):
    RuntimeError: ok
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in
    findfix&#39; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:inruncmd'
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in
    command&#39; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:inoff'
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff&#39; /home/olevy/git/proxy/test/bmc_test.rb:34:intest_should_power_off'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    __send__&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:inrun'

  11. Error:
    test_should_power_on(BmcTest):
    RuntimeError: ok
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in
    findfix&#39; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:inruncmd'
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in
    command&#39; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:inoff'
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff&#39; /home/olevy/git/proxy/test/bmc_test.rb:71:incleanup'
    /home/olevy/git/proxy/test/bmc_test.rb:41:in test_should_power_on&#39; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
    `run'

98 tests, 139 assertions, 8 failures, 3 errors
rake aborted!
Command failed with status (1): [/usr/bin/ruby -I"lib:lib:test"
-I"/usr/lib…]

··· On 08/27/2012 01:51 AM, Corey Osman wrote: > > All tests are passing for me through ipmitool. Freeipmi I still have > tests that fail due to HP ilo issues and the freeipmi lib, but this is > expected. > > > What tests are failing for you? >

What is the make and model of server? What firmware version is the bmc device running? Are you able to update the firmware?

··· Sent from my iPhone

On Aug 27, 2012, at 6:03 AM, Ohad Levy ohadlevy@gmail.com wrote:

On 08/27/2012 01:51 AM, Corey Osman wrote:

All tests are passing for me through ipmitool. Freeipmi I still have tests that fail due to HP ilo issues and the freeipmi lib, but this is expected.

What tests are failing for you?
for ipmitool

  1. Error:
    test_should_power_on(BmcTest):
    RuntimeError: Set Chassis Power Control to Up/On failed: Invalid data field in request
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/basecommand.rb:28:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:12:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:19:in on’
    ./lib/proxy/bmc/ipmi.rb:37:in poweron' /home/olevy/git/proxy/test/bmc_test.rb:39:in test_should_power_on’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in __send__' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in run’

98 tests, 144 assertions, 0 failures, 1 errors

and for freeipmi

  1. Failure:
    test_api_can_get_power_off(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:44:in `test_api_can_get_power_off’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    Last response was not ok.
    is not true.

  2. Failure:
    test_api_can_get_power_on_status(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:37:in `test_api_can_get_power_on_status’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    Last response was not ok.
    is not true.

  3. Failure:
    test_api_can_put_power_action(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:30:in `test_api_can_put_power_action’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    Last response was not ok.
    is not true.

  4. Failure:
    test_api_can_set_pxe_boot_device(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:88:in `test_api_can_set_pxe_boot_device’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    <“”> expected to be =~
    </true|false/>.

  5. Failure:
    test_should_bootbios(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:59:in `test_should_bootbios’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  6. Failure:
    test_should_bootcdrom(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:63:in `test_should_bootcdrom’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  7. Failure:
    test_should_bootdisk(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:55:in `test_should_bootdisk’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  8. Failure:
    test_should_bootpxe(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:51:in `test_should_bootpxe’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  9. Error:
    test_should_power_cycle(BmcTest):
    RuntimeError: off
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in off’
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:71:in cleanup’
    /home/olevy/git/proxy/test/bmc_test.rb:47:in test_should_power_cycle' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’

  10. Error:
    test_should_power_off(BmcTest):
    RuntimeError: ok
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in off’
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:34:in test_should_power_off’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in __send__' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in run’

  11. Error:
    test_should_power_on(BmcTest):
    RuntimeError: ok
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in off’
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:71:in cleanup’
    /home/olevy/git/proxy/test/bmc_test.rb:41:in test_should_power_on' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’

98 tests, 139 assertions, 8 failures, 3 errors
rake aborted!
Command failed with status (1): [/usr/bin/ruby -I"lib:lib:test" -I"/usr/lib…]

>
> What is the make and model of server? What firmware version is the bmc
device running? Are you able to update the firmware?

IMHO, that testing needs to happen within the ipmi gem, and the proxy
should mock those requests (so no real changes are ever happening).

Ohad

>
>
>
>
> Sent from my iPhone
>
>
> >>
> >> All tests are passing for me through ipmitool. Freeipmi I still have
tests that fail due to HP ilo issues and the freeipmi lib, but this is
expected.
> >>
> >>
> >> What tests are failing for you?
> > for ipmitool
> >
> > 1) Error:
> > test_should_power_on(BmcTest):
> > RuntimeError: Set Chassis Power Control to Up/On failed: Invalid data
field in request
> >
/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/basecommand.rb:28:in
findfix&#39; &gt; &gt; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:inruncmd'
> >
/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:12:in
command&#39; &gt; &gt; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:19:inon'
> > ./lib/proxy/bmc/ipmi.rb:37:in poweron&#39; &gt; &gt; /home/olevy/git/proxy/test/bmc_test.rb:39:intest_should_power_on'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
__send__&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:inrun'
> >
> > 98 tests, 144 assertions, 0 failures, 1 errors
> >
> > and for freeipmi
> >
> > 1) Failure:
> > test_api_can_get_power_off(BmcApiTest)
> > [/home/olevy/git/proxy/test/bmc_api_test.rb:44:in
test_api_can_get_power_off&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
run&#39;]: &gt; &gt; Last response was not ok. &gt; &gt; &lt;false&gt; is not true. &gt; &gt; &gt; &gt; 2) Failure: &gt; &gt; test_api_can_get_power_on_status(BmcApiTest) &gt; &gt; [/home/olevy/git/proxy/test/bmc_api_test.rb:37:intest_api_can_get_power_on_status'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
__send__&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:inrun']:
> > Last response was not ok.
> > <false> is not true.
> >
> > 3) Failure:
> > test_api_can_put_power_action(BmcApiTest)
> > [/home/olevy/git/proxy/test/bmc_api_test.rb:30:in
test_api_can_put_power_action&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
run&#39;]: &gt; &gt; Last response was not ok. &gt; &gt; &lt;false&gt; is not true. &gt; &gt; &gt; &gt; 4) Failure: &gt; &gt; test_api_can_set_pxe_boot_device(BmcApiTest) &gt; &gt; [/home/olevy/git/proxy/test/bmc_api_test.rb:88:intest_api_can_set_pxe_boot_device'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
__send__&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:inrun']:
> > <""> expected to be =~
> > </true|false/>.
> >
> > 5) Failure:
> > test_should_bootbios(BmcTest)
> > [/home/olevy/git/proxy/test/bmc_test.rb:59:in test_should_bootbios&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
run&#39;]: &gt; &gt; &lt;nil&gt; is not true. &gt; &gt; &gt; &gt; 6) Failure: &gt; &gt; test_should_bootcdrom(BmcTest) &gt; &gt; [/home/olevy/git/proxy/test/bmc_test.rb:63:intest_should_bootcdrom'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
__send__&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:inrun']:
> > <nil> is not true.
> >
> > 7) Failure:
> > test_should_bootdisk(BmcTest)
> > [/home/olevy/git/proxy/test/bmc_test.rb:55:in test_should_bootdisk&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
run&#39;]: &gt; &gt; &lt;nil&gt; is not true. &gt; &gt; &gt; &gt; 8) Failure: &gt; &gt; test_should_bootpxe(BmcTest) &gt; &gt; [/home/olevy/git/proxy/test/bmc_test.rb:51:intest_should_bootpxe'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
__send__&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:inrun']:
> > <nil> is not true.
> >
> > 9) Error:
> > test_should_power_cycle(BmcTest):
> > RuntimeError: off
> >
/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in
findfix&#39; &gt; &gt; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:inruncmd'
> >
/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in
command&#39; &gt; &gt; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:inoff'
> > ./lib/proxy/bmc/ipmi.rb:31:in poweroff&#39; &gt; &gt; /home/olevy/git/proxy/test/bmc_test.rb:71:incleanup'
> > /home/olevy/git/proxy/test/bmc_test.rb:47:in
test_should_power_cycle&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
run&#39; &gt; &gt; &gt; &gt; 10) Error: &gt; &gt; test_should_power_off(BmcTest): &gt; &gt; RuntimeError: ok &gt; &gt; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:infindfix'
> >
/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in
runcmd&#39; &gt; &gt; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:incommand'
> >
/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in
off&#39; &gt; &gt; ./lib/proxy/bmc/ipmi.rb:31:inpoweroff'
> > /home/olevy/git/proxy/test/bmc_test.rb:34:in test_should_power_off&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:insend'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
run&#39; &gt; &gt; &gt; &gt; 11) Error: &gt; &gt; test_should_power_on(BmcTest): &gt; &gt; RuntimeError: ok &gt; &gt; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:infindfix'
> >
/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in
runcmd&#39; &gt; &gt; /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:incommand'
> >
/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in
off&#39; &gt; &gt; ./lib/proxy/bmc/ipmi.rb:31:inpoweroff'
> > /home/olevy/git/proxy/test/bmc_test.rb:71:in cleanup&#39; &gt; &gt; /home/olevy/git/proxy/test/bmc_test.rb:41:intest_should_power_on'
> >
/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
__send__&#39; &gt; &gt; /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:inrun'
> >
> > 98 tests, 139 assertions, 8 failures, 3 errors
> > rake aborted!
> > Command failed with status (1): [/usr/bin/ruby -I"lib:lib:test"
-I"/usr/lib…]

··· בתאריך 27 באוג 2012 18:46, מאת "Corey Osman" : > On Aug 27, 2012, at 6:03 AM, Ohad Levy wrote: > > On 08/27/2012 01:51 AM, Corey Osman wrote: > >

Ohad,

Unfortunately, that type of testing cannot be done. There is no way I can mock data coming back from the ipmi device as each ipmi device returns a slightly different packet of data. If I do mock the data it will only be good for that specific bmc device. The fact that you are having errors means there is a issue with your bmc device or bmc firmware version. This is to be expected though as manufactures shoe-horned ipmi support into their bmc devices and most likely never tested their implementation with any ipmi tool. I can't tell you how many revisions of firmware HP has gone through to fix IPMI related issues. This is precisely why I added special error handling in rubyipmi to automatically handle and resolve errors. I actually built in a error library that will try different "workarounds" given the error. However, the error library is very small right now until more users test and find workarounds with their devices.

IPMI is a standard but many devices don't follow the standard 100%. Additionally, many IPMI specifications are not required. So while a majority of bmc devices will work great, some devices may be incompatible or require work arounds or require a firmware upgrade to the bmc device and bios.

See: Manpage of ipmipower for more information regarding this subject.

If I knew the make, model and firmware revsion of your bmc device I can search google and possibly find a workaround or a known incompatibility and add to the error library.

Also what version of ipmitool and freeipmi are you using?

The first step is to run the impi command itself and see the problem:

ipmitool -U user -P pass -H hostname -I lanplus chassis power on

ipmipower --username=user --password=pass --hostname=hostname --driver-type=LAN_2_0 --on

use bmc-info to get firmware revision number

use ipmi-fru to get make / model information

Additionally, I am adding a function to rubyipmi to send diagnostic information to me for when this issue happens. Its unfortunate that IPMI is not a strict standard, but I think maintaining a error library with auto applied workarounds is the best course of action.

If you want to test at Rubyipmi level you can run:

rake ipmiuser=user ipmipass=pass ipmihost=hostname ipmiprovider=ipmitool or freeipmi

Thanks,

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

··· On Aug 27, 2012, at 9:45 AM, Ohad Levy wrote:

בתאריך 27 באוג 2012 18:46, מאת “Corey Osman” corey@logicminds.biz:

What is the make and model of server? What firmware version is the bmc device running? Are you able to update the firmware?

IMHO, that testing needs to happen within the ipmi gem, and the proxy should mock those requests (so no real changes are ever happening).

Ohad

Sent from my iPhone

On Aug 27, 2012, at 6:03 AM, Ohad Levy ohadlevy@gmail.com wrote:

On 08/27/2012 01:51 AM, Corey Osman wrote:

All tests are passing for me through ipmitool. Freeipmi I still have tests that fail due to HP ilo issues and the freeipmi lib, but this is expected.

What tests are failing for you?
for ipmitool

  1. Error:
    test_should_power_on(BmcTest):
    RuntimeError: Set Chassis Power Control to Up/On failed: Invalid data field in request
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/basecommand.rb:28:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:12:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:19:in on’
    ./lib/proxy/bmc/ipmi.rb:37:in poweron' /home/olevy/git/proxy/test/bmc_test.rb:39:in test_should_power_on’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in __send__' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in run’

98 tests, 144 assertions, 0 failures, 1 errors

and for freeipmi

  1. Failure:
    test_api_can_get_power_off(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:44:in `test_api_can_get_power_off’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    Last response was not ok.
    is not true.

  2. Failure:
    test_api_can_get_power_on_status(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:37:in `test_api_can_get_power_on_status’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    Last response was not ok.
    is not true.

  3. Failure:
    test_api_can_put_power_action(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:30:in `test_api_can_put_power_action’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    Last response was not ok.
    is not true.

  4. Failure:
    test_api_can_set_pxe_boot_device(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:88:in `test_api_can_set_pxe_boot_device’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    <“”> expected to be =~
    </true|false/>.

  5. Failure:
    test_should_bootbios(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:59:in `test_should_bootbios’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  6. Failure:
    test_should_bootcdrom(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:63:in `test_should_bootcdrom’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  7. Failure:
    test_should_bootdisk(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:55:in `test_should_bootdisk’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  8. Failure:
    test_should_bootpxe(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:51:in `test_should_bootpxe’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  9. Error:
    test_should_power_cycle(BmcTest):
    RuntimeError: off
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in off’
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:71:in cleanup’
    /home/olevy/git/proxy/test/bmc_test.rb:47:in test_should_power_cycle' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’

  10. Error:
    test_should_power_off(BmcTest):
    RuntimeError: ok
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in off’
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:34:in test_should_power_off’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in __send__' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in run’

  11. Error:
    test_should_power_on(BmcTest):
    RuntimeError: ok
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in off’
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:71:in cleanup’
    /home/olevy/git/proxy/test/bmc_test.rb:41:in test_should_power_on' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’

98 tests, 139 assertions, 8 failures, 3 errors
rake aborted!
Command failed with status (1): [/usr/bin/ruby -I"lib:lib:test" -I"/usr/lib…]

> Ohad,
>
> Unfortunately, that type of testing cannot be done. There is no way I
> can mock data coming back from the ipmi device as each ipmi device returns
> a slightly different packet of data. If I do mock the data it will only be
> good for that specific bmc device. The fact that you are having errors
> means there is a issue with your bmc device or bmc firmware version. This
> is to be expected though as manufactures shoe-horned ipmi support into
> their bmc devices and most likely never tested their implementation with
> any ipmi tool. I can't tell you how many revisions of firmware HP has gone
> through to fix IPMI related issues. This is precisely why I added special
> error handling in rubyipmi to automatically handle and resolve errors. I
> actually built in a error library that will try different "workarounds"
> given the error. However, the error library is very small right now until
> more users test and find workarounds with their devices.
>

Corey, I get it, but what I'm saying is a bit different imho.

Testing the api code in the proxy nearly need to mean, make sure that that
specific class instance is called, and the result is true or false (e.g. I
requested a power off, and it should call power off) so you could easily
mock out the powreoff command to return true and your test is successful.

One of the reasons I like the fact that you separated the ipmi stuff into a
gem, is that it allows it to be useful in many ways, and that the problem
domain (just as you describe it) is not simple.

imho I think that either we should mock the calls to the gem, or you could
provide a mocked mode in your gem, where the real calls are not made (just
like fog does it).

what do you think?

ps. its an hp server, I'm offline, but I can figure out the hw specs /
versions tomorrow.
and, the power off / on commands did work via the api, just the tests did
not.

Ohad

··· On Mon, Aug 27, 2012 at 8:21 PM, Corey Osman wrote:

IPMI is a standard but many devices don’t follow the standard 100%.
Additionally, many IPMI specifications are not required. So while a
majority of bmc devices will work great, some devices may be incompatible
or require work arounds or require a firmware upgrade to the bmc device and
bios.

See: Manpage of ipmipower for more information regarding this subject.

If I knew the make, model and firmware revsion of your bmc device I can
search google and possibly find a workaround or a known incompatibility and
add to the error library.

Also what version of ipmitool and freeipmi are you using?

The first step is to run the impi command itself and see the problem:

ipmitool -U user -P pass -H hostname -I lanplus chassis power on

ipmipower --username=user --password=pass --hostname=hostname
–driver-type=LAN_2_0 --on

use bmc-info to get firmware revision number

use ipmi-fru to get make / model information

Additionally, I am adding a function to rubyipmi to send diagnostic
information to me for when this issue happens. Its unfortunate that IPMI
is not a strict standard, but I think maintaining a error library with auto
applied workarounds is the best course of action.

If you want to test at Rubyipmi level you can run:

rake ipmiuser=user ipmipass=pass ipmihost=hostname ipmiprovider=ipmitool
or freeipmi

Thanks,

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

On Aug 27, 2012, at 9:45 AM, Ohad Levy ohadlevy@gmail.com wrote:

בתאריך 27 באוג 2012 18:46, מאת “Corey Osman” corey@logicminds.biz:

What is the make and model of server? What firmware version is the bmc
device running? Are you able to update the firmware?

IMHO, that testing needs to happen within the ipmi gem, and the proxy
should mock those requests (so no real changes are ever happening).

Ohad

Sent from my iPhone

On Aug 27, 2012, at 6:03 AM, Ohad Levy ohadlevy@gmail.com wrote:

On 08/27/2012 01:51 AM, Corey Osman wrote:

All tests are passing for me through ipmitool. Freeipmi I still have
tests that fail due to HP ilo issues and the freeipmi lib, but this is
expected.

What tests are failing for you?
for ipmitool

  1. Error:
    test_should_power_on(BmcTest):
    RuntimeError: Set Chassis Power Control to Up/On failed: Invalid data
    field in request

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/basecommand.rb:28:in
`findfix’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in
`runcmd’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:12:in
`command’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:19:in
`on’

./lib/proxy/bmc/ipmi.rb:37:in poweron' /home/olevy/git/proxy/test/bmc_test.rb:39:in test_should_power_on’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’

98 tests, 144 assertions, 0 failures, 1 errors

and for freeipmi

  1. Failure:
    test_api_can_get_power_off(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:44:in
    `test_api_can_get_power_off’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’]:

Last response was not ok.
is not true.

  1. Failure:
    test_api_can_get_power_on_status(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:37:in
    `test_api_can_get_power_on_status’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’]:

Last response was not ok.
is not true.

  1. Failure:
    test_api_can_put_power_action(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:30:in
    `test_api_can_put_power_action’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’]:

Last response was not ok.
is not true.

  1. Failure:
    test_api_can_set_pxe_boot_device(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:88:in
    `test_api_can_set_pxe_boot_device’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’]:

<“”> expected to be =~
</true|false/>.

  1. Failure:
    test_should_bootbios(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:59:in `test_should_bootbios’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’]:

is not true.

  1. Failure:
    test_should_bootcdrom(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:63:in
    `test_should_bootcdrom’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’]:

is not true.

  1. Failure:
    test_should_bootdisk(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:55:in `test_should_bootdisk’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’]:

is not true.

  1. Failure:
    test_should_bootpxe(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:51:in `test_should_bootpxe’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’]:

is not true.

  1. Error:
    test_should_power_cycle(BmcTest):
    RuntimeError: off

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in
`findfix’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in
`runcmd’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in
`command’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in
`off’

./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:71:in cleanup’
/home/olevy/git/proxy/test/bmc_test.rb:47:in
`test_should_power_cycle’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’

  1. Error:
    test_should_power_off(BmcTest):
    RuntimeError: ok

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in
`findfix’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in
`runcmd’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in
`command’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in
`off’

./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:34:in test_should_power_off’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’

  1. Error:
    test_should_power_on(BmcTest):
    RuntimeError: ok

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in
`findfix’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in
`runcmd’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in
`command’

/home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in
`off’

./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:71:in cleanup’
/home/olevy/git/proxy/test/bmc_test.rb:41:in `test_should_power_on’

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`send

/home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in
`run’

98 tests, 139 assertions, 8 failures, 3 errors
rake aborted!
Command failed with status (1): [/usr/bin/ruby -I"lib:lib:test"
-I"/usr/lib…]

>
>
> Ohad,
>
> Unfortunately, that type of testing cannot be done. There is no way I can mock data coming back from the ipmi device as each ipmi device returns a slightly different packet of data. If I do mock the data it will only be good for that specific bmc device. The fact that you are having errors means there is a issue with your bmc device or bmc firmware version. This is to be expected though as manufactures shoe-horned ipmi support into their bmc devices and most likely never tested their implementation with any ipmi tool. I can't tell you how many revisions of firmware HP has gone through to fix IPMI related issues. This is precisely why I added special error handling in rubyipmi to automatically handle and resolve errors. I actually built in a error library that will try different "workarounds" given the error. However, the error library is very small right now until more users test and find workarounds with their devices.
>
> Corey, I get it, but what I'm saying is a bit different imho.
>
> Testing the api code in the proxy nearly need to mean, make sure that that specific class instance is called, and the result is true or false (e.g. I requested a power off, and it should call power off) so you could easily mock out the powreoff command to return true and your test is successful.
>
> One of the reasons I like the fact that you separated the ipmi stuff into a gem, is that it allows it to be useful in many ways, and that the problem domain (just as you describe it) is not simple.
>
> imho I think that either we should mock the calls to the gem, or you could provide a mocked mode in your gem, where the real calls are not made (just like fog does it).
>
> what do you think?
>
> ps. its an hp server, I'm offline, but I can figure out the hw specs / versions tomorrow.
> and, the power off / on commands did work via the api, just the tests did not.

Ohad, I refactored the smart-proxy tests so that it does not require the use of a bmc device to test, only the code and calls being made are tested. It was not necessary to mock or stub any values as rubyipmi returns exceptions that are expected in the tests when executed without a bmc device.
Additionally, I added error handling at the ipmi.rb level as it was solely handled at the bmc_api level before.

Check the pull request for the latest code.

I have also updated rubyipmi to version 0.5 which now includes a default enhanced security mechanism by using random password files. You can also use my Rubyipmi.printdiag method to gather diagnostic information.

··· On Aug 27, 2012, at 10:36 AM, Ohad Levy wrote: > On Mon, Aug 27, 2012 at 8:21 PM, Corey Osman wrote:

Ohad

IPMI is a standard but many devices don’t follow the standard 100%. Additionally, many IPMI specifications are not required. So while a majority of bmc devices will work great, some devices may be incompatible or require work arounds or require a firmware upgrade to the bmc device and bios.

See: Manpage of ipmipower for more information regarding this subject.

If I knew the make, model and firmware revsion of your bmc device I can search google and possibly find a workaround or a known incompatibility and add to the error library.

Also what version of ipmitool and freeipmi are you using?

The first step is to run the impi command itself and see the problem:

ipmitool -U user -P pass -H hostname -I lanplus chassis power on

ipmipower --username=user --password=pass --hostname=hostname --driver-type=LAN_2_0 --on

use bmc-info to get firmware revision number

use ipmi-fru to get make / model information

Additionally, I am adding a function to rubyipmi to send diagnostic information to me for when this issue happens. Its unfortunate that IPMI is not a strict standard, but I think maintaining a error library with auto applied workarounds is the best course of action.

If you want to test at Rubyipmi level you can run:

rake ipmiuser=user ipmipass=pass ipmihost=hostname ipmiprovider=ipmitool or freeipmi

Thanks,

Corey Osman
corey@logicminds.biz

Green IT and Data Center Automation Specialist

On Aug 27, 2012, at 9:45 AM, Ohad Levy ohadlevy@gmail.com wrote:

בתאריך 27 באוג 2012 18:46, מאת “Corey Osman” corey@logicminds.biz:

What is the make and model of server? What firmware version is the bmc device running? Are you able to update the firmware?

IMHO, that testing needs to happen within the ipmi gem, and the proxy should mock those requests (so no real changes are ever happening).

Ohad

Sent from my iPhone

On Aug 27, 2012, at 6:03 AM, Ohad Levy ohadlevy@gmail.com wrote:

On 08/27/2012 01:51 AM, Corey Osman wrote:

All tests are passing for me through ipmitool. Freeipmi I still have tests that fail due to HP ilo issues and the freeipmi lib, but this is expected.

What tests are failing for you?
for ipmitool

  1. Error:
    test_should_power_on(BmcTest):
    RuntimeError: Set Chassis Power Control to Up/On failed: Invalid data field in request
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/basecommand.rb:28:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:12:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/ipmitool/commands/power.rb:19:in on’
    ./lib/proxy/bmc/ipmi.rb:37:in poweron' /home/olevy/git/proxy/test/bmc_test.rb:39:in test_should_power_on’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in __send__' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in run’

98 tests, 144 assertions, 0 failures, 1 errors

and for freeipmi

  1. Failure:
    test_api_can_get_power_off(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:44:in `test_api_can_get_power_off’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    Last response was not ok.
    is not true.

  2. Failure:
    test_api_can_get_power_on_status(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:37:in `test_api_can_get_power_on_status’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    Last response was not ok.
    is not true.

  3. Failure:
    test_api_can_put_power_action(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:30:in `test_api_can_put_power_action’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    Last response was not ok.
    is not true.

  4. Failure:
    test_api_can_set_pxe_boot_device(BmcApiTest)
    [/home/olevy/git/proxy/test/bmc_api_test.rb:88:in `test_api_can_set_pxe_boot_device’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    <“”> expected to be =~
    </true|false/>.

  5. Failure:
    test_should_bootbios(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:59:in `test_should_bootbios’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  6. Failure:
    test_should_bootcdrom(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:63:in `test_should_bootcdrom’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  7. Failure:
    test_should_bootdisk(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:55:in `test_should_bootdisk’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  8. Failure:
    test_should_bootpxe(BmcTest)
    [/home/olevy/git/proxy/test/bmc_test.rb:51:in `test_should_bootpxe’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’]:
    is not true.

  9. Error:
    test_should_power_cycle(BmcTest):
    RuntimeError: off
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in off’
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:71:in cleanup’
    /home/olevy/git/proxy/test/bmc_test.rb:47:in test_should_power_cycle' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’

  10. Error:
    test_should_power_off(BmcTest):
    RuntimeError: ok
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in off’
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:34:in test_should_power_off’
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in __send__' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in run’

  11. Error:
    test_should_power_on(BmcTest):
    RuntimeError: ok
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/basecommand.rb:44:in findfix' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/commands/basecommand.rb:41:in runcmd’
    /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:11:in command' /home/olevy/.gem/gems/rubyipmi-0.4.0/lib/rubyipmi/freeipmi/commands/power.rb:23:in off’
    ./lib/proxy/bmc/ipmi.rb:31:in poweroff' /home/olevy/git/proxy/test/bmc_test.rb:71:in cleanup’
    /home/olevy/git/proxy/test/bmc_test.rb:41:in test_should_power_on' /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in send
    /home/olevy/.gem/gems/mocha-0.12.1/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:22:in `run’

98 tests, 139 assertions, 8 failures, 3 errors
rake aborted!
Command failed with status (1): [/usr/bin/ruby -I"lib:lib:test" -I"/usr/lib…]