Power IQ Client
Power IQ Rest API client for Power IQ 3.1. For a complete list of resources, routes, and methods available see the online Power IQ documentation (www.raritan.com/support/power-iq).
Installation
% gem install poweriq_client
Console
The Power IQ client comes with a interactive console. From the console you can make REST API calls to Power IQ. To run the console:
% poweriq_client
Options
Usage: poweriq_client [options]
-l, --less-typing Put resource objects in global namespace
(ie PowerIQ::Resource::Outlet becomes Outlet)
-c, --check-compatibility Check client compatibility with server
-u, --user [USER] User name for authentication
-p, --password [PASSWORD] Password for authentication
-s, --server [HOST] Host name or IP of Power IQ
Configuration
Create the file $HOME/.poweriq_client. The contents of the file should look similiar to below, adjusted to your Power IQ server:
default:
host: vm163
user: admin
password: raritan
If you do not use a configuration file, or the command line options above, you’ll need to provide the configuration manually:
% poweriq_client
>> PowerIQ::Configuration.configure("user"=>"foo","password"=>"bar","host"=>"vm150")
Examples
Start the client console:
% poweriq_client -u admin -p raritan -s vm163
Retrieve all outlets:
>> outlets_resource = PowerIQ::Resource::Outlet.new
https://vm163/api/v2/outlets
>> outlets_json = outlets_resource.get
Retrieve one outlet:
>> outlet_resource = PowerIQ::Resource::Outlet.new('/381')
https://vm163/api/v2/outlets/381
>> outlet_json = outlet_resource.get
Update an outlet:
>> outlet_resource = PowerIQ::Resource::Outlet.new('/381')
https://vm163/api/v2/outlets/381
>> outlet_json = outlet_resource.get
>> outlet_json['outlet']['outlet_name'] = "New Name"
>> outlet_resource.put outlet_json.to_json
Error Handling
When an error occurs during an API call, the Power IQ server will return an appropriate HTTP response code, and include a json response with error details. On the client side, an exception is thrown. Either the exception or the resource object can be used to reveal details about what went wrong:
>> outlet_resource = PowerIQ::Resource::Outlet.new('/381')
https://vm163/api/v2/outlets/381
>> outlet_json = outlet_resource.get
{
"outlet" => {
"id" => 381,
"outlet_id" => 11,
"outlet_name" => "Outlet 11",
"device_id" => nil,
"state" => "ON",
"pdu_id" => 40,
"reading" => {}
}
}
>> outlet_json['outlet']['outlet_name']="foo"
"foo"
>> outlet_resource.put outlet_json.to_json
RestClient::UnprocessableEntity: 422 Unprocessable Entity
from /Users/tba/.rvm/gems/ruby-1.9.2-p180@poweriq_client/gems/rest-client-1.6.7/lib/restclient/abstract_response.rb:48:in `return!'
from /Users/tba/Workspaces/local/poweriq_client/lib/poweriq_client/resource/base.rb:11:in `block in create'
from /Users/tba/.rvm/gems/ruby-1.9.2-p180@poweriq_client/gems/rest-client-1.6.7/lib/restclient/request.rb:228:in `call'
from /Users/tba/.rvm/gems/ruby-1.9.2-p180@poweriq_client/gems/rest-client-1.6.7/lib/restclient/request.rb:228:in `process_result'
from /Users/tba/.rvm/gems/ruby-1.9.2-p180@poweriq_client/gems/rest-client-1.6.7/lib/restclient/request.rb:178:in `block in transmit'
from /Users/tba/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/http.rb:627:in `start'
from /Users/tba/.rvm/gems/ruby-1.9.2-p180@poweriq_client/gems/rest-client-1.6.7/lib/restclient/request.rb:172:in `transmit'
from /Users/tba/.rvm/gems/ruby-1.9.2-p180@poweriq_client/gems/rest-client-1.6.7/lib/restclient/request.rb:64:in `execute'
from /Users/tba/.rvm/gems/ruby-1.9.2-p180@poweriq_client/gems/rest-client-1.6.7/lib/restclient/request.rb:33:in `execute'
from /Users/tba/.rvm/gems/ruby-1.9.2-p180@poweriq_client/gems/rest-client-1.6.7/lib/restclient/resource.rb:76:in `put'
from (irb):4
from bin/poweriq_client:66:in `<main>'
The resource will always hold the last response from the latest rest invocation:
>> outlet_resource.response.json
{
"error" => "Job::JobError",
"messages" => [
[0] "Job(ID:5) with 1 error(s) and status COMPLETED completed",
[1] "Confirmed existence of foo",
[2] "Confirmed existence of 192.168.45.234 for outlet foo.",
[3] "Retrieved plugin for 192.168.45.234.",
[4] "Failed to set outlet id: 381 label on PDU 192.168.45.234. PowerIQ was unable to reach 192.168.45.234."
],
"job" => {
"description" => nil,
"end_time" => "2011/11/06 00:56:47 +0000",
"has_errors" => true,
"id" => 5,
"start_time" => "2011/11/06 00:56:28 +0000",
"status" => "COMPLETED",
"user_id" => 1
},
"trace" => "/var/oculan/home/tba/rails/src/lib/messaging/job_polling.rb:31:...."
}
You can also catch the exception, and the exception will have the response object in it:
>> exc = nil
>> begin outlet_resource.put outlet_json.to_json; rescue => exc; end
>> exc.response.json
{
"error" => "Job::JobError",
"messages" => [
[0] "Job(ID:5) with 1 error(s) and status COMPLETED completed",
[1] "Confirmed existence of foo",
[2] "Confirmed existence of 192.168.45.234 for outlet foo.",
[3] "Retrieved plugin for 192.168.45.234.",
[4] "Failed to set outlet id: 381 label on PDU 192.168.45.234. PowerIQ was unable to reach 192.168.45.234."
],
"job" => {
"description" => nil,
"end_time" => "2011/11/06 00:56:47 +0000",
"has_errors" => true,
"id" => 5,
"start_time" => "2011/11/06 00:56:28 +0000",
"status" => "COMPLETED",
"user_id" => 1
},
"trace" => "/var/oculan/home/tba/rails/src/lib/messaging/job_polling.rb:31:...."
}
Jobs
Some resource actions will return a Job JSON structure. These actions either will always, or optionally execute asynchronously. In order to determine when a job has been completed, the server must be polled for job completeness. Methods on the job resource simplify this for you:
>> job = Job.new('/5')
https://vm163/api/v2/jobs/5
>> job.poll(:max=>12,:delay=>5)
true
>> job.response.json
{
"job" => {
"id" => 5,
"user_id" => 1,
"status" => "COMPLETED",
"description" => nil,
"start_time" => "2011/11/06 00:56:28 +0000",
"end_time" => "2011/11/06 00:56:47 +0000",
"has_errors" => true,
"percent_complete" => 1.0,
"completed" => true,
"last_message" => "Failed to set outlet id: 381 label on PDU 192.168.45.234. PowerIQ was unable to reach 192.168.45.234.",
"error_count" => 1
},
"job_messages" => [
[0] {
"id" => 15,
"unit_of_work" => 0.25,
"job_id" => 5,
"level" => "INFO",
"trace" => nil,
"start_time" => "2011/11/06 00:56:30 +0000",
"end_time" => nil,
"message_key" => ":magic.outlet_get_outlet_success",
"message_vars" => "{\"new_outlet_name\":\"foo\",\"_pdu_outlet_id\":\"381\"}",
"aborted" => false,
"message" => "Confirmed existence of Outlet 11"
},
[1] {
"id" => 16,
"unit_of_work" => 0.25,
"job_id" => 5,
"level" => "INFO",
"trace" => nil,
"start_time" => "2011/11/06 00:56:32 +0000",
"end_time" => nil,
"message_key" => ":magic.outlet_get_pdu_success",
"message_vars" => "{\"_pdu_id\":\"40\",\"new_outlet_name\":\"foo\",\"_pdu_outlet_id\":\"381\"}",
"aborted" => false,
"message" => "Confirmed existence of 192.168.45.234 for outlet Outlet 11."
},
[2] {
"id" => 17,
"unit_of_work" => 0.25,
"job_id" => 5,
"level" => "INFO",
"trace" => nil,
"start_time" => "2011/11/06 00:56:34 +0000",
"end_time" => nil,
"message_key" => ":magic.outlet_get_pdu_metadata_success",
"message_vars" => "{\"_pdu_id\":\"40\",\"new_outlet_name\":\"foo\",\"_pdu_outlet_id\":\"381\"}",
"aborted" => false,
"message" => "Retrieved plugin for 192.168.45.234."
},
[3] {
"id" => 18,
"unit_of_work" => 0.25,
"job_id" => 5,
"level" => "ERROR",
"trace" => "SNMP_ERROR_TIMEOUT",
"start_time" => "2011/11/06 00:56:47 +0000",
"end_time" => nil,
"message_key" => ":magic.outlet_rename_snmp_timeout",
"message_vars" => "{\"_pdu_id\":\"40\",\"new_outlet_name\":\"foo\",\"_pdu_outlet_id\":\"381\"}",
"aborted" => false,
"message" => "Failed to set outlet id: 381 label on PDU 192.168.45.234. PowerIQ was unable to reach 192.168.45.234."
}
]
}
-
job.poll(:max=>5,:delay=>10) where :max is the maximum number of times to poll for job completeness, and :delay is the
amount of seconds to pause between each poll
-
job.poll returns true if the job completed, false otherwise
-
job.poll will also automatically retrieve all job_messages after completion
Please refer to the online Power IQ documentation (www.raritan.com/support/power-iq) for a list of resources that optionally or require asynchrounous execution.
Development
The Power IQ rest client uses the rest-client gem, with some modifications to make it easier to query Power IQ resources. For now you’ll need to view the source code for more details, however the usage is essentially the same as you see in the interactive console examples above.
Contributing to Power IQ Client
-
Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet
-
Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it
-
Fork the project
-
Start a feature/bugfix branch
-
Commit and push until you are happy with your contribution
-
Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright
Copyright © 2011 Raritan, INC. See LICENSE.txt for further details.