ibm_power_hmc 0.1.0 → 0.1.1
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 +4 -4
- data/.gitignore +0 -0
- data/.rubocop.yml +4 -0
- data/.rubocop_local.yml +7 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +0 -0
- data/Gemfile.lock +0 -0
- data/LICENSE +0 -0
- data/README.md +0 -0
- data/Rakefile +0 -0
- data/ibm_power_hmc.gemspec +0 -0
- data/lib/ibm_power_hmc/connection.rb +250 -102
- data/lib/ibm_power_hmc/job.rb +80 -19
- data/lib/ibm_power_hmc/objects.rb +22 -31
- data/lib/ibm_power_hmc/pcm.rb +55 -0
- data/lib/ibm_power_hmc/version.rb +1 -1
- data/lib/ibm_power_hmc.rb +0 -0
- metadata +10 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 214dfa7f9a89d236f1f9bc4ee927b619596a0fabe59c2f596359637e891601ab
|
4
|
+
data.tar.gz: 2affd160febc3952014ab522bb9b0f89b0ebef6d785720d2d8d2a875cd1df918
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e6e6ae8b4c7d84eea70e3328ea44834a5b95ecd98fbe6a31c045e575951b6c17751ca7d6517d3ad58647b5c8b7e1321470c368c48018c31a450a28ba40463e5
|
7
|
+
data.tar.gz: f9139f2ea1a83d0abedc3c73832450e20fa4fcf7c56cc65c50ec5b14750bb5bb2eb17d7948ffc22d5887984d0f412ae8213a237892350e55f0cd55a49af80f30
|
data/.gitignore
CHANGED
File without changes
|
data/.rubocop.yml
ADDED
data/.rubocop_local.yml
ADDED
data/CHANGELOG.md
CHANGED
File without changes
|
data/Gemfile
CHANGED
File without changes
|
data/Gemfile.lock
CHANGED
File without changes
|
data/LICENSE
CHANGED
File without changes
|
data/README.md
CHANGED
File without changes
|
data/Rakefile
CHANGED
File without changes
|
data/ibm_power_hmc.gemspec
CHANGED
File without changes
|
@@ -2,8 +2,22 @@
|
|
2
2
|
|
3
3
|
# Module for IBM HMC Rest API Client
|
4
4
|
module IbmPowerHmc
|
5
|
-
|
5
|
+
require_relative 'pcm.rb'
|
6
|
+
|
7
|
+
class Error < StandardError; end
|
8
|
+
|
9
|
+
##
|
10
|
+
# HMC REST Client connection.
|
6
11
|
class Connection
|
12
|
+
##
|
13
|
+
# @!method initialize(host:, username: "hscroot", password:, port: 12_443, validate_ssl: true)
|
14
|
+
# Create a new HMC connection.
|
15
|
+
#
|
16
|
+
# @param host [String] Hostname of the HMC.
|
17
|
+
# @param username [String] User name.
|
18
|
+
# @param password [String] Password.
|
19
|
+
# @param port [Integer] TCP port number.
|
20
|
+
# @param validate_ssl [Boolean] Verify SSL certificates.
|
7
21
|
def initialize(host:, username: "hscroot", password:, port: 12_443, validate_ssl: true)
|
8
22
|
# Damien: use URI::HTTPS
|
9
23
|
@hostname = "#{host}:#{port}"
|
@@ -13,10 +27,14 @@ module IbmPowerHmc
|
|
13
27
|
@api_session_token = nil
|
14
28
|
end
|
15
29
|
|
30
|
+
##
|
31
|
+
# @!method logon
|
32
|
+
# Establish a trusted session with the Web Services APIs.
|
33
|
+
# @return [String] The X-API-Session token.
|
16
34
|
def logon
|
17
35
|
method_url = "/rest/api/web/Logon"
|
18
36
|
headers = {
|
19
|
-
content_type
|
37
|
+
:content_type => "application/vnd.ibm.powervm.web+xml; type=LogonRequest"
|
20
38
|
}
|
21
39
|
doc = REXML::Document.new("")
|
22
40
|
doc.add_element("LogonRequest", {
|
@@ -26,41 +44,84 @@ module IbmPowerHmc
|
|
26
44
|
doc.root.add_element("UserID").text = @username
|
27
45
|
doc.root.add_element("Password").text = @password
|
28
46
|
|
29
|
-
# Damien: begin/rescue
|
30
47
|
@api_session_token = ""
|
31
48
|
response = request(:put, method_url, headers, doc.to_s)
|
32
49
|
doc = REXML::Document.new(response.body)
|
33
|
-
|
50
|
+
elem = doc.elements["LogonResponse/X-API-Session"]
|
51
|
+
raise Error, "LogonResponse/X-API-Session not found" if elem.nil?
|
52
|
+
|
53
|
+
@api_session_token = elem.text
|
34
54
|
end
|
35
55
|
|
56
|
+
##
|
57
|
+
# @!method logoff
|
58
|
+
# Close the session.
|
36
59
|
def logoff
|
60
|
+
# Don't want to trigger automatic logon here!
|
61
|
+
return if @api_session_token.nil?
|
62
|
+
|
37
63
|
method_url = "/rest/api/web/Logon"
|
38
|
-
|
64
|
+
begin
|
65
|
+
request(:delete, method_url)
|
66
|
+
rescue
|
67
|
+
# Ignore exceptions as this is best effort attempt to log off.
|
68
|
+
end
|
39
69
|
@api_session_token = nil
|
40
70
|
end
|
41
71
|
|
72
|
+
def parse_feed(doc, myclass)
|
73
|
+
objs = []
|
74
|
+
doc.each_element("feed/entry") do |entry|
|
75
|
+
objs << myclass.new(entry)
|
76
|
+
end
|
77
|
+
objs
|
78
|
+
end
|
79
|
+
private :parse_feed
|
80
|
+
|
81
|
+
##
|
82
|
+
# @!method management_console
|
83
|
+
# Retrieve information about the management console.
|
84
|
+
# @return [IbmPowerHmc::ManagementConsole] The management console.
|
42
85
|
def management_console
|
43
86
|
method_url = "/rest/api/uom/ManagementConsole"
|
44
87
|
response = request(:get, method_url)
|
45
88
|
doc = REXML::Document.new(response.body)
|
46
|
-
|
47
|
-
ManagementConsole.
|
89
|
+
# This request returns a feed with a single entry.
|
90
|
+
parse_feed(doc, ManagementConsole).first
|
48
91
|
end
|
49
92
|
|
93
|
+
##
|
94
|
+
# @!method managed_systems
|
95
|
+
# Retrieve the list of systems managed by the HMC.
|
96
|
+
# @return [Array<IbmPowerHmc::ManagedSystem>] The list of managed systems.
|
50
97
|
def managed_systems
|
51
98
|
method_url = "/rest/api/uom/ManagedSystem"
|
52
99
|
response = request(:get, method_url)
|
53
100
|
doc = REXML::Document.new(response.body)
|
54
|
-
|
55
|
-
|
101
|
+
parse_feed(doc, ManagedSystem)
|
102
|
+
end
|
56
103
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
104
|
+
##
|
105
|
+
# @!method managed_system(lpar_uuid, sys_uuid = nil, group_name = nil)
|
106
|
+
# Retrieve information about a managed system.
|
107
|
+
# @param sys_uuid [String] The UUID of the managed system.
|
108
|
+
# @param group_name [String] The extended group attributes.
|
109
|
+
# @return [IbmPowerHmc::ManagedSystem] The logical partition.
|
110
|
+
def managed_system(sys_uuid, group_name = nil)
|
111
|
+
method_url = "/rest/api/uom/ManagedSystem/#{sys_uuid}"
|
112
|
+
method_url += "?group=#{group_name}" unless group_name.nil?
|
113
|
+
|
114
|
+
response = request(:get, method_url)
|
115
|
+
doc = REXML::Document.new(response.body)
|
116
|
+
entry = doc.elements["entry"]
|
117
|
+
ManagedSystem.new(entry)
|
62
118
|
end
|
63
119
|
|
120
|
+
##
|
121
|
+
# @!method lpars(sys_uuid = nil)
|
122
|
+
# Retrieve the list of logical partitions managed by the HMC.
|
123
|
+
# @param sys_uuid [String] The UUID of the managed system.
|
124
|
+
# @return [Array<IbmPowerHmc::LogicalPartition>] The list of logical partitions.
|
64
125
|
def lpars(sys_uuid = nil)
|
65
126
|
if sys_uuid.nil?
|
66
127
|
method_url = "/rest/api/uom/LogicalPartition"
|
@@ -69,16 +130,16 @@ module IbmPowerHmc
|
|
69
130
|
end
|
70
131
|
response = request(:get, method_url)
|
71
132
|
doc = REXML::Document.new(response.body)
|
72
|
-
|
73
|
-
return lpars if doc.root.nil?
|
74
|
-
|
75
|
-
doc.root.each_element("entry") do |entry|
|
76
|
-
lpar = LogicalPartition.new(entry)
|
77
|
-
lpars += [lpar]
|
78
|
-
end
|
79
|
-
lpars
|
133
|
+
parse_feed(doc, LogicalPartition)
|
80
134
|
end
|
81
135
|
|
136
|
+
##
|
137
|
+
# @!method lpar(lpar_uuid, sys_uuid = nil, group_name = nil)
|
138
|
+
# Retrieve information about a logical partition.
|
139
|
+
# @param lpar_uuid [String] The UUID of the logical partition.
|
140
|
+
# @param sys_uuid [String] The UUID of the managed system.
|
141
|
+
# @param group_name [String] The extended group attributes.
|
142
|
+
# @return [IbmPowerHmc::LogicalPartition] The logical partition.
|
82
143
|
def lpar(lpar_uuid, sys_uuid = nil, group_name = nil)
|
83
144
|
if sys_uuid.nil?
|
84
145
|
method_url = "/rest/api/uom/LogicalPartition/#{lpar_uuid}"
|
@@ -93,6 +154,11 @@ module IbmPowerHmc
|
|
93
154
|
LogicalPartition.new(entry)
|
94
155
|
end
|
95
156
|
|
157
|
+
##
|
158
|
+
# @!method lpar_quick_property(lpar_uuid, property_name)
|
159
|
+
# Retrieve a quick property of a logical partition.
|
160
|
+
# @param lpar_uuid [String] The UUID of the logical partition.
|
161
|
+
# @return [String] The quick property value.
|
96
162
|
def lpar_quick_property(lpar_uuid, property_name)
|
97
163
|
method_url = "/rest/api/uom/LogicalPartition/#{lpar_uuid}/quick/#{property_name}"
|
98
164
|
|
@@ -100,141 +166,223 @@ module IbmPowerHmc
|
|
100
166
|
response.body[1..-2]
|
101
167
|
end
|
102
168
|
|
169
|
+
##
|
170
|
+
# @!method vioses(sys_uuid = nil)
|
171
|
+
# Retrieve the list of virtual I/O servers managed by the HMC.
|
172
|
+
# @param sys_uuid [String] The UUID of the managed system.
|
173
|
+
# @return [Array<IbmPowerHmc::VirtualIOServer>] The list of virtual I/O servers.
|
103
174
|
def vioses(sys_uuid = nil)
|
104
175
|
if sys_uuid.nil?
|
105
176
|
method_url = "/rest/api/uom/VirtualIOServer"
|
106
177
|
else
|
107
178
|
method_url = "/rest/api/uom/ManagedSystem/#{sys_uuid}/VirtualIOServer"
|
108
179
|
end
|
109
|
-
|
110
|
-
response = request(:get, method_url)
|
111
|
-
rescue StandardError
|
112
|
-
return []
|
113
|
-
end
|
180
|
+
response = request(:get, method_url)
|
114
181
|
doc = REXML::Document.new(response.body)
|
115
|
-
|
116
|
-
return vioses if doc.root.nil?
|
117
|
-
|
118
|
-
doc.root.each_element("entry") do |entry|
|
119
|
-
vios = VirtualIOServer.new(entry)
|
120
|
-
vioses += [vios]
|
121
|
-
end
|
122
|
-
vioses
|
182
|
+
parse_feed(doc, VirtualIOServer)
|
123
183
|
end
|
124
184
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
185
|
+
##
|
186
|
+
# @!method vios(vios_uuid, sys_uuid = nil, group_name = nil)
|
187
|
+
# Retrieve information about a virtual I/O server.
|
188
|
+
# @param vios_uuid [String] The UUID of the virtual I/O server.
|
189
|
+
# @param sys_uuid [String] The UUID of the managed system.
|
190
|
+
# @param group_name [String] The extended group attributes.
|
191
|
+
# @return [IbmPowerHmc::VirtualIOServer] The virtual I/O server.
|
192
|
+
def vios(vios_uuid, sys_uuid = nil, group_name = nil)
|
193
|
+
if sys_uuid.nil?
|
194
|
+
method_url = "/rest/api/uom/VirtualIOServer/#{vios_uuid}"
|
195
|
+
else
|
196
|
+
method_url = "/rest/api/uom/ManagedSystem/#{sys_uuid}/VirtualIOServer/#{vios_uuid}"
|
132
197
|
end
|
133
|
-
|
134
|
-
profiles = []
|
135
|
-
return profiles if doc.root.nil?
|
198
|
+
method_url += "?group=#{group_name}" unless group_name.nil?
|
136
199
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
profiles
|
200
|
+
response = request(:get, method_url)
|
201
|
+
doc = REXML::Document.new(response.body)
|
202
|
+
entry = doc.elements["entry"]
|
203
|
+
VirtualIOServer.new(entry)
|
142
204
|
end
|
143
205
|
|
144
|
-
|
206
|
+
##
|
207
|
+
# @!method poweron_lpar(lpar_uuid, params = {}, sync = true)
|
208
|
+
# Power on a logical partition.
|
209
|
+
# @param lpar_uuid [String] The UUID of the logical partition.
|
210
|
+
# @param params [Hash] Job parameters.
|
211
|
+
# @param sync [Boolean] Start the job and wait for its completion.
|
212
|
+
# @return [IbmPowerHmc::HmcJob] The HMC job.
|
213
|
+
def poweron_lpar(lpar_uuid, params = {}, sync = true)
|
145
214
|
method_url = "/rest/api/uom/LogicalPartition/#{lpar_uuid}/do/PowerOn"
|
146
215
|
|
147
216
|
job = HmcJob.new(self, method_url, "PowerOn", "LogicalPartition", params)
|
148
|
-
job.
|
149
|
-
job
|
150
|
-
job.delete
|
217
|
+
job.run if sync
|
218
|
+
job
|
151
219
|
end
|
152
220
|
|
153
|
-
|
221
|
+
##
|
222
|
+
# @!method poweroff_lpar(lpar_uuid, params = {}, sync = true)
|
223
|
+
# Power off a logical partition.
|
224
|
+
# @param lpar_uuid [String] The UUID of the logical partition.
|
225
|
+
# @param params [Hash] Job parameters.
|
226
|
+
# @param sync [Boolean] Start the job and wait for its completion.
|
227
|
+
# @return [IbmPowerHmc::HmcJob] The HMC job.
|
228
|
+
def poweroff_lpar(lpar_uuid, params = {}, sync = true)
|
154
229
|
method_url = "/rest/api/uom/LogicalPartition/#{lpar_uuid}/do/PowerOff"
|
155
230
|
|
156
231
|
job = HmcJob.new(self, method_url, "PowerOff", "LogicalPartition", params)
|
157
|
-
job.
|
158
|
-
job
|
159
|
-
job.delete
|
232
|
+
job.run if sync
|
233
|
+
job
|
160
234
|
end
|
161
235
|
|
162
|
-
|
163
|
-
|
236
|
+
##
|
237
|
+
# @!method poweron_vios(vios_uuid, params = {}, sync = true)
|
238
|
+
# Power on a virtual I/O server.
|
239
|
+
# @param vios_uuid [String] The UUID of the virtual I/O server.
|
240
|
+
# @param params [Hash] Job parameters.
|
241
|
+
# @param sync [Boolean] Start the job and wait for its completion.
|
242
|
+
# @return [IbmPowerHmc::HmcJob] The HMC job.
|
243
|
+
def poweron_vios(vios_uuid, params = {}, sync = true)
|
164
244
|
method_url = "/rest/api/uom/VirtualIOServer/#{vios_uuid}/do/PowerOn"
|
165
245
|
|
166
246
|
job = HmcJob.new(self, method_url, "PowerOn", "VirtualIOServer", params)
|
167
|
-
job.
|
168
|
-
job
|
169
|
-
job.delete
|
247
|
+
job.run if sync
|
248
|
+
job
|
170
249
|
end
|
171
250
|
|
172
|
-
|
173
|
-
|
251
|
+
##
|
252
|
+
# @!method poweroff_vios(vios_uuid, params = {}, sync = true)
|
253
|
+
# Power off a virtual I/O server.
|
254
|
+
# @param vios_uuid [String] The UUID of the virtual I/O server.
|
255
|
+
# @param params [Hash] Job parameters.
|
256
|
+
# @param sync [Boolean] Start the job and wait for its completion.
|
257
|
+
# @return [IbmPowerHmc::HmcJob] The HMC job.
|
258
|
+
def poweroff_vios(vios_uuid, params = {}, sync = true)
|
174
259
|
method_url = "/rest/api/uom/VirtualIOServer/#{vios_uuid}/do/PowerOff"
|
175
260
|
|
176
261
|
job = HmcJob.new(self, method_url, "PowerOff", "VirtualIOServer", params)
|
177
|
-
job.
|
178
|
-
job
|
179
|
-
job.delete
|
262
|
+
job.run if sync
|
263
|
+
job
|
180
264
|
end
|
181
265
|
|
182
|
-
|
266
|
+
##
|
267
|
+
# @!method poweron_managed_system(sys_uuid, params = {}, sync = true)
|
268
|
+
# Power on a managed system.
|
269
|
+
# @param sys_uuid [String] The UUID of the managed system.
|
270
|
+
# @param params [Hash] Job parameters.
|
271
|
+
# @param sync [Boolean] Start the job and wait for its completion.
|
272
|
+
# @return [IbmPowerHmc::HmcJob] The HMC job.
|
273
|
+
def poweron_managed_system(sys_uuid, params = {}, sync = true)
|
183
274
|
method_url = "/rest/api/uom/ManagedSystem/#{sys_uuid}/do/PowerOn"
|
184
275
|
|
185
276
|
job = HmcJob.new(self, method_url, "PowerOn", "ManagedSystem", params)
|
186
|
-
job.
|
187
|
-
job
|
188
|
-
job.delete
|
277
|
+
job.run if sync
|
278
|
+
job
|
189
279
|
end
|
190
280
|
|
191
|
-
|
281
|
+
##
|
282
|
+
# @!method poweroff_managed_system(sys_uuid, params = {}, sync = true)
|
283
|
+
# Power off a managed system.
|
284
|
+
# @param sys_uuid [String] The UUID of the managed system.
|
285
|
+
# @param params [Hash] Job parameters.
|
286
|
+
# @param sync [Boolean] Start the job and wait for its completion.
|
287
|
+
# @return [IbmPowerHmc::HmcJob] The HMC job.
|
288
|
+
def poweroff_managed_system(sys_uuid, params = {}, sync = true)
|
192
289
|
method_url = "/rest/api/uom/ManagedSystem/#{sys_uuid}/do/PowerOff"
|
193
290
|
|
194
291
|
job = HmcJob.new(self, method_url, "PowerOff", "ManagedSystem", params)
|
195
|
-
job.
|
196
|
-
job
|
197
|
-
job.delete
|
292
|
+
job.run if sync
|
293
|
+
job
|
198
294
|
end
|
199
295
|
|
200
|
-
|
201
|
-
|
296
|
+
##
|
297
|
+
# @!method cli_run(hmc_uuid, cmd, sync = true)
|
298
|
+
# Run a CLI command on the HMC as a job.
|
299
|
+
# @param hmc_uuid [String] The UUID of the management console.
|
300
|
+
# @param cmd [String] The command to run.
|
301
|
+
# @param sync [Boolean] Start the job and wait for its completion.
|
302
|
+
# @return [IbmPowerHmc::HmcJob] The HMC job.
|
303
|
+
def cli_run(hmc_uuid, cmd, sync = true)
|
304
|
+
method_url = "/rest/api/uom/ManagementConsole/#{hmc_uuid}/do/CLIRunner"
|
305
|
+
|
306
|
+
params = {
|
307
|
+
"cmd" => cmd,
|
308
|
+
"acknowledgeThisAPIMayGoAwayInTheFuture" => "true",
|
309
|
+
}
|
310
|
+
job = HmcJob.new(self, method_url, "CLIRunner", "ManagementConsole", params)
|
311
|
+
job.run if sync
|
312
|
+
job
|
313
|
+
end
|
314
|
+
|
315
|
+
##
|
316
|
+
# @!method next_events(wait = true)
|
317
|
+
# Retrieve a list of events that occured since last call.
|
318
|
+
# @param wait [Boolean] If no event is available, block until new events occur.
|
319
|
+
# @return [Array<IbmPowerHmc::Event>] The list of events.
|
320
|
+
def next_events(wait = true)
|
202
321
|
method_url = "/rest/api/uom/Event"
|
203
322
|
|
204
|
-
|
323
|
+
response = nil
|
205
324
|
loop do
|
206
325
|
response = request(:get, method_url)
|
207
|
-
|
326
|
+
# No need to sleep as the HMC already waits a bit before returning 204
|
327
|
+
break if response.code != 204 || !wait
|
328
|
+
end
|
329
|
+
doc = REXML::Document.new(response.body)
|
330
|
+
parse_feed(doc, Event)
|
331
|
+
end
|
208
332
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
333
|
+
class HttpError < Error
|
334
|
+
attr_reader :status, :uri, :reason, :message
|
335
|
+
|
336
|
+
##
|
337
|
+
# @!method initialize(err)
|
338
|
+
# Create a new HttpError exception.
|
339
|
+
# @param err [RestClient::Exception] The REST client exception.
|
340
|
+
def initialize(err)
|
341
|
+
super
|
342
|
+
@status = err.http_code
|
343
|
+
|
344
|
+
# Try to parse body as an HttpErrorResponse
|
345
|
+
doc = REXML::Document.new(err.response.body)
|
346
|
+
entry = doc.elements["entry"]
|
347
|
+
unless entry.nil?
|
348
|
+
resp = HttpErrorResponse.new(entry)
|
349
|
+
@uri = resp.uri
|
350
|
+
@reason = resp.reason
|
351
|
+
@message = resp.message
|
213
352
|
end
|
214
|
-
break
|
215
353
|
end
|
216
|
-
events
|
217
354
|
end
|
218
355
|
|
356
|
+
##
|
357
|
+
# @!method request(method, url, headers = {}, payload = nil)
|
358
|
+
# Perform a REST API request.
|
359
|
+
# @param method [String] The HTTP method.
|
360
|
+
# @param url [String] The method URL.
|
361
|
+
# @param headers [Hash] HTTP headers.
|
362
|
+
# @param payload [String] HTTP request payload.
|
363
|
+
# @return [RestClient::Response] The response from the HMC.
|
219
364
|
def request(method, url, headers = {}, payload = nil)
|
220
365
|
logon if @api_session_token.nil?
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
#
|
233
|
-
@api_session_token
|
234
|
-
|
235
|
-
|
366
|
+
reauth = false
|
367
|
+
begin
|
368
|
+
headers = headers.merge({"X-API-Session" => @api_session_token})
|
369
|
+
RestClient::Request.execute(
|
370
|
+
:method => method,
|
371
|
+
:url => "https://" + @hostname + url,
|
372
|
+
:verify_ssl => @verify_ssl,
|
373
|
+
:payload => payload,
|
374
|
+
:headers => headers
|
375
|
+
)
|
376
|
+
rescue RestClient::Exception => e
|
377
|
+
# Do not retry on failed logon attempts
|
378
|
+
if e.http_code == 401 && @api_session_token != "" && !reauth
|
379
|
+
# Try to reauth
|
380
|
+
reauth = true
|
381
|
+
logon
|
382
|
+
retry
|
383
|
+
end
|
384
|
+
raise HttpError.new(e), "REST request failed"
|
236
385
|
end
|
237
|
-
response
|
238
386
|
end
|
239
387
|
end
|
240
388
|
end
|
data/lib/ibm_power_hmc/job.rb
CHANGED
@@ -1,20 +1,35 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Module for IBM HMC Rest API Client
|
4
3
|
module IbmPowerHmc
|
5
|
-
|
4
|
+
##
|
5
|
+
# HMC Job for long running operations.
|
6
6
|
class HmcJob
|
7
|
-
|
8
|
-
|
7
|
+
class JobNotStarted < StandardError; end
|
8
|
+
|
9
|
+
##
|
10
|
+
# @!method initialize(conn, method_url, operation, group, params = {})
|
11
|
+
# Construct a new HMC Job.
|
12
|
+
#
|
13
|
+
# @param conn [IbmPowerHmc::Connection] The connection to the HMC.
|
14
|
+
# @param method_url [String] The method URL.
|
15
|
+
# @param operation [String] The name of the requested operation.
|
16
|
+
# @param group [String] The name of the group.
|
17
|
+
# @param params [Hash] The job name/value parameters.
|
18
|
+
def initialize(conn, method_url, operation, group, params = {})
|
19
|
+
@conn = conn
|
9
20
|
@method_url = method_url
|
10
21
|
@operation = operation
|
11
22
|
@group = group
|
12
23
|
@params = params
|
13
24
|
end
|
14
25
|
|
26
|
+
##
|
27
|
+
# @!method status
|
28
|
+
# Start the job asynchronously.
|
29
|
+
# @return [String] The ID of the job.
|
15
30
|
def start
|
16
31
|
headers = {
|
17
|
-
content_type
|
32
|
+
:content_type => "application/vnd.ibm.powervm.web+xml; type=JobRequest"
|
18
33
|
}
|
19
34
|
doc = REXML::Document.new("")
|
20
35
|
doc.add_element("JobRequest:JobRequest", {
|
@@ -22,49 +37,95 @@ module IbmPowerHmc
|
|
22
37
|
"xmlns" => "http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/",
|
23
38
|
"schemaVersion" => "V1_1_0"
|
24
39
|
})
|
25
|
-
op = doc.root.add_element("RequestedOperation", {
|
40
|
+
op = doc.root.add_element("RequestedOperation", {"schemaVersion" => "V1_1_0"})
|
26
41
|
op.add_element("OperationName").text = @operation
|
27
42
|
op.add_element("GroupName").text = @group
|
28
43
|
# Damien: ProgressType?
|
29
|
-
jobparams = doc.root.add_element("JobParameters", {
|
44
|
+
jobparams = doc.root.add_element("JobParameters", {"schemaVersion" => "V1_1_0"})
|
30
45
|
@params.each do |key, value|
|
31
|
-
jobparam = jobparams.add_element("JobParameter", {
|
46
|
+
jobparam = jobparams.add_element("JobParameter", {"schemaVersion" => "V1_1_0"})
|
32
47
|
jobparam.add_element("ParameterName").text = key
|
33
48
|
jobparam.add_element("ParameterValue").text = value
|
34
49
|
end
|
35
|
-
response = @
|
50
|
+
response = @conn.request(:put, @method_url, headers, doc.to_s)
|
36
51
|
doc = REXML::Document.new(response.body)
|
37
52
|
info = doc.root.elements["content/JobResponse:JobResponse"]
|
38
53
|
@id = info.elements["JobID"].text
|
39
54
|
end
|
40
55
|
|
56
|
+
# @return [Hash] The job results returned by the HMC.
|
57
|
+
attr_reader :results
|
58
|
+
|
59
|
+
##
|
60
|
+
# @!method status
|
61
|
+
# Return the status of the job.
|
62
|
+
# @return [String] The status of the job.
|
41
63
|
def status
|
42
|
-
|
64
|
+
raise JobNotStarted unless defined?(@id)
|
65
|
+
|
43
66
|
method_url = "/rest/api/uom/jobs/#{@id}"
|
44
67
|
headers = {
|
45
|
-
content_type
|
68
|
+
:content_type => "application/vnd.ibm.powervm.web+xml; type=JobRequest"
|
46
69
|
}
|
47
|
-
response = @
|
70
|
+
response = @conn.request(:get, method_url, headers)
|
48
71
|
doc = REXML::Document.new(response.body)
|
49
72
|
info = doc.root.elements["content/JobResponse:JobResponse"]
|
50
73
|
status = info.elements["Status"].text
|
51
|
-
# Damien: also retrieve "ResponseException/Message"
|
74
|
+
# Damien: also retrieve "ResponseException/Message"?
|
75
|
+
|
76
|
+
# Gather Job results returned by the HMC.
|
77
|
+
@results = {}
|
78
|
+
info.each_element("Results/JobParameter") do |result|
|
79
|
+
name = result.elements["ParameterName"].text.strip
|
80
|
+
value = result.elements["ParameterValue"].text.strip
|
81
|
+
@results[name] = value
|
82
|
+
end
|
83
|
+
|
52
84
|
status
|
53
85
|
end
|
54
86
|
|
55
|
-
|
56
|
-
|
57
|
-
|
87
|
+
##
|
88
|
+
# @!method wait(timeout = 120, poll_interval = 0)
|
89
|
+
# Wait for the job to complete.
|
90
|
+
# @param timeout [Integer] The maximum time in seconds to wait for the job to complete.
|
91
|
+
# @param poll_interval [Integer] The interval in seconds between status queries (0 means auto).
|
92
|
+
# @return [String] The status of the job.
|
93
|
+
def wait(timeout = 120, poll_interval = 0)
|
94
|
+
endtime = Time.now.utc + timeout
|
95
|
+
auto = poll_interval == 0
|
96
|
+
poll_interval = 1 if auto
|
97
|
+
while Time.now.utc < endtime
|
58
98
|
status = self.status
|
59
|
-
|
99
|
+
return status if status != "RUNNING" && status != "NOT_STARTED"
|
100
|
+
|
101
|
+
poll_interval *= 2 if auto && poll_interval < 30
|
60
102
|
sleep(poll_interval)
|
61
103
|
end
|
104
|
+
"TIMEDOUT"
|
62
105
|
end
|
63
106
|
|
107
|
+
##
|
108
|
+
# @!method run(timeout = 120, poll_interval = 0)
|
109
|
+
# Run the job synchronously.
|
110
|
+
# @param timeout [Integer] The maximum time in seconds to wait for the job to complete.
|
111
|
+
# @param poll_interval [Integer] The interval in seconds between status queries (0 means auto).
|
112
|
+
# @return [String] The status of the job.
|
113
|
+
def run(timeout = 120, poll_interval = 0)
|
114
|
+
start
|
115
|
+
status = wait(timeout, poll_interval)
|
116
|
+
status
|
117
|
+
ensure
|
118
|
+
delete if defined?(@id)
|
119
|
+
end
|
120
|
+
|
121
|
+
##
|
122
|
+
# @!method delete
|
123
|
+
# Delete the job from the HMC.
|
64
124
|
def delete
|
65
|
-
|
125
|
+
raise JobNotStarted unless defined?(@id)
|
126
|
+
|
66
127
|
method_url = "/rest/api/uom/jobs/#{@id}"
|
67
|
-
@
|
128
|
+
@conn.request(:delete, method_url)
|
68
129
|
# Returns HTTP 204 if ok
|
69
130
|
end
|
70
131
|
end
|
@@ -16,7 +16,7 @@ module IbmPowerHmc
|
|
16
16
|
value = doc.elements[xpath]
|
17
17
|
value = value.text unless value.nil?
|
18
18
|
value = value.strip unless value.nil?
|
19
|
-
self.class.__send__(:attr_reader,
|
19
|
+
self.class.__send__(:attr_reader, varname)
|
20
20
|
instance_variable_set("@#{varname}", value)
|
21
21
|
end
|
22
22
|
|
@@ -25,10 +25,6 @@ module IbmPowerHmc
|
|
25
25
|
get_value(doc, key, value)
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
29
|
-
def to_s
|
30
|
-
"uuid=#{@uuid}"
|
31
|
-
end
|
32
28
|
end
|
33
29
|
|
34
30
|
# HMC information
|
@@ -44,10 +40,6 @@ module IbmPowerHmc
|
|
44
40
|
info = doc.elements["content/ManagementConsole:ManagementConsole"]
|
45
41
|
get_values(info, XMLMAP)
|
46
42
|
end
|
47
|
-
|
48
|
-
def to_s
|
49
|
-
"hmc name=#{@name} version=#{@version} build_level=#{@build_level}"
|
50
|
-
end
|
51
43
|
end
|
52
44
|
|
53
45
|
# Managed System information
|
@@ -60,7 +52,10 @@ module IbmPowerHmc
|
|
60
52
|
"AssociatedSystemMemoryConfiguration/InstalledSystemMemory" => "memory",
|
61
53
|
"AssociatedSystemMemoryConfiguration/CurrentAvailableSystemMemory" => "avail_mem",
|
62
54
|
"AssociatedSystemProcessorConfiguration/InstalledSystemProcessorUnits" => "cpus",
|
63
|
-
"AssociatedSystemProcessorConfiguration/CurrentAvailableSystemProcessorUnits" => "avail_cpus"
|
55
|
+
"AssociatedSystemProcessorConfiguration/CurrentAvailableSystemProcessorUnits" => "avail_cpus",
|
56
|
+
"MachineTypeModelAndSerialNumber/MachineType" => "mtype",
|
57
|
+
"MachineTypeModelAndSerialNumber/Model" => "model",
|
58
|
+
"MachineTypeModelAndSerialNumber/SerialNumber" => "serial",
|
64
59
|
}.freeze
|
65
60
|
|
66
61
|
def initialize(doc)
|
@@ -68,10 +63,6 @@ module IbmPowerHmc
|
|
68
63
|
info = doc.elements["content/ManagedSystem:ManagedSystem"]
|
69
64
|
get_values(info, XMLMAP)
|
70
65
|
end
|
71
|
-
|
72
|
-
def to_s
|
73
|
-
"sys name=#{@name} state=#{@state} ip=#{@ipaddr} mem=#{@memory}MB avail=#{@avail_mem}MB CPUs=#{@cpus} avail=#{@avail_cpus}"
|
74
|
-
end
|
75
66
|
end
|
76
67
|
|
77
68
|
# Logical Partition information
|
@@ -96,10 +87,6 @@ module IbmPowerHmc
|
|
96
87
|
@sys_uuid = URI(sys_href).path.split('/').last
|
97
88
|
get_values(info, XMLMAP)
|
98
89
|
end
|
99
|
-
|
100
|
-
def to_s
|
101
|
-
"lpar name=#{@name} id=#{@id} state=#{@state} type=#{@type} memory=#{@memory}MB dedicated cpus=#{@dedicated}"
|
102
|
-
end
|
103
90
|
end
|
104
91
|
|
105
92
|
# VIOS information
|
@@ -122,21 +109,12 @@ module IbmPowerHmc
|
|
122
109
|
@sys_uuid = URI(sys_href).path.split('/').last
|
123
110
|
get_values(info, XMLMAP)
|
124
111
|
end
|
125
|
-
|
126
|
-
def to_s
|
127
|
-
"vios name=#{@name} id=#{@id} state=#{@state} type=#{@type} memory=#{@memory}MB dedicated cpus=#{@dedicated}"
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
# LPAR profile
|
132
|
-
class LogicalPartitionProfile < HmcObject
|
133
|
-
attr_reader :lpar_uuid
|
134
|
-
|
135
|
-
# Damien: TBD
|
136
112
|
end
|
137
113
|
|
138
114
|
# HMC Event
|
139
115
|
class Event < HmcObject
|
116
|
+
attr_reader :published
|
117
|
+
|
140
118
|
XMLMAP = {
|
141
119
|
"EventID" => "id",
|
142
120
|
"EventType" => "type",
|
@@ -146,12 +124,25 @@ module IbmPowerHmc
|
|
146
124
|
|
147
125
|
def initialize(doc)
|
148
126
|
super(doc)
|
127
|
+
@published = doc.elements["published"].text
|
149
128
|
info = doc.elements["content/Event:Event"]
|
150
129
|
get_values(info, XMLMAP)
|
151
130
|
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Error response from HMC
|
134
|
+
class HttpErrorResponse < HmcObject
|
135
|
+
XMLMAP = {
|
136
|
+
"HTTPStatus" => "status",
|
137
|
+
"RequestURI" => "uri",
|
138
|
+
"ReasonCode" => "reason",
|
139
|
+
"Message" => "message",
|
140
|
+
}.freeze
|
152
141
|
|
153
|
-
def
|
154
|
-
|
142
|
+
def initialize(doc)
|
143
|
+
super(doc)
|
144
|
+
info = doc.elements["content/HttpErrorResponse:HttpErrorResponse"]
|
145
|
+
get_values(info, XMLMAP)
|
155
146
|
end
|
156
147
|
end
|
157
148
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
module IbmPowerHmc
|
7
|
+
class Connection
|
8
|
+
##
|
9
|
+
# @!method managed_system_metrics(sys_uuid:, start_ts: nil, end_ts: nil, no_samples: nil)
|
10
|
+
# Retrieve metrics for a managed system.
|
11
|
+
# @param sys_uuid [String] The managed system UUID.
|
12
|
+
# @param start_ts [String] Start timestamp.
|
13
|
+
# @param end_ts [String] End timestamp.
|
14
|
+
# @param no_samples [Integer] Number of samples.
|
15
|
+
# @return [Array<Hash>] The processed metrics for the managed system.
|
16
|
+
def managed_system_metrics(sys_uuid:, start_ts: nil, end_ts: nil, no_samples: nil)
|
17
|
+
method_url = "/rest/api/pcm/ManagedSystem/#{sys_uuid}/ProcessedMetrics"
|
18
|
+
query = []
|
19
|
+
query << "StartTS=#{start_ts}" unless start_ts.nil?
|
20
|
+
query << "EndTS=#{end_ts}" unless end_ts.nil?
|
21
|
+
query << "NoOfSamples=#{no_samples}" unless no_samples.nil?
|
22
|
+
method_url += "?" + query.compact.join('&') unless query.empty?
|
23
|
+
|
24
|
+
response = request(:get, method_url)
|
25
|
+
doc = REXML::Document.new(response.body)
|
26
|
+
metrics = []
|
27
|
+
doc.each_element("feed/entry") do |entry|
|
28
|
+
category = entry.elements["category"]
|
29
|
+
next if category.nil?
|
30
|
+
|
31
|
+
term = category.attributes["term"]
|
32
|
+
next if term.nil? || term != "ManagedSystem"
|
33
|
+
|
34
|
+
link = entry.elements["link"]
|
35
|
+
next if link.nil?
|
36
|
+
|
37
|
+
href = link.attributes["href"]
|
38
|
+
next if href.nil?
|
39
|
+
|
40
|
+
# Validate URI
|
41
|
+
begin
|
42
|
+
href = URI(href)
|
43
|
+
rescue
|
44
|
+
next
|
45
|
+
end
|
46
|
+
# Remove https://hostname:port prefix.
|
47
|
+
href.scheme = href.host = href.port = nil
|
48
|
+
|
49
|
+
response = request(:get, href.to_s)
|
50
|
+
metrics << JSON.parse(response.body)
|
51
|
+
end
|
52
|
+
metrics
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/ibm_power_hmc.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ibm_power_hmc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- IBM Power
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -25,12 +25,14 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.1'
|
27
27
|
description: A Ruby gem for interacting with the IBM Hardware Management Console (HMC).
|
28
|
-
email:
|
28
|
+
email:
|
29
29
|
executables: []
|
30
30
|
extensions: []
|
31
31
|
extra_rdoc_files: []
|
32
32
|
files:
|
33
33
|
- ".gitignore"
|
34
|
+
- ".rubocop.yml"
|
35
|
+
- ".rubocop_local.yml"
|
34
36
|
- CHANGELOG.md
|
35
37
|
- Gemfile
|
36
38
|
- Gemfile.lock
|
@@ -44,6 +46,7 @@ files:
|
|
44
46
|
- lib/ibm_power_hmc/connection.rb
|
45
47
|
- lib/ibm_power_hmc/job.rb
|
46
48
|
- lib/ibm_power_hmc/objects.rb
|
49
|
+
- lib/ibm_power_hmc/pcm.rb
|
47
50
|
- lib/ibm_power_hmc/version.rb
|
48
51
|
homepage: http://github.com/IBM/ibm_power_hmc_sdk_ruby
|
49
52
|
licenses:
|
@@ -53,7 +56,7 @@ metadata:
|
|
53
56
|
homepage_uri: http://github.com/IBM/ibm_power_hmc_sdk_ruby
|
54
57
|
source_code_uri: http://github.com/IBM/ibm_power_hmc_sdk_ruby
|
55
58
|
changelog_uri: http://github.com/IBM/ibm_power_hmc_sdk_ruby/blob/master/CHANGELOG.md
|
56
|
-
post_install_message:
|
59
|
+
post_install_message:
|
57
60
|
rdoc_options: []
|
58
61
|
require_paths:
|
59
62
|
- lib
|
@@ -68,8 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
71
|
- !ruby/object:Gem::Version
|
69
72
|
version: '0'
|
70
73
|
requirements: []
|
71
|
-
rubygems_version: 3.
|
72
|
-
signing_key:
|
74
|
+
rubygems_version: 3.0.3
|
75
|
+
signing_key:
|
73
76
|
specification_version: 4
|
74
77
|
summary: IBM Power HMC Ruby gem.
|
75
78
|
test_files: []
|