Module: Rubyipmi

Defined in:
lib/rubyipmi.rb,
lib/rubyipmi/observablehash.rb,
lib/rubyipmi/freeipmi/connection.rb,
lib/rubyipmi/ipmitool/connection.rb,
lib/rubyipmi/ipmitool/errorcodes.rb,
lib/rubyipmi/commands/basecommand.rb

Defined Under Namespace

Modules: Freeipmi, Ipmitool Classes: BaseCommand, ObservableHash

Constant Summary collapse

PRIV_TYPES =
['CALLBACK', 'USER', 'OPERATOR', 'ADMINISTRATOR']

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#log_levelObject

Returns the value of attribute log_level.



34
35
36
# File 'lib/rubyipmi.rb', line 34

def log_level
  @log_level
end

#loggerObject

Returns the value of attribute logger.



34
35
36
# File 'lib/rubyipmi.rb', line 34

def logger
  @logger
end

Class Method Details

.connect(user, pass, host, provider = 'any', opts = {:driver => 'lan20', :timeout => 'default'}) ⇒ Object

The connect method will create a connection object based the provider type passed in If provider is left blank the function will use the first available provider When the driver is set to auto, rubyipmi will try and figure out which driver to use by common error messages. We will most likely be using the lan20 driver, but in order to support a wide use case we default to auto.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/rubyipmi.rb', line 76

def self.connect(user, pass, host, provider='any', opts={:driver => 'lan20', :timeout => 'default'})
  # use this variable to reduce cmd calls
  installed = false

  # if the user supplied nil, we want to fix this automatically
  opts = {:driver => 'lan20', :timeout => 'default'} if opts.nil?

  # convert all keys to symbols for opts, we can't assume the user will use symbols
  opts.keys.each do |key|
    opts[(key.to_sym rescue key) || key] = opts.delete(key)
  end

  # allow the user to specify an options hash instead of the provider
  # in the future I would stop using the provider and use the opts hash instead to get the provider
  # This allows us to be a little more flexible if the user is doesn't supply us what we need.
  if provider.is_a?(Hash)
    opts = provider
    provider = opts[:provider] ||= 'any'
  end

  # Verify options just in case user passed in a incomplete hash
  opts[:driver]  ||= 'lan20'
  opts[:timeout] ||= 'default'

  if opts[:privilege] and not supported_privilege_type?(opts[:privilege])
    logger.error("Invalid privilege type :#{opts[:privilege]}, must be one of: #{PRIV_TYPES.join("\n")}") if logger
    raise "Invalid privilege type :#{opts[:privilege]}, must be one of: #{PRIV_TYPES.join("\n")}"
  end

  # use the first available provider
  if provider == 'any'
    if is_provider_installed?("freeipmi")
      provider = "freeipmi"
      installed = true
    elsif is_provider_installed?("ipmitool")
      provider = "ipmitool"
      installed = true
    else
      logger.error("No IPMI provider is installed, please install freeipmi or ipmitool")
      raise "No IPMI provider is installed, please install freeipmi or ipmitool"
    end
  end

  # Support multiple drivers
  # Note: these are just generic names of drivers that need to be specified for each provider
  unless valid_drivers.include?(opts[:driver])
    logger.debug("You must specify a valid driver: #{valid_drivers.join(',')}") if logger
    raise "You must specify a valid driver: #{valid_drivers.join(',')}"
  end

  # If the provider is available create a connection object
  if installed or is_provider_installed?(provider)
    if provider == "freeipmi"
      Rubyipmi::Freeipmi::Connection.new(user, pass, host, opts)
    elsif provider == "ipmitool"
      Rubyipmi::Ipmitool::Connection.new(user,pass,host, opts)
    else
      logger.error("Incorrect provider given, must use one of #{valid_providers.join(', ')}") if logger
      raise "Incorrect provider given, must use one of #{valid_providers.join(', ')}"
    end
  else
    # Can't find the provider command line tool, maybe try other provider?
    logger.error("The IPMI provider: #{provider} is not installed") if logger
    raise "The IPMI provider: #{provider} is not installed"
  end
end

.get_diag(user, pass, host, opts = {:driver => 'lan20', :timeout => 'default'}) ⇒ Object

