ibm_power_hmc 0.1.1 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 214dfa7f9a89d236f1f9bc4ee927b619596a0fabe59c2f596359637e891601ab
4
- data.tar.gz: 2affd160febc3952014ab522bb9b0f89b0ebef6d785720d2d8d2a875cd1df918
3
+ metadata.gz: c19305b95374164ab2a6e6168a4a292ea0666065cbcbe8f05dea30483b622055
4
+ data.tar.gz: be50d67e7c462cc17f20be3f643c6029e4f2ba7d43f872f1821bbe428f0e11fe
5
5
  SHA512:
6
- metadata.gz: 3e6e6ae8b4c7d84eea70e3328ea44834a5b95ecd98fbe6a31c045e575951b6c17751ca7d6517d3ad58647b5c8b7e1321470c368c48018c31a450a28ba40463e5
7
- data.tar.gz: f9139f2ea1a83d0abedc3c73832450e20fa4fcf7c56cc65c50ec5b14750bb5bb2eb17d7948ffc22d5887984d0f412ae8213a237892350e55f0cd55a49af80f30
6
+ metadata.gz: 1191f64dd2f5c550d25a372b4a0502dd4e7b5a8e779a2dacdf079a22f3a8b8092af6e4ddff514b0e06dddf8239985033034959e385f951f2f535f092866cbd12
7
+ data.tar.gz: d6af992547d99624f59e6eb5ec3404768c91d1b9c9809e9542966fee15b4a350e8b8803e6fd25a597c48699b630171b7cae8327108f0ec6616e2329c5441bf1c
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ /Gemfile.lock
1
2
  /.bundle/
2
3
  /.yardoc
3
4
  /_yardoc/
data/.rubocop_local.yml CHANGED
@@ -2,6 +2,8 @@ AllCops:
2
2
  Exclude:
3
3
  - '*.gemspec'
4
4
  Layout/HashAlignment:
5
- EnforcedHashRocketStyle: key
5
+ Enabled: false
6
6
  Style/ConditionalAssignment:
7
- EnforcedStyle: assign_inside_condition
7
+ Enabled: false
8
+ Style/OptionalBooleanParameter:
9
+ Enabled: false
data/README.md CHANGED
@@ -42,6 +42,12 @@ puts hmc.name
42
42
  puts hmc.version
43
43
  ```
44
44
 
45
+ Retrieving managed systems that are powered on:
46
+
47
+ ```ruby
48
+ hc.managed_systems("State" => "operating")
49
+ ```
50
+
45
51
  Listing the logical partitions and virtual I/O servers of each managed system:
46
52
 
47
53
  ```ruby
@@ -2,24 +2,21 @@
2
2
 
3
3
  # Module for IBM HMC Rest API Client
4
4
  module IbmPowerHmc
5
- require_relative 'pcm.rb'
6
-
7
5
  class Error < StandardError; end
8
6
 
9
7
  ##
10
8
  # HMC REST Client connection.
11
9
  class Connection
12
10
  ##
13
- # @!method initialize(host:, username: "hscroot", password:, port: 12_443, validate_ssl: true)
11
+ # @!method initialize(host:, password:, username: "hscroot", port: 12_443, validate_ssl: true)
14
12
  # Create a new HMC connection.
15
13
  #
16
14
  # @param host [String] Hostname of the HMC.
17
- # @param username [String] User name.
18
15
  # @param password [String] Password.
16
+ # @param username [String] User name.
19
17
  # @param port [Integer] TCP port number.
20
18
  # @param validate_ssl [Boolean] Verify SSL certificates.
21
- def initialize(host:, username: "hscroot", password:, port: 12_443, validate_ssl: true)
22
- # Damien: use URI::HTTPS
19
+ def initialize(host:, password:, username: "hscroot", port: 12_443, validate_ssl: true)
23
20
  @hostname = "#{host}:#{port}"
24
21
  @username = username
25
22
  @password = password
@@ -37,10 +34,8 @@ module IbmPowerHmc
37
34
  :content_type => "application/vnd.ibm.powervm.web+xml; type=LogonRequest"
38
35
  }
39
36
  doc = REXML::Document.new("")
40
- doc.add_element("LogonRequest", {
41
- "xmlns" => "http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/",
42
- "schemaVersion" => "V1_1_0"
43
- })
37
+ doc.add_element("LogonRequest", "schemaVersion" => "V1_1_0")
38
+ doc.root.add_namespace("http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/")
44
39
  doc.root.add_element("UserID").text = @username
45
40
  doc.root.add_element("Password").text = @password
46
41
 
@@ -69,15 +64,6 @@ module IbmPowerHmc
69
64
  @api_session_token = nil
70
65
  end
71
66
 
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
67
  ##
82
68
  # @!method management_console
83
69
  # Retrieve information about the management console.
@@ -85,20 +71,20 @@ module IbmPowerHmc
85
71
  def management_console
86
72
  method_url = "/rest/api/uom/ManagementConsole"
87
73
  response = request(:get, method_url)
88
- doc = REXML::Document.new(response.body)
89
74
  # This request returns a feed with a single entry.
90
- parse_feed(doc, ManagementConsole).first
75
+ FeedParser.new(response.body).objects(:ManagementConsole).first
91
76
  end
92
77
 
93
78
  ##
94
- # @!method managed_systems
79
+ # @!method managed_systems(search = {})
95
80
  # Retrieve the list of systems managed by the HMC.
81
+ # @param search [Hash] The optional property name and value to match.
96
82
  # @return [Array<IbmPowerHmc::ManagedSystem>] The list of managed systems.
97
- def managed_systems
83
+ def managed_systems(search = {})
98
84
  method_url = "/rest/api/uom/ManagedSystem"
85
+ search.each { |key, value| method_url += "/search/(#{key}==#{value})" }
99
86
  response = request(:get, method_url)
100
- doc = REXML::Document.new(response.body)
101
- parse_feed(doc, ManagedSystem)
87
+ FeedParser.new(response.body).objects(:ManagedSystem)
102
88
  end
103
89
 
104
90
  ##
@@ -106,31 +92,30 @@ module IbmPowerHmc
106
92
  # Retrieve information about a managed system.
107
93
  # @param sys_uuid [String] The UUID of the managed system.
108
94
  # @param group_name [String] The extended group attributes.
109
- # @return [IbmPowerHmc::ManagedSystem] The logical partition.
95
+ # @return [IbmPowerHmc::ManagedSystem] The managed system.
110
96
  def managed_system(sys_uuid, group_name = nil)
