class Moob::Idrac7

Constants

INFO_FIELDS

Public Class Methods

new(hostname, options = {}) click to toggle source
Calls superclass method Moob::BaseLom::new
# File lib/moob/idrac7.rb, line 24
def initialize hostname, options = {}
  super hostname, options
  @username ||= 'root'
  @password ||= 'calvin'
  @index = nil
end

Public Instance Methods

authenticate() click to toggle source
# File lib/moob/idrac7.rb, line 31
def authenticate
  @session.handle_cookies nil
  # Needed for new version of iDrac emb web server to even responde
  @session.headers['Accept-Language'] = 'en-US,en;q=0.8,sv;q=0.6'
  # idrac7 responds with a 404 if the request is sent for html is sent without encoding headers
  @session.headers['Accept-Encoding'] = 'gzip,deflate,sdch'

  login = @session.get 'login.html'

  raise ResponseError.new login unless login.status == 200

  auth = @session.post 'data/login', "user=#{@username}&password=#{@password}"

  raise ResponseError.new auth unless auth.status == 200

  auth.body =~ /<authResult>([^<]+)<\/authResult>/

  raise 'Cannot find auth result' unless $&
  raise "Auth failed with: \"#{auth.body}\"" unless $1 == "0"

  auth.body =~ /<forwardUrl>([^<]+)<\/forwardUrl>/

  raise 'Cannot find the authenticated index url after auth' unless $&

  @indexurl = $1

  #1.30.30 (Build 43) introduced a nag to change credentials. bypass it.

  if @indexurl =~ /defaultCred/
    @indexurl.gsub!(/defaultCred/,'index')
    Moob.inform "iDRAC recommends you should change the default credentials!"
  end

  Moob.inform "Requesting indexurl of #{@indexurl}"

  # someone decided it was a good idea to include a ST2 token in every XHR
  # request. We need it for a lot of our features.
  @authhash = @indexurl.split('?')[1]
  @authhash =~ /ST2=([0-9a-f]+)/
  @st2 = $1

  if @st2.nil?
      Moob.inform 'Trying to parse ST2 token from HTML page'

      @index = @session.get @indexurl
      @index.body =~ /var TOKEN_VALUE = "([0-9a-f]+)";/
      raise ResponseError.new @index unless @index.status == 200
      @st2 = $1
  end

  @session.headers['ST2'] = @st2

  return self
end
boot_on(level) click to toggle source
# File lib/moob/idrac7.rb, line 126
def boot_on level
  req = @session.post "data?set=vmBootOnce:1,firstBootDevice:#{level}", {}
  raise ResponseError.new req unless req.status == 200
  return nil
end
detect() click to toggle source
# File lib/moob/idrac7.rb, line 96
def detect
  begin
    home = @session.get 'login.html'
    home.body =~ /(Integrated Dell Remote Access Controller 7)|(iDRAC7)/
  rescue
    false
  end
end
drac_set_params(params) click to toggle source
# File lib/moob/idrac7.rb, line 207
def drac_set_params params
  params.each do |p,v|
    req = @session.post "data?set=#{p}:#{v}", {}
    raise ResponseError.new req unless req.status == 200
  end
  return nil
end
enable_ipmi() click to toggle source
# File lib/moob/idrac7.rb, line 203
def enable_ipmi
  drac_set_params({ 'ipmiLAN' => 1 })
end
fetch_console_preview() click to toggle source
# File lib/moob/idrac7.rb, line 218
def fetch_console_preview
  imgfile = Tempfile.new('console_preview')

  refreshreq = @session.get "data?get=consolepreview[auto%20#{Time.now.utc.to_i}]", {}

  raise ResponseError.new req unless refreshreq.status == 200

  req = @session.get_file "capconsole/scapture0.png?#{Time.now.utc.to_i}", imgfile.path

  raise ResponseError.new req unless req.status == 200

  content_type = req.headers['Content-type'] || req.headers['Content-Type']
  raise "Unexpected content type #{content_type}, expected 'image/' prefix" unless content_type =~ /image\//

  return imgfile, req.headers
end
get_infos(keys) click to toggle source
# File lib/moob/idrac7.rb, line 178
def get_infos keys
  Moob.inform "Requesting data?get=#{keys.join(',')}"
  infos = @session.post "data?get=#{keys.join(',')}", {}

  raise ResponseError.new infos unless infos.status == 200
  raise "The status isn't OK" unless infos.body =~ /<status>ok<\/status>/

  return Hash[keys.collect do |k|
    if infos.body =~ /<#{k}>(.*?)<\/#{k}>/
      [k, $1]
    else
      [k, nil]
    end
  end]
end
infos() click to toggle source
# File lib/moob/idrac7.rb, line 174
def infos
  return JSON.pretty_generate get_infos INFO_FIELDS
end
jnlp() click to toggle source
# File lib/moob/idrac7.rb, line 107
def jnlp
  # Request system name and hostname from data end-point
  req = get_infos ['sysDesc' ,'hostname']

  # eg escaped "idrac-A1BCD2E, PowerEdge R610, User:root"
  title = CGI::escape "#{req['hostname']}, #{req['sysDesc']}, User:#{@username}"

  viewer = @session.get "viewer.jnlp(#{@hostname}@0@#{title}@#{Time.now.to_i * 1000}@#{@authhash})"
  raise ResponseError.new viewer unless viewer.status == 200

  return viewer.body
end
logout() click to toggle source
# File lib/moob/idrac7.rb, line 86
def logout
  if @skiplogout
    Moob.inform 'Skipping logout...'
  else
    out = @session.get 'data/logout'
    raise ResponseError.new out unless out.status == 200
  end
  return self
end
lomreset() click to toggle source
# File lib/moob/idrac7.rb, line 236
def lomreset
  @skiplogout = true
  drac_set_params({ 'iDracReset' => 1 })
end
power_control(action) click to toggle source
# File lib/moob/idrac7.rb, line 120
def power_control action
  req = @session.post "data?set=pwState:#{action}", {}
  raise ResponseError.new req unless req.status == 200
  return nil
end
pstatus() click to toggle source
# File lib/moob/idrac7.rb, line 162
def pstatus
  case get_infos(['pwState'])['pwState']
  when '0'
    return :off
  when '1'
    return :on
  else
    return nil
  end
end
set_params() click to toggle source
# File lib/moob/idrac7.rb, line 195
def set_params
  unless @params
    raise "Params are not set!"
  end
  drac_set_params @params
end