rubyipmi 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/Gemfile +5 -3
- data/README.md +24 -14
- data/Rakefile +82 -4
- data/VERSION +1 -1
- data/lib/rubyipmi.rb +36 -14
- data/lib/rubyipmi/commands/basecommand.rb +57 -119
- data/lib/rubyipmi/freeipmi/commands/basecommand.rb +29 -25
- data/lib/rubyipmi/freeipmi/commands/bmc.rb +3 -3
- data/lib/rubyipmi/freeipmi/commands/bmcconfig.rb +6 -6
- data/lib/rubyipmi/freeipmi/commands/bmcinfo.rb +3 -23
- data/lib/rubyipmi/freeipmi/commands/fru.rb +117 -23
- data/lib/rubyipmi/freeipmi/commands/lan.rb +32 -37
- data/lib/rubyipmi/freeipmi/commands/power.rb +1 -1
- data/lib/rubyipmi/freeipmi/commands/sensors.rb +53 -50
- data/lib/rubyipmi/freeipmi/connection.rb +16 -2
- data/lib/rubyipmi/freeipmi/errorcodes.rb +25 -2
- data/lib/rubyipmi/ipmitool/commands/basecommand.rb +20 -37
- data/lib/rubyipmi/ipmitool/commands/bmc.rb +1 -24
- data/lib/rubyipmi/ipmitool/commands/chassis.rb +1 -0
- data/lib/rubyipmi/ipmitool/commands/fru.rb +112 -30
- data/lib/rubyipmi/ipmitool/commands/lan.rb +55 -77
- data/lib/rubyipmi/ipmitool/commands/power.rb +10 -4
- data/lib/rubyipmi/ipmitool/commands/sensors.rb +53 -80
- data/lib/rubyipmi/ipmitool/connection.rb +19 -3
- data/lib/rubyipmi/ipmitool/errorcodes.rb +51 -3
- data/rubyipmi.gemspec +73 -33
- data/spec/Vagrantfile +45 -0
- data/spec/fixtures/freeipmi/bmc_config.txt +317 -0
- data/spec/fixtures/freeipmi/bmc_config_lan_conf.txt +19 -0
- data/spec/fixtures/freeipmi/bmc_info.txt +32 -0
- data/spec/fixtures/freeipmi/errors.txt +3 -0
- data/spec/fixtures/freeipmi/fru.txt +13 -0
- data/spec/fixtures/freeipmi/sensors.txt +29 -0
- data/spec/fixtures/ipmitool/bmc_info.txt +20 -0
- data/spec/fixtures/ipmitool/errors.txt +10 -0
- data/spec/fixtures/ipmitool/fru.txt +96 -0
- data/spec/fixtures/ipmitool/lan.txt +17 -0
- data/spec/fixtures/ipmitool/sensors.txt +105 -0
- data/spec/integration/bmc_spec.rb +49 -0
- data/spec/{chassis_config_spec.rb → integration/chassis_config_spec.rb} +6 -6
- data/spec/integration/chassis_spec.rb +26 -0
- data/spec/integration/connection_spec.rb +35 -0
- data/spec/{fru_spec.rb → integration/fru_spec.rb} +11 -10
- data/spec/{lan_spec.rb → integration/lan_spec.rb} +9 -7
- data/spec/integration/power_spec.rb +40 -0
- data/spec/{rubyipmi_spec.rb → integration/rubyipmi_spec.rb} +7 -10
- data/spec/{sensor_spec.rb → integration/sensor_spec.rb} +5 -20
- data/spec/manifests/default.pp +50 -0
- data/spec/puppetmodules/archive/LICENSE-2.0.txt +202 -0
- data/spec/puppetmodules/archive/Modulefile +8 -0
- data/spec/puppetmodules/archive/README.md +40 -0
- data/spec/puppetmodules/archive/manifests/download.pp +157 -0
- data/spec/puppetmodules/archive/manifests/extract.pp +81 -0
- data/spec/puppetmodules/archive/manifests/init.pp +70 -0
- data/spec/puppetmodules/archive/manifests/tar-gz.pp +7 -0
- data/spec/puppetmodules/archive/manifests/zip.pp +7 -0
- data/spec/puppetmodules/archive/metadata.json +26 -0
- data/spec/spec_helper.rb +35 -3
- data/spec/unit/freeipmi/bmc-info_spec.rb +42 -0
- data/spec/unit/freeipmi/bmc_spec.rb +44 -0
- data/spec/unit/freeipmi/connection_spec.rb +56 -0
- data/spec/unit/freeipmi/errorcodes_spec.rb +34 -0
- data/spec/unit/freeipmi/fru_spec.rb +77 -0
- data/spec/unit/freeipmi/lan_spec.rb +0 -0
- data/spec/unit/freeipmi/sensors_spec.rb +83 -0
- data/spec/unit/ipmitool/bmc_spec.rb +78 -0
- data/spec/unit/ipmitool/connection_spec.rb +58 -0
- data/spec/unit/ipmitool/errorcodes_spec.rb +34 -0
- data/spec/unit/ipmitool/fru_spec.rb +77 -0
- data/spec/unit/ipmitool/lan_spec.rb +93 -0
- data/spec/unit/ipmitool/sensors_spec.rb +95 -0
- data/spec/unit/rubyipmi_spec.rb +31 -0
- data/spec/vagrant +27 -0
- data/spec/vagrant.pub +1 -0
- metadata +157 -106
- data/.document +0 -5
- data/.rspec +0 -1
- data/Gemfile.lock +0 -33
- data/spec/bmc_spec.rb +0 -46
- data/spec/chassis_spec.rb +0 -26
- data/spec/connection_spec.rb +0 -31
- data/spec/power_spec.rb +0 -42
@@ -4,6 +4,7 @@ module Rubyipmi::Ipmitool
|
|
4
4
|
|
5
5
|
attr_accessor :info
|
6
6
|
attr_accessor :channel
|
7
|
+
MAX_RETRY = 1
|
7
8
|
|
8
9
|
def initialize(opts = ObservableHash.new)
|
9
10
|
super("ipmitool", opts)
|
@@ -12,65 +13,58 @@ module Rubyipmi::Ipmitool
|
|
12
13
|
|
13
14
|
end
|
14
15
|
|
16
|
+
# sets the info var to be empty causing the variable to repopulate upon the next call to info
|
17
|
+
def refresh
|
18
|
+
@info = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def channel=(num)
|
22
|
+
refresh
|
23
|
+
@channel = num
|
24
|
+
end
|
25
|
+
|
15
26
|
def info
|
27
|
+
retrycount = 0
|
16
28
|
if @info.length < 1
|
17
|
-
|
29
|
+
begin
|
30
|
+
parse(print)
|
31
|
+
rescue
|
32
|
+
# sometimes we need to get the info from channel 1,
|
33
|
+
# wait for error to occur then retry using channel 1
|
34
|
+
if retrycount < MAX_RETRY
|
35
|
+
@channel = 1
|
36
|
+
retry
|
37
|
+
end
|
38
|
+
end
|
18
39
|
else
|
40
|
+
# return the cached info
|
19
41
|
@info
|
20
42
|
end
|
21
43
|
end
|
22
44
|
|
23
|
-
def
|
24
|
-
|
25
|
-
value = runcmd
|
26
|
-
@options.delete_notify("cmdargs")
|
27
|
-
if value
|
28
|
-
@result
|
29
|
-
end
|
45
|
+
def snmp
|
46
|
+
info.fetch("snmp_community_string",nil)
|
30
47
|
end
|
31
48
|
|
32
|
-
# def snmp
|
33
|
-
# if @info.length < 1
|
34
|
-
# parse(print)
|
35
|
-
# end
|
36
|
-
# # Some systems do not report the snmp string
|
37
|
-
# @info["snmp community string"]
|
38
|
-
# end
|
39
|
-
|
40
49
|
def ip
|
41
|
-
|
42
|
-
parse(print)
|
43
|
-
end
|
44
|
-
@info["ip address"]
|
50
|
+
info.fetch("ip_address",nil)
|
45
51
|
end
|
46
52
|
|
47
53
|
def mac
|
48
|
-
|
49
|
-
parse(print)
|
50
|
-
end
|
51
|
-
@info["mac address"]
|
54
|
+
info.fetch("mac_address",nil)
|
52
55
|
end
|
53
56
|
|
54
57
|
def netmask
|
55
|
-
|
56
|
-
parse(print)
|
57
|
-
end
|
58
|
-
@info["subnet mask"]
|
58
|
+
info.fetch("subnet_mask",nil)
|
59
59
|
end
|
60
60
|
|
61
61
|
def gateway
|
62
|
-
|
63
|
-
parse(print)
|
64
|
-
end
|
65
|
-
@info["default gateway ip"]
|
62
|
+
info.fetch("default_gateway_ip",nil)
|
66
63
|
end
|
67
64
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
# end
|
72
|
-
# @info["802.1q vlan id"]
|
73
|
-
# end
|
65
|
+
def vlanid
|
66
|
+
info.fetch("802.1q_vlan_id",nil)
|
67
|
+
end
|
74
68
|
|
75
69
|
# def snmp=(community)
|
76
70
|
# @options["cmdargs"] = "lan set #{channel} snmp #{community}"
|
@@ -94,42 +88,43 @@ module Rubyipmi::Ipmitool
|
|
94
88
|
end
|
95
89
|
|
96
90
|
def gateway=(address)
|
97
|
-
@options["cmdargs"] = "lan set #{channel} defgw #{address}"
|
91
|
+
@options["cmdargs"] = "lan set #{channel} defgw ipaddr #{address}"
|
98
92
|
value = runcmd
|
99
93
|
@options.delete_notify("cmdargs")
|
100
94
|
return value
|
101
95
|
end
|
102
96
|
|
103
97
|
def dhcp?
|
104
|
-
|
105
|
-
parse(print)
|
106
|
-
end
|
107
|
-
@info["ip address source"].match(/dhcp/i) != nil
|
98
|
+
info.fetch("ip_address_source",nil).match(/dhcp/i) != nil
|
108
99
|
end
|
109
100
|
|
110
101
|
def static?
|
111
|
-
|
112
|
-
parse(print)
|
113
|
-
end
|
114
|
-
@info["ip address source"].match(/static/i) != nil
|
102
|
+
info.fetch("ip_address_source",nil).match(/static/i) != nil
|
115
103
|
end
|
116
104
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
105
|
+
def vlanid=(vlan)
|
106
|
+
@options["cmdargs"] = "lan set #{channel} vlan id #{vlan}"
|
107
|
+
value = runcmd
|
108
|
+
@options.delete_notify("cmdargs")
|
109
|
+
return value
|
110
|
+
end
|
123
111
|
|
112
|
+
private
|
124
113
|
|
125
|
-
def
|
126
|
-
|
127
|
-
|
114
|
+
def print
|
115
|
+
@options["cmdargs"] = "lan print"
|
116
|
+
value = runcmd
|
117
|
+
@options.delete_notify("cmdargs")
|
118
|
+
if value
|
119
|
+
@result
|
120
|
+
end
|
121
|
+
end
|
128
122
|
|
123
|
+
def parse(landata)
|
129
124
|
landata.lines.each do |line|
|
130
125
|
# clean up the data from spaces
|
131
126
|
item = line.split(':', 2)
|
132
|
-
key = item.first.strip
|
127
|
+
key = normalize(item.first.strip)
|
133
128
|
value = item.last.strip
|
134
129
|
@info[key] = value
|
135
130
|
|
@@ -137,26 +132,9 @@ module Rubyipmi::Ipmitool
|
|
137
132
|
return @info
|
138
133
|
end
|
139
134
|
|
140
|
-
|
141
|
-
|
135
|
+
def normalize(text)
|
136
|
+
text.gsub(/\ /, '_').gsub(/\./, '').downcase
|
137
|
+
end
|
142
138
|
|
143
139
|
end
|
144
140
|
end
|
145
|
-
|
146
|
-
#Set in Progress : Set Complete
|
147
|
-
#Auth Type Support :
|
148
|
-
#Auth Type Enable : Callback :
|
149
|
-
# : User : NONE MD2 MD5 PASSWORD OEM
|
150
|
-
# : Operator : NONE MD2 MD5
|
151
|
-
# : Admin : MD2 MD5
|
152
|
-
# : OEM :
|
153
|
-
#IP Address Source : DHCP Address
|
154
|
-
#IP Address : 192.168.1.41
|
155
|
-
#Subnet Mask : 255.255.255.0
|
156
|
-
#MAC Address : 00:17:a4:49:ab:70
|
157
|
-
#BMC ARP Control : ARP Responses Enabled, Gratuitous ARP Disabled
|
158
|
-
#Gratituous ARP Intrvl : 0.0 seconds
|
159
|
-
#Default Gateway IP : 192.168.1.1
|
160
|
-
#802.1q VLAN ID : Disabled
|
161
|
-
#802.1q VLAN Priority : 0
|
162
|
-
#Cipher Suite Priv Max : Not Available
|
@@ -16,12 +16,20 @@ module Rubyipmi::Ipmitool
|
|
16
16
|
|
17
17
|
# Turn on the system
|
18
18
|
def on
|
19
|
-
|
19
|
+
if off?
|
20
|
+
command("on")
|
21
|
+
else
|
22
|
+
return true
|
23
|
+
end
|
20
24
|
end
|
21
25
|
|
22
26
|
# Turn off the system
|
23
27
|
def off
|
24
|
-
|
28
|
+
if off?
|
29
|
+
return true
|
30
|
+
else
|
31
|
+
command("off")
|
32
|
+
end
|
25
33
|
end
|
26
34
|
|
27
35
|
# Power cycle the system
|
@@ -68,7 +76,5 @@ module Rubyipmi::Ipmitool
|
|
68
76
|
status == "off"
|
69
77
|
end
|
70
78
|
|
71
|
-
|
72
|
-
|
73
79
|
end
|
74
80
|
end
|
@@ -8,129 +8,102 @@ module Rubyipmi::Ipmitool
|
|
8
8
|
|
9
9
|
def refresh
|
10
10
|
@sensors = nil
|
11
|
-
|
11
|
+
list
|
12
12
|
end
|
13
13
|
|
14
14
|
def list
|
15
|
-
sensors
|
15
|
+
@sensors ||= parse(getsensors)
|
16
16
|
end
|
17
17
|
|
18
18
|
def count
|
19
|
-
|
19
|
+
list.count
|
20
20
|
end
|
21
21
|
|
22
22
|
def names
|
23
|
-
|
23
|
+
list.keys
|
24
24
|
end
|
25
25
|
|
26
|
+
# returns a hash of fan sensors where the key is fan name and value is the sensor
|
26
27
|
def fanlist(refreshdata=false)
|
27
28
|
refresh if refreshdata
|
28
|
-
flist =
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
if match[1] == "fan"
|
33
|
-
num = (match[2].to_i) -1
|
34
|
-
flist[num] = sensor.last[:value]
|
29
|
+
flist = {}
|
30
|
+
list.each do | name,sensor |
|
31
|
+
if name =~ /.*fan.*/
|
32
|
+
flist[name] = sensor
|
35
33
|
end
|
36
34
|
end
|
37
|
-
flist
|
35
|
+
return flist
|
38
36
|
end
|
39
37
|
|
38
|
+
# returns a hash of sensors where each key is the name of the sensor and the value is the sensor
|
40
39
|
def templist(refreshdata=false)
|
41
40
|
refresh if refreshdata
|
42
|
-
tlist =
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
if match[1] == "temp"
|
47
|
-
num = (match[2].to_i) -1
|
48
|
-
tlist[num] = sensor.last[:value]
|
41
|
+
tlist = {}
|
42
|
+
list.each do | name , sensor |
|
43
|
+
if sensor[:unit] =~ /.*degree.*/ || name =~ /.*temp.*/
|
44
|
+
tlist[name] = sensor
|
49
45
|
end
|
50
46
|
end
|
51
|
-
tlist
|
47
|
+
return tlist
|
52
48
|
end
|
53
49
|
|
54
|
-
|
50
|
+
def getsensors
|
51
|
+
options["cmdargs"] = "sensor"
|
52
|
+
value = runcmd
|
53
|
+
options.delete_notify("cmdargs")
|
54
|
+
@result
|
55
|
+
end
|
55
56
|
|
56
57
|
private
|
57
58
|
|
58
|
-
def sensors
|
59
|
-
@sensors ||= parse(getsensors)
|
60
|
-
end
|
61
|
-
|
62
59
|
def method_missing(method, *args, &block)
|
63
|
-
if not
|
60
|
+
if not list.has_key?(method.to_s)
|
64
61
|
raise NoMethodError
|
65
62
|
else
|
66
|
-
|
63
|
+
list[method.to_s]
|
67
64
|
end
|
68
65
|
end
|
69
66
|
|
70
|
-
def getsensors
|
71
|
-
options["cmdargs"] = "sensor"
|
72
|
-
value = runcmd
|
73
|
-
options.delete_notify("cmdargs")
|
74
|
-
@result
|
75
|
-
end
|
76
|
-
|
77
67
|
def parse(data)
|
78
68
|
sensorlist = {}
|
79
|
-
data.
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
sensor[:status] = data[3].strip
|
86
|
-
sensor[:type] = nil
|
87
|
-
sensor[:state] = nil
|
88
|
-
#sensor[:lower_nonrec] = data[4].strip
|
89
|
-
#sensor[:lower_crit] = data[5].strip
|
90
|
-
#sensor[:lower_noncrit] = data[6].strip
|
91
|
-
#sensor[:upper_noncrit] = data[7].strip
|
92
|
-
#sensor[:upper_crit] = data[8].strip
|
93
|
-
#sensor[:upper_nonrec] = data[9].strip
|
94
|
-
sensorlist[sensor[:name]] = sensor
|
95
|
-
|
69
|
+
if ! data.nil?
|
70
|
+
data.lines.each do | line|
|
71
|
+
# skip the header
|
72
|
+
sensor = Sensor.new(line)
|
73
|
+
sensorlist[sensor[:name]] = sensor
|
74
|
+
end
|
96
75
|
end
|
97
76
|
return sensorlist
|
98
|
-
|
99
77
|
end
|
100
|
-
|
101
78
|
end
|
102
79
|
|
103
|
-
class Sensor < Hash
|
104
80
|
|
105
|
-
|
106
|
-
|
107
|
-
|
81
|
+
class Sensor < Hash
|
82
|
+
def initialize(line)
|
83
|
+
parse(line)
|
84
|
+
self[:name] = normalize(self[:name])
|
108
85
|
end
|
109
86
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
#def parse(data)
|
116
|
-
# values = data.lines.collect do |line|
|
117
|
-
# line.split(':').last.strip
|
118
|
-
# end
|
119
|
-
# # first 4 entries are lines we don't care about
|
120
|
-
# value = values[4].split(/\([\w\W]+\)/)
|
121
|
-
# self[:value] = value.first.strip
|
122
|
-
# self[:unit] = value.last.strip
|
123
|
-
# self[:status] = values[5].strip.chomp
|
124
|
-
# self[:lower_nonrec] = values[6].strip.chomp
|
125
|
-
# self[:lower_crit] = values[7].strip.chomp
|
126
|
-
# self[:lower_noncrit] = values[8].strip.chomp
|
127
|
-
# self[:upper_noncrit] = values[9].strip.chomp
|
128
|
-
# self[:upper_crit] = values[10].strip.chomp
|
129
|
-
# self[:upper_nonrec] = values[11].strip.chomp
|
130
|
-
|
131
|
-
|
132
|
-
#end
|
87
|
+
private
|
88
|
+
def normalize(text)
|
89
|
+
text.gsub(/\ /, '_').gsub(/\./, '').downcase
|
90
|
+
end
|
133
91
|
|
92
|
+
# Parse the individual sensor
|
93
|
+
# Note: not all fields will exist on every server
|
94
|
+
def parse(line)
|
95
|
+
fields = [:name, :value, :unit, :status, :type, :state, :lower_nonrec,
|
96
|
+
:lower_crit,:lower_noncrit, :upper_crit, :upper_nonrec, :asserts_enabled, :deasserts_enabled ]
|
97
|
+
# skip the header
|
98
|
+
data = line.split(/\|/)
|
99
|
+
# should we ever encounter a field not in the fields list, just use a counter based fieldname
|
100
|
+
i = 0
|
101
|
+
data.each do | value |
|
102
|
+
field ||= fields.shift || "field#{i}"
|
103
|
+
self[field] = value.strip
|
104
|
+
i = i.next
|
105
|
+
end
|
106
|
+
end
|
134
107
|
end
|
135
108
|
|
136
109
|
end
|
@@ -12,10 +12,12 @@ module Rubyipmi
|
|
12
12
|
|
13
13
|
class Connection
|
14
14
|
|
15
|
-
attr_accessor :options
|
15
|
+
attr_accessor :options, :debug
|
16
|
+
attr_reader :debug
|
16
17
|
|
17
18
|
|
18
|
-
def initialize(user, pass, host)
|
19
|
+
def initialize(user, pass, host,debug_value=false)
|
20
|
+
@debug = debug_value
|
19
21
|
@options = Rubyipmi::ObservableHash.new
|
20
22
|
raise("Must provide a host to connect to") unless host
|
21
23
|
@options["H"] = host
|
@@ -25,7 +27,7 @@ module Rubyipmi
|
|
25
27
|
@options["P"] = pass if pass
|
26
28
|
# default to IPMI 2.0 communication, this means that older devices will not work
|
27
29
|
# Those old servers should be recycled by now, as the 1.0, 1.5 spec came out in 2005ish and is 2013.
|
28
|
-
|
30
|
+
#@options["I"] = "lanplus"
|
29
31
|
|
30
32
|
#getWorkArounds
|
31
33
|
end
|
@@ -50,6 +52,20 @@ module Rubyipmi
|
|
50
52
|
@chassis ||= Rubyipmi::Ipmitool::Chassis.new(@options)
|
51
53
|
end
|
52
54
|
|
55
|
+
def get_diag
|
56
|
+
data = {}
|
57
|
+
data['provider'] = provider
|
58
|
+
if @fru
|
59
|
+
data['frus'] = @fru.getfrus
|
60
|
+
end
|
61
|
+
if @sensors
|
62
|
+
data['sensors'] = @sensors.getsensors
|
63
|
+
end
|
64
|
+
if @bmc
|
65
|
+
data['bmc_info'] = @bmc.info
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
53
69
|
end
|
54
70
|
end
|
55
71
|
end
|