111
97
  method_url = "/rest/api/uom/ManagedSystem/#{sys_uuid}"
112
98
  method_url += "?group=#{group_name}" unless group_name.nil?
113
99
 
114
100
  response = request(:get, method_url)
115
- doc = REXML::Document.new(response.body)
116
- entry = doc.elements["entry"]
117
- ManagedSystem.new(entry)
101
+ Parser.new(response.body).object(:ManagedSystem)
118
102
  end
119
103
 
120
104
  ##
121
- # @!method lpars(sys_uuid = nil)
105
+ # @!method lpars(sys_uuid = nil, search = {})
122
106
  # Retrieve the list of logical partitions managed by the HMC.
123
107
  # @param sys_uuid [String] The UUID of the managed system.
108
+ # @param search [Hash] The optional property name and value to match.
124
109
  # @return [Array<IbmPowerHmc::LogicalPartition>] The list of logical partitions.
125
- def lpars(sys_uuid = nil)
110
+ def lpars(sys_uuid = nil, search = {})
126
111
  if sys_uuid.nil?
127
112
  method_url = "/rest/api/uom/LogicalPartition"
113
+ search.each { |key, value| method_url += "/search/(#{key}==#{value})" }
128
114
  else
129
115
  method_url = "/rest/api/uom/ManagedSystem/#{sys_uuid}/LogicalPartition"
130
116
  end
131
117
  response = request(:get, method_url)
132
- doc = REXML::Document.new(response.body)
133
- parse_feed(doc, LogicalPartition)
118
+ FeedParser.new(response.body).objects(:LogicalPartition)
134
119
  end
135
120
 
136
121
  ##
@@ -149,15 +134,14 @@ module IbmPowerHmc
149
134
  method_url += "?group=#{group_name}" unless group_name.nil?
150
135
 
151
136
  response = request(:get, method_url)
152
- doc = REXML::Document.new(response.body)
153
- entry = doc.elements["entry"]
154
- LogicalPartition.new(entry)
137
+ Parser.new(response.body).object(:LogicalPartition)
155
138
  end
156
139
 
157
140
  ##
158
141
  # @!method lpar_quick_property(lpar_uuid, property_name)
159
142
  # Retrieve a quick property of a logical partition.
160
143
  # @param lpar_uuid [String] The UUID of the logical partition.
144
+ # @param property_name [String] The quick property name.
161
145
  # @return [String] The quick property value.
162
146
  def lpar_quick_property(lpar_uuid, property_name)
163
147
  method_url = "/rest/api/uom/LogicalPartition/#{lpar_uuid}/quick/#{property_name}"
@@ -167,19 +151,31 @@ module IbmPowerHmc
167
151
  end
168
152
 
169
153
  ##
170
- # @!method vioses(sys_uuid = nil)
154
+ # @!method rename_lpar(lpar_uuid, new_name)
155
+ # Rename a logical partition.
156
+ # @param lpar_uuid [String] The UUID of the logical partition.
157
+ # @param new_name [String] The new name of the logical partition.
158
+ def rename_lpar(lpar_uuid, new_name)
159
+ method_url = "/rest/api/uom/LogicalPartition/#{lpar_uuid}"
160
+
161
+ modify_object(method_url) { |lpar| lpar.name = new_name }
162
+ end
163
+
164
+ ##
165
+ # @!method vioses(sys_uuid = nil, search = {})
171
166
  # Retrieve the list of virtual I/O servers managed by the HMC.
172
167
  # @param sys_uuid [String] The UUID of the managed system.
168
+ # @param search [Hash] The optional property name and value to match.
173
169
  # @return [Array<IbmPowerHmc::VirtualIOServer>] The list of virtual I/O servers.
174
- def vioses(sys_uuid = nil)
170
+ def vioses(sys_uuid = nil, search = {})
175
171
  if sys_uuid.nil?
176
172
  method_url = "/rest/api/uom/VirtualIOServer"
173
+ search.each { |key, value| method_url += "/search/(#{key}==#{value})" }
177
174
  else
178
175
  method_url = "/rest/api/uom/ManagedSystem/#{sys_uuid}/VirtualIOServer"
179
176
  end
180
177
  response = request(:get, method_url)
181
- doc = REXML::Document.new(response.body)
182
- parse_feed(doc, VirtualIOServer)
178
+ FeedParser.new(response.body).objects(:VirtualIOServer)
183
179
  end
184
180
 
185
181
  ##
@@ -198,9 +194,27 @@ module IbmPowerHmc
198
194
  method_url += "?group=#{group_name}" unless group_name.nil?
199
195
 
200
196
  response = request(:get, method_url)
201
- doc = REXML::Document.new(response.body)
202
- entry = doc.elements["entry"]
203
- VirtualIOServer.new(entry)
197
+ Parser.new(response.body).object(:VirtualIOServer)
198
+ end
199
+
200
+ ##
201
+ # @!method network_adapter_lpar(lpar_uuid, netadap_uuid = nil)
202
+ # Retrieve one or all virtual ethernet network adapters attached to a logical partition.
203
+ # @param lpar_uuid [String] UUID of the logical partition.
204
+ # @param netadap_uuid [String] UUID of the adapter to match (returns all adapters if omitted).
205
+ # @return [Array<IbmPowerHmc::ClientNetworkAdapter>] The list of network adapters.
206
+ def network_adapter_lpar(lpar_uuid, netadap_uuid = nil)
207
+ network_adapter("LogicalPartition", lpar_uuid, netadap_uuid)
208
+ end
209
+
210
+ ##
211
+ # @!method network_adapter_vios(vios_uuid, netadap_uuid = nil)
212
+ # Retrieve one or all virtual ethernet network adapters attached to a Virtual I/O Server.
213
+ # @param vios_uuid [String] UUID of the Virtual I/O Server.
214
+ # @param netadap_uuid [String] UUID of the adapter to match (returns all adapters if omitted).
215
+ # @return [Array<IbmPowerHmc::ClientNetworkAdapter>] The list of network adapters.
216
+ def network_adapter_vios(vios_uuid, netadap_uuid = nil)
217
+ network_adapter("VirtualIOServer", vios_uuid, netadap_uuid)
204
218
  end
205
219
 
206
220
  ##
@@ -221,9 +235,7 @@ module IbmPowerHmc
221
235
  ##
222
236
  # @!method poweroff_lpar(lpar_uuid, params = {}, sync = true)