gets data from the bmc device and puts in a hash for diagnostics



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/rubyipmi.rb', line 192

def self.get_diag(user, pass, host, opts={:driver => 'lan20', :timeout => 'default'})
  data = {}
  if Rubyipmi.is_provider_installed?('freeipmi')
    freeconn = Rubyipmi.connect(user, pass, host, 'freeipmi', opts)
    if freeconn
      puts "Retrieving freeipmi data"
      data[:freeipmi] = freeconn.get_diag
    end
  end
  if Rubyipmi.is_provider_installed?('ipmitool')
    ipmiconn = Rubyipmi.connect(user, pass, host, 'ipmitool', opts)
    if ipmiconn
      puts "Retrieving ipmitool data"
      data[:ipmitool] = ipmiconn.get_diag
    end
  end
  File.open('/tmp/rubyipmi_diag_data.txt', 'w') {|f| f.write(data)}
  puts "Created file /tmp/rubyipmi_diag_data.txt"
end

.is_provider_installed?(provider) ⇒ Boolean

Return true or false if the provider is available

Returns:

  • (Boolean)


158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/rubyipmi.rb', line 158

def self.is_provider_installed?(provider)
  case provider
    when "freeipmi"
      cmdpath = locate_command('ipmipower')
    when "ipmitool"
      cmdpath = locate_command('ipmitool')
    else
      logger.error("Invalid BMC provider type #{provider}") if logger
      false
  end
  # return false if command was not found
  return ! cmdpath.nil?
end

.locate_command(commandname) ⇒ Object

method used to find the command which also makes it easier to mock with



149
150
151
152
153
154
155
# File 'lib/rubyipmi.rb', line 149

def self.locate_command(commandname)
  location = `which #{commandname}`.strip
  if not $?.success?
    location = nil
  end
  location
end

.log_level=(level) ⇒ Object

sets the log level, this should be called first if logging to a file is desired if you wish to customize the logging options, set the logger yourself with logger= valid levels are of the type Logger::INFO, Logger::DEBUG, Logger::ERROR, …



45
46
47
# File 'lib/rubyipmi.rb', line 45

def self.log_level=(level)
  @log_level = level
end

.loggerObject

this is an read only method that only creates a real logger if the log_level is set if the log_level is not setup it creates a null logger which logs nothing



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/rubyipmi.rb', line 51

def self.logger
  # by default the log will be set to info
  unless @logger
    if @log_level and @log_level >= 0
      @logger = Logger.new('/tmp/rubyipmi.log')
      @logger.progname = 'Rubyipmi'
      @logger.level = @log_level
    else
      @logger = NullLogger.new
    end
  end
  @logger
end

.logger=(log) ⇒ Object

set a logger instance yourself to customize where the logs should go you will need to set the log level yourself



38
39
40
# File 'lib/rubyipmi.rb', line 38

def self.logger=(log)
  @logger = log
end

.provider_installed?Boolean

returns true if any of the providers are installed

Returns:

  • (Boolean)


177
178
179
# File 'lib/rubyipmi.rb', line 177

def self.provider_installed?
  providers_installed.length > 0
end

.providersObject



172
173
174
# File 'lib/rubyipmi.rb', line 172

def self.providers
  ["freeipmi", "ipmitool"]
end

.providers_installedObject



181
182
183
184
185
186
187
188
189
# File 'lib/rubyipmi.rb', line 181

def self.providers_installed
  available = []
  providers.each do |prov|
    if is_provider_installed?(prov)
      available << prov
    end
  end
  return available
end

.supported_privilege_type?(type) ⇒ Boolean

returns boolean true if privilege type is valid

Returns:

  • (Boolean)


144
145
146
# File 'lib/rubyipmi.rb', line 144

def self.supported_privilege_type?(type)
   PRIV_TYPES.include?(type)
end

.valid_driversObject



65
66
67
# File 'lib/rubyipmi.rb', line 65

def self.valid_drivers
  ['auto', "lan15", "lan20", "open"]
end

.valid_providersObject



69
70
71
# File 'lib/rubyipmi.rb', line 69

def self.valid_providers
  ['auto', 'ipmitool', 'freeipmi']
end