223
237
  # 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.
238
+ # @param (see #poweron_lpar)
227
239
  # @return [IbmPowerHmc::HmcJob] The HMC job.
228
240
  def poweroff_lpar(lpar_uuid, params = {}, sync = true)
229
241
  method_url = "/rest/api/uom/LogicalPartition/#{lpar_uuid}/do/PowerOff"
@@ -251,9 +263,7 @@ module IbmPowerHmc
251
263
  ##
252
264
  # @!method poweroff_vios(vios_uuid, params = {}, sync = true)
253
265
  # 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.
266
+ # @param (see #poweron_vios)
257
267
  # @return [IbmPowerHmc::HmcJob] The HMC job.
258
268
  def poweroff_vios(vios_uuid, params = {}, sync = true)
259
269
  method_url = "/rest/api/uom/VirtualIOServer/#{vios_uuid}/do/PowerOff"
@@ -281,9 +291,7 @@ module IbmPowerHmc
281
291
  ##
282
292
  # @!method poweroff_managed_system(sys_uuid, params = {}, sync = true)
283
293
  # 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.
294
+ # @param (see #poweron_managed_system)
287
295
  # @return [IbmPowerHmc::HmcJob] The HMC job.
288
296
  def poweroff_managed_system(sys_uuid, params = {}, sync = true)
289
297
  method_url = "/rest/api/uom/ManagedSystem/#{sys_uuid}/do/PowerOff"
@@ -293,6 +301,21 @@ module IbmPowerHmc
293
301
  job
294
302
  end
295
303
 
304
+ ##
305
+ # @!method remove_connection(hmc_uuid, sys_uuid, sync = true)
306
+ # Remove a managed system from the management console.
307
+ # @param hmc_uuid [String] The UUID of the management console.
308
+ # @param sys_uuid [String] The UUID of the managed system.
309
+ # @param sync [Boolean] Start the job and wait for its completion.
310
+ # @return [IbmPowerHmc::HmcJob] The HMC job.
311
+ def remove_connection(hmc_uuid, sys_uuid, sync = true)
312
+ method_url = "/rest/api/uom/ManagementConsole/#{hmc_uuid}/ManagedSystem/#{sys_uuid}/do/RemoveConnection"
313
+
314
+ job = HmcJob.new(self, method_url, "RemoveConnection", "ManagedSystem")
315
+ job.run if sync
316
+ job
317
+ end
318
+
296
319
  ##
297
320
  # @!method cli_run(hmc_uuid, cmd, sync = true)
298
321
  # Run a CLI command on the HMC as a job.
@@ -312,6 +335,29 @@ module IbmPowerHmc
312
335
  job
313
336
  end
314
337
 
338
+ ##
339
+ # @!method virtual_switches(sys_uuid)
340
+ # Retrieve the list of virtual switches from a specified managed system.
341
+ # @param sys_uuid [String] The UUID of the managed system.
342
+ # @return [Array<IbmPowerHmc::VirtualSwitch>] The list of virtual switches.
343
+ def virtual_switches(sys_uuid)
344
+ method_url = "/rest/api/uom/ManagedSystem/#{sys_uuid}/VirtualSwitch"
345
+ response = request(:get, method_url)
346
+ FeedParser.new(response.body).objects(:VirtualSwitch)
347
+ end
348
+
349
+ ##
350
+ # @!method virtual_switch(vswitch_uuid, sys_uuid)
351
+ # Retrieve information about a virtual switch.
352
+ # @param vswitch_uuid [String] The UUID of the virtual switch.
353
+ # @param sys_uuid [String] The UUID of the managed system.
354
+ # @return [IbmPowerHmc::VirtualSwitch] The virtual switch.
355
+ def virtual_switch(vswitch_uuid, sys_uuid)
356
+ method_url = "/rest/api/uom/ManagedSystem/#{sys_uuid}/VirtualSwitch/#{vswitch_uuid}"
357
+ response = request(:get, method_url)
358
+ Parser.new(response.body).object(:VirtualSwitch)
359
+ end
360
+
315
361
  ##
316
362
  # @!method next_events(wait = true)
317
363
  # Retrieve a list of events that occured since last call.
@@ -326,12 +372,22 @@ module IbmPowerHmc
326
372
  # No need to sleep as the HMC already waits a bit before returning 204
327
373
  break if response.code != 204 || !wait
328
374
  end
329
- doc = REXML::Document.new(response.body)
330
- parse_feed(doc, Event)
375
+ FeedParser.new(response.body).objects(:Event)
376
+ end
377
+
378
+ ##
379
+ # @!method schema(type)
380
+ # Retrieve the XML schema file for a given object type.
381
+ # @param type [String] The object type (e.g. "LogicalPartition", "inc/Types")
382
+ # @return [REXML::Document] The XML schema file.
383
+ def schema(type)
384
+ method_url = "/rest/api/web/schema/#{type}.xsd"
385
+ response = request(:get, method_url)
386
+ REXML::Document.new(response.body)
331
387
  end
332
388
 
333
389
  class HttpError < Error
334
- attr_reader :status, :uri, :reason, :message
390
+ attr_reader :status, :uri, :reason, :message, :original_exception
335
391
 
336
392
  ##
337
393
  # @!method initialize(err)
@@ -339,18 +395,24 @@ module IbmPowerHmc
339
395
  # @param err [RestClient::Exception] The REST client exception.
340
396
  def initialize(err)
341
397
  super
398
+ @original_exception = err
342
399
  @status = err.http_code
400
+ @message = err.message
343
401
 
344
402
  # 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
403
+ unless err.response.nil?
404
+ resp = Parser.new(err.response.body).object(:HttpErrorResponse)
405
+ unless resp.nil?
406
+ @uri = resp.uri
407
+ @reason = resp.reason
408
+ @message = resp.message
409
+ end
352
410
  end
353
411
  end
412
+
413
+ def to_s
414
+ "msg=\"#{@message}\" status=\"#{@status}\" reason=\"#{@reason}\" uri=#{@uri}"
415
+ end
354
416
  end
355
417
 
356
418
  ##
@@ -364,11 +426,13 @@ module IbmPowerHmc
364
426
  def request(method, url, headers = {}, payload = nil)
365
427
  logon if @api_session_token.nil?
366
428
  reauth = false
429
+ # Check for relative URLs
430
+ url = "https://#{@hostname}#{url}" if url.start_with?("/")
367
431
  begin
368
- headers = headers.merge({"X-API-Session" => @api_session_token})
432
+ headers = headers.merge("X-API-Session" => @api_session_token)
369
433
  RestClient::Request.execute(
370
434
  :method => method,
371
- :url => "https://" + @hostname + url,
435
+ :url => url,
372
436
  :verify_ssl => @verify_ssl,
373
437
  :payload => payload,
374
438
  :headers => headers
@@ -384,5 +448,52 @@ module IbmPowerHmc
384
448
  raise HttpError.new(e), "REST request failed"
385
449
  end
386
450
  end
451
+
452
+ private
453
+
454
+ # @!method modify_object(method_url, headers = {}, attempts = 5)
455
+ # Modify an object at a specified URI.
456
+ # @param method_url [String] The URL of the object to modify.
457
+ # @param headers [Hash] HTTP headers.
458
+ # @param attempts [Integer] Maximum number of retries.
459
+ # @yield [obj] The object to modify.
460
+ # @yieldparam obj [IbmPowerHmc::AbstractRest] The object to modify.
461
+ def modify_object(method_url, headers = {}, attempts = 5)
462
+ while attempts > 0
463
+ response = request(:get, method_url)
464
+ obj = Parser.new(response.body).object
465
+
466
+ yield obj
467
+
468
+ # Use ETag to ensure object has not changed.
469
+ headers = headers.merge("If-Match" => obj.etag, :content_type => obj.content_type)
470
+ begin
471
+ request(:post, method_url, headers, obj.xml.to_s)
472
+ break
473
+ rescue HttpError => e
474
+ attempts -= 1
475
+ # Will get 412 ("Precondition Failed") if ETag mismatches
476
+ raise if e.status != 412 || attempts == 0
477
+ end
478
+ end
479
+ end
480
+
481
+ ##
482
+ # @!method network_adapter_lpar(lpar_uuid, netadap_uuid = nil)
483
+ # Retrieve one or all virtual ethernet network adapters attached to a Logical Partition or a Virtual I/O Server.
484
+ # @param vm_type [String] "Logical Partition" or "VirtualIOServer".
485
+ # @param lpar_uuid [String] UUID of the Logical Partition or the Virtual I/O Server.
486
+ # @param netadap_uuid [String] UUID of the adapter to match (returns all adapters if nil).
487
+ # @return [Array<IbmPowerHmc::ClientNetworkAdapter>] The list of network adapters.
488
+ def network_adapter(vm_type, lpar_uuid, netadap_uuid)
489
+ if netadap_uuid.nil?
490
+ method_url = "/rest/api/uom/#{vm_type}/#{lpar_uuid}/ClientNetworkAdapter"
491
+ else
492
+ method_url = "/rest/api/uom/#{vm_type}/#{lpar_uuid}/ClientNetworkAdapter/#{netadap_uuid}"
493
+ end
494
+
495
+ response = request(:get, method_url)
496
+ Parser.new(response.body).object(:ClientNetworkAdapter)
497
+ end
387
498
  end
388
499
  end
@@ -24,7 +24,7 @@ module IbmPowerHmc
24
24
  end
25
25
 
26
26
  ##
27
- # @!method status
27
+ # @!method start
28
28
  # Start the job asynchronously.
29
29
  # @return [String] The ID of the job.
30
30
  def start
@@ -32,25 +32,22 @@ module IbmPowerHmc
32
32
  :content_type => "application/vnd.ibm.powervm.web+xml; type=JobRequest"
33
33
  }
34
34
  doc = REXML::Document.new("")
35
- doc.add_element("JobRequest:JobRequest", {
36
- "xmlns:JobRequest" => "http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/",
37
- "xmlns" => "http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/",
38
- "schemaVersion" => "V1_1_0"
39
- })
40
- op = doc.root.add_element("RequestedOperation", {"schemaVersion" => "V1_1_0"})
35
+ doc.add_element("JobRequest:JobRequest", "schemaVersion" => "V1_1_0")
36
+ doc.root.add_namespace("http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/")
37
+ doc.root.add_namespace("JobRequest", "http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/")
38
+ op = doc.root.add_element("RequestedOperation", "schemaVersion" => "V1_1_0")
41
39
  op.add_element("OperationName").text = @operation
42
40
  op.add_element("GroupName").text = @group
43
- # Damien: ProgressType?
44
- jobparams = doc.root.add_element("JobParameters", {"schemaVersion" => "V1_1_0"})
41
+
42
+ jobparams = doc.root.add_element("JobParameters", "schemaVersion" => "V1_1_0")
45
43
  @params.each do |key, value|
46
- jobparam = jobparams.add_element("JobParameter", {"schemaVersion" => "V1_1_0"})
44
+ jobparam = jobparams.add_element("JobParameter", "schemaVersion" => "V1_1_0")
47
45
  jobparam.add_element("ParameterName").text = key
48
46
  jobparam.add_element("ParameterValue").text = value
49
47
  end
50
48
  response = @conn.request(:put, @method_url, headers, doc.to_s)
51
- doc = REXML::Document.new(response.body)
52
- info = doc.root.elements["content/JobResponse:JobResponse"]
53
- @id = info.elements["JobID"].text
49
+ jobresp = Parser.new(response.body).object(:JobResponse)
50
+ @id = jobresp.id
54
51
  end
55
52
 
56
53
  # @return [Hash] The job results returned by the HMC.
@@ -68,20 +65,9 @@ module IbmPowerHmc
68
65
  :content_type => "application/vnd.ibm.powervm.web+xml; type=JobRequest"
69
66
  }
70
67
  response = @conn.request(:get, method_url, headers)
71
- doc = REXML::Document.new(response.body)
72
- info = doc.root.elements["content/JobResponse:JobResponse"]
73
- status = info.elements["Status"].text
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
-
84
- status
68
+ jobresp = Parser.new(response.body).object(:JobResponse)
69
+ @results = jobresp.results
70
+ jobresp.status
85
71
  end
86
72
 
87
73
  ##
@@ -112,8 +98,7 @@ module IbmPowerHmc
112
98
  # @return [String] The status of the job.
113
99
  def run(timeout = 120, poll_interval = 0)
114
100
  start
115
- status = wait(timeout, poll_interval)
116
- status
101
+ wait(timeout, poll_interval)
117
102
  ensure
118
103
  delete if defined?(@id)
119
104
  end
@@ -0,0 +1,302 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'uri'
5
+
6
+ module IbmPowerHmc
7
+ ##
8
+ # Generic parser for HMC K2 XML responses.
9
+ class Parser
10
+ def initialize(body)
11
+ @doc = REXML::Document.new(body)
12
+ end
13
+
14
+ ##
15
+ # @!method entry
16
+ # Return the first K2 entry element in the response.
17
+ # @return [REXML::Element, nil] The first entry element.
18
+ def entry
19
+ @doc.elements["entry"]
20
+ end
21
+
22
+ ##
23
+ # @!method object(filter_type = nil)
24
+ # Parse the first K2 entry element into an object.
25
+ # @param filter_type [String] Entry type must match the specified type.
26
+ # @return [IbmPowerHmc::AbstractRest, nil] The parsed object.
27
+ def object(filter_type = nil)
28
+ self.class.to_obj(entry, filter_type)
29
+ end
30
+
31
+ def self.to_obj(entry, filter_type = nil)
32
+ return if entry.nil?
33
+
34
+ content = entry.elements["content[@type]"]
35
+ return if content.nil?
36
+
37
+ type = content.attributes["type"].split("=").last
38
+ return unless filter_type.nil? || filter_type.to_s == type
39
+
40
+ Module.const_get("IbmPowerHmc::#{type}").new(entry)
41
+ end
42
+ end
43
+
44
+ ##
45
+ # Parser for HMC K2 feeds.
46
+ # A feed encapsulates a list of entries like this:
47
+ # <feed>
48
+ # <entry>
49
+ # <!-- entry #1 -->
50
+ # </entry>
51
+ # <entry>
52
+ # <!-- entry #2 -->
53
+ # </entry>
54
+ # ...
55
+ # </feed>
56
+ class FeedParser < Parser
57
+ def entries
58
+ objs = []
59
+ @doc.each_element("feed/entry") do |entry|
60
+ objs << yield(entry)
61
+ end
62
+ objs
63
+ end
64
+
65
+ ##
66
+ # @!method objects(filter_type = nil)
67
+ # Parse feed entries into objects.
68
+ # @param filter_type [String] Filter entries based on content type.
69
+ # @return [Array<IbmPowerHmc::AbstractRest>] The list of objects.
70
+ def objects(filter_type = nil)
71
+ entries do |entry|
72
+ self.class.to_obj(entry, filter_type)
73
+ end.compact
74
+ end
75
+ end
76
+
77
+ private_constant :Parser
78
+ private_constant :FeedParser
79
+
80
+ ##
81
+ # HMC generic K2 XML entry.
82
+ # Encapsulate data for a single object.
83
+ # The XML looks like this:
84
+ # <entry>
85
+ # <id>uuid</id>
86
+ # <published>timestamp</published>
87
+ # <etag:etag>ETag</etag:etag>
88
+ # <content type="type">
89
+ # <!-- actual content here -->
90
+ # </content>
91
+ # </entry>
92
+ #
93
+ # @abstract
94
+ # @attr_reader [String] uuid The UUID of the object contained in the entry.
95
+ # @attr_reader [URI::HTTPS] href The URL of the object itself.
96
+ # @attr_reader [Time] published The time at which the entry was published.
97
+ # @attr_reader [String] etag The entity tag of the entry.
98
+ # @attr_reader [String] content_type The content type of the object contained in the entry.
99
+ # @attr_reader [REXML::Document] xml The XML document representing this object.
100
+ class AbstractRest
101
+ ATTRS = {}.freeze
102
+ attr_reader :uuid, :href, :published, :etag, :content_type, :xml
103
+
104
+ def initialize(doc)
105
+ @uuid = doc.elements["id"]&.text
106
+ link = doc.elements["link[@rel='SELF']"]
107
+ @href = URI(link.attributes["href"]) unless link.nil?
108
+ @published = Time.xmlschema(doc.elements["published"]&.text)
109
+ @etag = doc.elements["etag:etag"]&.text&.strip
110
+ content = doc.elements["content"]
111
+ @content_type = content.attributes["type"]
112
+ @xml = content.elements.first
113
+ define_attrs(self.class::ATTRS)
114
+ end
115
+
116
+ ##
117
+ # @!method define_attr(varname, xpath)
118
+ # Define an instance variable using the text of an XML element as value.
119
+ # @param varname [String] The name of the instance variable.
120
+ # @param xpath [String] The XPath of the XML element containing the text.
121
+ def define_attr(varname, xpath)
122
+ value = singleton(xpath)
123
+ self.class.__send__(:attr_reader, varname)
124
+ instance_variable_set("@#{varname}", value)
125
+ end
126
+
127
+ ##
128
+ # @!method define_attrs(hash)
129
+ # Define instance variables using the texts of XML elements as values.
130
+ # @param hash [Hash] The name of the instance variables and the XPaths
131
+ # of the XML elements containing the values.
132
+ def define_attrs(hash)
133
+ hash.each do |key, value|
134
+ define_attr(key, value)
135
+ end
136
+ end
137
+
138
+ ##
139
+ # @!method singleton(xpath, attr = nil)
140
+ # Get the text (or the value of a specified attribute) of an XML element.
141
+ # @param xpath [String] The XPath of the XML element.
142
+ # @param attr [String] The name of the attribute.
143
+ # @return [String, nil] The text or attribute value of the XML element or nil.
144
+ # @example lpar.singleton("PartitionProcessorConfiguration/*/MaximumVirtualProcessors").to_i
145
+ def singleton(xpath, attr = nil)
146
+ elem = xml.elements[xpath]
147
+ return if elem.nil?
148
+
149
+ attr.nil? ? elem.text&.strip : elem.attributes[attr]
150
+ end
151
+
152
+ def extract_uuid_from_href(href)
153
+ URI(href).path.split('/').last
154
+ end
155
+ end
156
+
157
+ # HMC information
158
+ class ManagementConsole < AbstractRest
159
+ ATTRS = {
160
+ :name => "ManagementConsoleName",
161
+ :build_level => "VersionInfo/BuildLevel",
162
+ :version => "BaseVersion"
163
+ }.freeze
164
+
165
+ def managed_systems_uuids
166
+ xml.get_elements("ManagedSystems/link").map do |link|
167
+ extract_uuid_from_href(link.attributes["href"])
168
+ end.compact
169
+ end
170
+ end
171
+
172
+ # Managed System information
173
+ class ManagedSystem < AbstractRest
174
+ ATTRS = {
175
+ :name => "SystemName",
176
+ :state => "State",
177
+ :hostname => "Hostname",
178
+ :ipaddr => "PrimaryIPAddress",
179
+ :fwversion => "SystemFirmware",
180
+ :memory => "AssociatedSystemMemoryConfiguration/InstalledSystemMemory",
181
+ :avail_mem => "AssociatedSystemMemoryConfiguration/CurrentAvailableSystemMemory",
182
+ :cpus => "AssociatedSystemProcessorConfiguration/InstalledSystemProcessorUnits",
183
+ :avail_cpus => "AssociatedSystemProcessorConfiguration/CurrentAvailableSystemProcessorUnits",
184
+ :mtype => "MachineTypeModelAndSerialNumber/MachineType",
185
+ :model => "MachineTypeModelAndSerialNumber/Model",
186
+ :serial => "MachineTypeModelAndSerialNumber/SerialNumber"
187
+ }.freeze
188
+
189
+ def lpars_uuids
190
+ xml.get_elements("AssociatedLogicalPartitions/link").map do |link|
191
+ extract_uuid_from_href(link.attributes["href"])
192
+ end.compact
193
+ end
194
+
195
+ def vioses_uuids
196
+ xml.get_elements("AssociatedVirtualIOServers/link").map do |link|
197
+ extract_uuid_from_href(link.attributes["href"])
198
+ end.compact
199
+ end
200
+ end
201
+
202
+ # Common class for LPAR and VIOS
203
+ class BasePartition < AbstractRest
204
+ ATTRS = {
205
+ :name => "PartitionName",
206
+ :id => "PartitionID",
207
+ :state => "PartitionState",
208
+ :type => "PartitionType",
209
+ :memory => "PartitionMemoryConfiguration/CurrentMemory",
210
+ :dedicated => "PartitionProcessorConfiguration/HasDedicatedProcessors",
211
+ :rmc_state => "ResourceMonitoringControlState",
212
+ :rmc_ipaddr => "ResourceMonitoringIPAddress",
213
+ :os => "OperatingSystemVersion",
214
+ :ref_code => "ReferenceCode"
215
+ }.freeze
216
+
217
+ def sys_uuid
218
+ sys_href = singleton("AssociatedManagedSystem", "href")
219
+ extract_uuid_from_href(sys_href)
220
+ end
221
+
222
+ def net_adap_uuids
223
+ xml.get_elements("ClientNetworkAdapters/link").map do |link|
224
+ extract_uuid_from_href(link.attributes["href"])
225
+ end
226
+ end
227
+
228
+ def name=(name)
229
+ xml.elements[ATTRS[:name]].text = name
230
+ @name = name
231
+ end
232
+ end
233
+
234
+ # Logical Partition information
235
+ class LogicalPartition < BasePartition
236
+ end
237
+
238
+ # VIOS information
239
+ class VirtualIOServer < BasePartition
240
+ end
241
+
242
+ # Virtual Switch information
243
+ class VirtualSwitch < AbstractRest
244
+ ATTRS = {
245
+ :id => "SwitchID",
246
+ :mode => "SwitchMode",
247
+ :name => "SwitchName"
248
+ }.freeze
249
+
250
+ def sys_uuid
251
+ href.path.split('/')[-3]
252
+ end
253
+ end
254
+
255
+ # HMC Event
256
+ class Event < AbstractRest
257
+ ATTRS = {
258
+ :id => "EventID",
259
+ :type => "EventType",
260
+ :data => "EventData",
261
+ :detail => "EventDetail"
262
+ }.freeze
263
+ end
264
+
265
+ # Network adapter information
266
+ class ClientNetworkAdapter < AbstractRest
267
+ ATTRS = {
268
+ :macaddr => "MACAddress",
269
+ :vswitch_id => "VirtualSwitchID",
270
+ :vlan_id => "PortVLANID"
271
+ }.freeze
272
+ end
273
+
274
+ # Error response from HMC
275
+ class HttpErrorResponse < AbstractRest
276
+ ATTRS = {
277
+ :status => "HTTPStatus",
278
+ :uri => "RequestURI",
279
+ :reason => "ReasonCode",
280
+ :message => "Message"
281
+ }.freeze
282
+ end
283
+
284
+ # Job Response
285
+ class JobResponse < AbstractRest
286
+ ATTRS = {
287
+ :id => "JobID",
288
+ :status => "Status",
289
+ :message => "ResponseException/Message"
290
+ }.freeze
291
+
292
+ def results
293
+ results = {}
294
+ xml.each_element("Results/JobParameter") do |jobparam|
295
+ name = jobparam.elements["ParameterName"]&.text&.strip
296
+ value = jobparam.elements["ParameterValue"]&.text&.strip
297
+ results[name] = value unless name.nil?
298
+ end
299
+ results
300
+ end
301
+ end
302
+ end
@@ -5,26 +5,62 @@ require 'uri'
5
5
 
6
6
  module IbmPowerHmc
7
7
  class Connection
8
+ def pcm_preferences
9
+ method_url = "/rest/api/pcm/preferences"
10
+
11
+ response = request(:get, method_url)
12
+ REXML::Document.new(response.body)
13
+ end
14
+
15
+ ##
16
+ # @!method phyp_metrics(sys_uuid:, start_ts: nil, end_ts: nil, short_term: false)
17
+ # Retrieve PowerVM metrics for a given managed system.
18
+ # @param sys_uuid [String] The managed system UUID.
19
+ # @param start_ts [Time] Start timestamp.
20
+ # @param end_ts [Time] End timestamp.
21
+ # @param short_term [Boolean] Retrieve short term monitor metrics (default to long term).
22
+ # @return [Array<Hash>] The PowerVM metrics for the managed system.
23
+ def phyp_metrics(sys_uuid:, start_ts: nil, end_ts: nil, short_term: false)
24
+ type = short_term ? "ShortTermMonitor" : "LongTermMonitor"
25
+ method_url = "/rest/api/pcm/ManagedSystem/#{sys_uuid}/RawMetrics/#{type}"
26
+ query = {}
27
+ query["StartTS"] = self.class.format_time(start_ts) unless start_ts.nil?
28
+ query["EndTS"] = self.class.format_time(end_ts) unless end_ts.nil?
29
+ method_url += "?" + query.map { |h| h.join("=") }.join("&") unless query.empty?
30
+
31
+ response = request(:get, method_url)
32
+ FeedParser.new(response.body).entries do |entry|
33
+ link = entry.elements["link"]
34
+ next if link.nil?
35
+
36
+ href = link.attributes["href"]
37
+ next if href.nil?
38
+
39
+ response = request(:get, href)
40
+ JSON.parse(response.body)
41
+ end.compact
42
+ end
43
+
8
44
  ##
9
- # @!method managed_system_metrics(sys_uuid:, start_ts: nil, end_ts: nil, no_samples: nil)
45
+ # @!method managed_system_metrics(sys_uuid:, start_ts: nil, end_ts: nil, no_samples: nil, aggregated: false)
10
46
  # Retrieve metrics for a managed system.
11
47
  # @param sys_uuid [String] The managed system UUID.
12
- # @param start_ts [String] Start timestamp.
13
- # @param end_ts [String] End timestamp.
48
+ # @param start_ts [Time] Start timestamp.
49
+ # @param end_ts [Time] End timestamp.
14
50
  # @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?
51
+ # @param aggregated [Boolean] Retrieve aggregated metrics (default to Processed).
52
+ # @return [Array<Hash>] The metrics for the managed system.
53
+ def managed_system_metrics(sys_uuid:, start_ts: nil, end_ts: nil, no_samples: nil, aggregated: false)
54
+ type = aggregated ? "AggregatedMetrics" : "ProcessedMetrics"
55
+ method_url = "/rest/api/pcm/ManagedSystem/#{sys_uuid}/#{type}"
56
+ query = {}
57
+ query["StartTS"] = self.class.format_time(start_ts) unless start_ts.nil?
58
+ query["EndTS"] = self.class.format_time(end_ts) unless end_ts.nil?
59
+ query["NoOfSamples"] = no_samples unless no_samples.nil?
60
+ method_url += "?" + query.map { |h| h.join("=") }.join("&") unless query.empty?
23
61
 
24
62
  response = request(:get, method_url)
25
- doc = REXML::Document.new(response.body)
26
- metrics = []
27
- doc.each_element("feed/entry") do |entry|
63
+ FeedParser.new(response.body).entries do |entry|
28
64
  category = entry.elements["category"]
29
65
  next if category.nil?
30
66
 
@@ -37,19 +73,50 @@ module IbmPowerHmc
37
73
  href = link.attributes["href"]
38
74
  next if href.nil?
39
75
 
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
76
+ response = request(:get, href)
77
+ JSON.parse(response.body)
78
+ end.compact
79
+ end
80
+
81
+ ##
82
+ # @!method lpar_metrics(sys_uuid:, lpar_uuid:, start_ts: nil, end_ts: nil, no_samples: nil, aggregated: false)
83
+ # Retrieve metrics for a logical partition.
84
+ # @param sys_uuid [String] The managed system UUID.
85
+ # @param lpar_uuid [String] The logical partition UUID.
86
+ # @param start_ts [Time] Start timestamp.
87
+ # @param end_ts [Time] End timestamp.
88
+ # @param no_samples [Integer] Number of samples.
89
+ # @param aggregated [Boolean] Retrieve aggregated metrics (default to Processed).
90
+ # @return [Array<Hash>] The metrics for the logical partition.
91
+ def lpar_metrics(sys_uuid:, lpar_uuid:, start_ts: nil, end_ts: nil, no_samples: nil, aggregated: false)
92
+ type = aggregated ? "AggregatedMetrics" : "ProcessedMetrics"
93
+ method_url = "/rest/api/pcm/ManagedSystem/#{sys_uuid}/LogicalPartition/#{lpar_uuid}/#{type}"
94
+ query = {}
95
+ query["StartTS"] = self.class.format_time(start_ts) unless start_ts.nil?
96
+ query["EndTS"] = self.class.format_time(end_ts) unless end_ts.nil?
97
+ query["NoOfSamples"] = no_samples unless no_samples.nil?
98
+ method_url += "?" + query.map { |h| h.join("=") }.join("&") unless query.empty?
99
+
100
+ response = request(:get, method_url)
101
+ FeedParser(response.body).entries do |entry|
102
+ link = entry.elements["link"]
103
+ next if link.nil?
104
+
105
+ href = link.attributes["href"]
106
+ next if href.nil?
107
+
108
+ response = request(:get, href)
109
+ JSON.parse(response.body)
110
+ end.compact
111
+ end
112
+
113
+ ##
114
+ # @!method format_time(time)
115
+ # Convert ruby time to HMC time format.
116
+ # @param time [Time] The ruby time to convert.
117
+ # @return [String] The time in HMC format.
118
+ def self.format_time(time)
119
+ time.utc.xmlschema
53
120
  end
54
121
  end
55
122
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IbmPowerHmc
4
- VERSION = "0.1.1"
4
+ VERSION = "0.4.0"
5
5
  end
data/lib/ibm_power_hmc.rb CHANGED
@@ -7,7 +7,8 @@ require "ibm_power_hmc/version"
7
7
 
8
8
  # Module for IBM HMC Rest API Client
9
9
  module IbmPowerHmc
10
- require_relative "./ibm_power_hmc/objects.rb"
11
- require_relative "./ibm_power_hmc/job.rb"
12
- require_relative "./ibm_power_hmc/connection.rb"
10
+ require_relative "./ibm_power_hmc/parser"
11
+ require_relative "./ibm_power_hmc/job"
12
+ require_relative "./ibm_power_hmc/connection"
13
+ require_relative "./ibm_power_hmc/pcm"
13
14
  end
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.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - IBM Power
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-28 00:00:00.000000000 Z
11
+ date: 2021-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -35,7 +35,6 @@ files:
35
35
  - ".rubocop_local.yml"
36
36
  - CHANGELOG.md
37
37
  - Gemfile
38
- - Gemfile.lock
39
38
  - LICENSE
40
39
  - README.md
41
40
  - Rakefile
@@ -45,7 +44,7 @@ files:
45
44
  - lib/ibm_power_hmc.rb
46
45
  - lib/ibm_power_hmc/connection.rb
47
46
  - lib/ibm_power_hmc/job.rb
48
- - lib/ibm_power_hmc/objects.rb
47
+ - lib/ibm_power_hmc/parser.rb
49
48
  - lib/ibm_power_hmc/pcm.rb
50
49
  - lib/ibm_power_hmc/version.rb
51
50
  homepage: http://github.com/IBM/ibm_power_hmc_sdk_ruby
@@ -71,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
70
  - !ruby/object:Gem::Version
72
71
  version: '0'
73
72
  requirements: []
74
- rubygems_version: 3.0.3
73
+ rubygems_version: 3.1.4
75
74
  signing_key:
76
75
  specification_version: 4
77
76
  summary: IBM Power HMC Ruby gem.
data/Gemfile.lock DELETED
@@ -1,37 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- ibm_power_hmc (0.1.0)
5
- rest-client (~> 2.1)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- domain_name (0.5.20190701)
11
- unf (>= 0.0.5, < 1.0.0)
12
- http-accept (1.7.0)
13
- http-cookie (1.0.4)
14
- domain_name (~> 0.5)
15
- mime-types (3.3.1)
16
- mime-types-data (~> 3.2015)
17
- mime-types-data (3.2021.0704)
18
- netrc (0.11.0)
19
- rake (12.3.3)
20
- rest-client (2.1.0)
21
- http-accept (>= 1.7.0, < 2.0)
22
- http-cookie (>= 1.0.2, < 2.0)
23
- mime-types (>= 1.16, < 4.0)
24
- netrc (~> 0.8)
25
- unf (0.1.4)
26
- unf_ext
27
- unf_ext (0.0.7.7)
28
-
29
- PLATFORMS
30
- ruby
31
-
32
- DEPENDENCIES
33
- ibm_power_hmc!
34
- rake (~> 12.0)
35
-
36
- BUNDLED WITH
37
- 2.1.4
@@ -1,148 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'uri'
4
-
5
- # Module for IBM HMC Rest API Client
6
- module IbmPowerHmc
7
- # HMC generic object
8
- class HmcObject
9
- attr_reader :uuid
10
-
11
- def initialize(doc)
12
- @uuid = doc.elements["id"].text
13
- end
14
-
15
- def get_value(doc, xpath, varname)
16
- value = doc.elements[xpath]
17
- value = value.text unless value.nil?
18
- value = value.strip unless value.nil?
19
- self.class.__send__(:attr_reader, varname)
20
- instance_variable_set("@#{varname}", value)
21
- end
22
-
23
- def get_values(doc, hash)
24
- hash.each do |key, value|
25
- get_value(doc, key, value)
26
- end
27
- end
28
- end
29
-
30
- # HMC information
31
- class ManagementConsole < HmcObject
32
- XMLMAP = {
33
- "ManagementConsoleName" => "name",
34
- "VersionInfo/BuildLevel" => "build_level",
35
- "BaseVersion" => "version"
36
- }.freeze
37
-
38
- def initialize(doc)
39
- super(doc)
40
- info = doc.elements["content/ManagementConsole:ManagementConsole"]
41
- get_values(info, XMLMAP)
42
- end
43
- end
44
-
45
- # Managed System information
46
- class ManagedSystem < HmcObject
47
- XMLMAP = {
48
- "SystemName" => "name",
49
- "State" => "state",
50
- "Hostname" => "hostname",
51
- "PrimaryIPAddress" => "ipaddr",
52
- "AssociatedSystemMemoryConfiguration/InstalledSystemMemory" => "memory",
53
- "AssociatedSystemMemoryConfiguration/CurrentAvailableSystemMemory" => "avail_mem",
54
- "AssociatedSystemProcessorConfiguration/InstalledSystemProcessorUnits" => "cpus",
55
- "AssociatedSystemProcessorConfiguration/CurrentAvailableSystemProcessorUnits" => "avail_cpus",
56
- "MachineTypeModelAndSerialNumber/MachineType" => "mtype",
57
- "MachineTypeModelAndSerialNumber/Model" => "model",
58
- "MachineTypeModelAndSerialNumber/SerialNumber" => "serial",
59
- }.freeze
60
-
61
- def initialize(doc)
62
- super(doc)
63
- info = doc.elements["content/ManagedSystem:ManagedSystem"]
64
- get_values(info, XMLMAP)
65
- end
66
- end
67
-
68
- # Logical Partition information
69
- class LogicalPartition < HmcObject
70
- attr_reader :sys_uuid
71
-
72
- XMLMAP = {
73
- "PartitionName" => "name",
74
- "PartitionID" => "id",
75
- "PartitionState" => "state",
76
- "PartitionType" => "type",
77
- "PartitionMemoryConfiguration/CurrentMemory" => "memory",
78
- "PartitionProcessorConfiguration/HasDedicatedProcessors" => "dedicated",
79
- "ResourceMonitoringControlState" => "rmc_state",
80
- "ResourceMonitoringIPAddress" => "rmc_ipaddr"
81
- }.freeze
82
-
83
- def initialize(doc)
84
- super(doc)
85
- info = doc.elements["content/LogicalPartition:LogicalPartition"]
86
- sys_href = info.elements["AssociatedManagedSystem"].attributes["href"]
87
- @sys_uuid = URI(sys_href).path.split('/').last
88
- get_values(info, XMLMAP)
89
- end
90
- end
91
-
92
- # VIOS information
93
- class VirtualIOServer < HmcObject
94
- attr_reader :sys_uuid
95
-
96
- XMLMAP = {
97
- "PartitionName" => "name",
98
- "PartitionID" => "id",
99
- "PartitionState" => "state",
100
- "PartitionType" => "type",
101
- "PartitionMemoryConfiguration/CurrentMemory" => "memory",
102
- "PartitionProcessorConfiguration/HasDedicatedProcessors" => "dedicated"
103
- }.freeze
104
-
105
- def initialize(doc)
106
- super(doc)
107
- info = doc.elements["content/VirtualIOServer:VirtualIOServer"]
108
- sys_href = info.elements["AssociatedManagedSystem"].attributes["href"]
109
- @sys_uuid = URI(sys_href).path.split('/').last
110
- get_values(info, XMLMAP)
111
- end
112
- end
113
-
114
- # HMC Event
115
- class Event < HmcObject
116
- attr_reader :published
117
-
118
- XMLMAP = {
119
- "EventID" => "id",
120
- "EventType" => "type",
121
- "EventData" => "data",
122
- "EventDetail" => "detail",
123
- }.freeze
124
-
125
- def initialize(doc)
126
- super(doc)
127
- @published = doc.elements["published"].text
128
- info = doc.elements["content/Event:Event"]
129
- get_values(info, XMLMAP)
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
141
-
142
- def initialize(doc)
143
- super(doc)
144
- info = doc.elements["content/HttpErrorResponse:HttpErrorResponse"]
145
- get_values(info, XMLMAP)
146
- end
147
- end
148
- end