ibm_power_hmc 0.20.0 → 0.21.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49c35a3e54753bb8c31a1eafc7c6e98e0ad2a662d4d24c284e873ec3d30aa144
4
- data.tar.gz: 8429c8a52729102cfcdd2294fc25a2a27dd3f01b0ba9f3f0e46ebbea931903ac
3
+ metadata.gz: 5e08e948608c194fe9442a0c599b579eda9d5419d7fe4688e3c48efd6e69e240
4
+ data.tar.gz: 56b1483268a63580b3a578a93191b20de00fcc32a2f28bf225ffa6feb4ccf155
5
5
  SHA512:
6
- metadata.gz: 7b0cdb3f5348b221cd5fd147e63d391719b06324a49eec554fd1820d90f8000fb4000e005d5e638e6445be0608f7ea30a3a1db1d1345ac1cbf32526fd428f01f
7
- data.tar.gz: 06d590cf0b6f2d92fbdd685d511ebd499597a285a248807cbe2814e5d569ad237753c7b2196c03b40d9f4be25d08071f990dc3d9d3fad0b20e4f5a8ef7a64438
6
+ metadata.gz: 88efdce121a41980815d40a727c6659936c5ffc52523e554f0618eaa1c539866e8160674b2bfdd78320a1780cac40143b631237f1e5bde4c8f500acc8103324b
7
+ data.tar.gz: 621108e32a80a207edba249d642af72814b5916ee404da36d84ebbd26f8e9442281127a68fcb878565517feb3a62d2fc8639a39b9d7bbea4663b3dd94e666968
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## v0.21.0
2
+ * Add methods to create/delete LPAR client network adapters
3
+ * Add methods and schema definitions for volume groups
4
+ * Add label and page83 schema definitions for PVs
5
+ * Add schema definitions for capabilities of lpars and vioses
1
6
  ## v0.20.0
2
7
  * Add permissive option (`ignoreError=true`) for cluster APIs
3
8
  * Fix `modify_object` method when URI has a query part
@@ -2,6 +2,9 @@
2
2
 
3
3
  # Module for IBM HMC Rest API Client
4
4
  module IbmPowerHmc
5
+ WEB_XMLNS = "http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/"
6
+ UOM_XMLNS = "http://www.ibm.com/xmlns/systems/power/firmware/uom/mc/2012_10/"
7
+
5
8
  class Error < StandardError; end
6
9
 
7
10
  ##
@@ -37,7 +40,7 @@ module IbmPowerHmc
37
40
  }
38
41
  doc = REXML::Document.new("")
39
42
  doc.add_element("LogonRequest", "schemaVersion" => "V1_1_0")
40
- doc.root.add_namespace("http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/")
43
+ doc.root.add_namespace(WEB_XMLNS)
41
44
  doc.root.add_element("UserID").text = @username
42
45
  doc.root.add_element("Password").text = @password
43
46
 
@@ -122,7 +125,7 @@ module IbmPowerHmc
122
125
  end
123
126
 
124
127
  def to_s
125
- "msg=\"#{@message}\" status=\"#{@status}\" reason=\"#{@reason}\" uri=#{@uri}"
128
+ %(msg="#{@message}" status="#{@status}" reason="#{@reason}" uri=#{@uri})
126
129
  end
127
130
  end
128
131
 
@@ -7,13 +7,15 @@ module IbmPowerHmc
7
7
  class JobNotStarted < StandardError; end
8
8
 
9
9
  class JobFailed < StandardError
10
+ attr_reader :job
11
+
10
12
  def initialize(job)
11
13
  super
12
14
  @job = job
13
15
  end
14
16
 
15
17
  def to_s
16
- "id=\"#{@job.id}\" operation=\"#{@job.group}/#{@job.operation}\" status=\"#{@job.status}\" message=\"#{@job.message}\" exception_text=\"#{@job.results['ExceptionText']}\""
18
+ %(#{job.status} err="#{job.results["result"]}" rc=#{job.results["returnCode"]} msg="#{job.message}" exception="#{job.results["ExceptionText"]}" url=#{job.url} id=#{job.id})
17
19
  end
18
20
  end
19
21
 
@@ -42,21 +44,8 @@ module IbmPowerHmc
42
44
  headers = {
43
45
  :content_type => "application/vnd.ibm.powervm.web+xml; type=JobRequest"
44
46
  }
45
- doc = REXML::Document.new("")
46
- doc.add_element("JobRequest:JobRequest", "schemaVersion" => "V1_1_0")
47
- doc.root.add_namespace("http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/")
48
- doc.root.add_namespace("JobRequest", "http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/")
49
- op = doc.root.add_element("RequestedOperation", "schemaVersion" => "V1_1_0")
50
- op.add_element("OperationName").text = @operation
51
- op.add_element("GroupName").text = @group
52
-
53
- jobparams = doc.root.add_element("JobParameters", "schemaVersion" => "V1_1_0")
54
- @params.each do |key, value|
55
- jobparam = jobparams.add_element("JobParameter", "schemaVersion" => "V1_1_0")
56
- jobparam.add_element("ParameterName").text = key
57
- jobparam.add_element("ParameterValue").text = value
58
- end
59
- response = @conn.request(:put, @method_url, headers, doc.to_s)
47
+ jobreq = JobRequest.marshal({:operation => @operation, :group => @group, :params => @params}, WEB_XMLNS)
48
+ response = @conn.request(:put, @method_url, headers, jobreq.xml.to_s)
60
49
  jobresp = Parser.new(response.body).object(:JobResponse)
61
50
  # Save the URL of the job (JobID is not sufficient as not all jobs are in uom).
62
51
  @href = jobresp.href.path
@@ -234,6 +234,29 @@ module IbmPowerHmc
234
234
  JSON.parse(response.body)
235
235
  end
236
236
 
237
+ ##
238
+ # @!method volume_groups(vios_uuid)
239
+ # Retrieve the list of volume groups available on a virtual I/O server.
240
+ # @param vios_uuid [String] The UUID of the virtual I/O server.
241
+ # @return [Array<IbmPowerHmc::VolumeGroup>] The list of volume groups.
242
+ def volume_groups(vios_uuid)
243
+ method_url = "/rest/api/uom/VirtualIOServer/#{vios_uuid}/VolumeGroup"
244
+ response = request(:get, method_url)
245
+ FeedParser.new(response.body).objects(:VolumeGroup)
246
+ end
247
+
248
+ ##
249
+ # @!method volume_group(vios_uuid, vg_uuid)
250
+ # Retrieve information about a volume group on a virtual I/O server.
251
+ # @param vios_uuid [String] The UUID of the virtual I/O server.
252
+ # @param vg_uuid [String] The UUID of the volume group.
253
+ # @return [IbmPowerHmc::VolumeGroup] The volume groups.
254
+ def volume_group(vios_uuid, vg_uuid)
255
+ method_url = "/rest/api/uom/VirtualIOServer/#{vios_uuid}/VolumeGroup/#{vg_uuid}"
256
+ response = request(:get, method_url)
257
+ Parser.new(response.body).object(:VolumeGroup)
258
+ end
259
+
237
260
  ##
238
261
  # @!method groups
239
262
  # Retrieve the list of groups defined on the HMC.
@@ -325,6 +348,36 @@ module IbmPowerHmc
325
348
  end
326
349
  private :network_adapter
327
350
 
351
+ ##
352
+ # @!method network_adapter_lpar_create(lpar_uuid, sys_uuid, vswitch_uuid, **args)
353
+ # Create a virtual ethernet network adapter attached to a logical partition.
354
+ # @param lpar_uuid [String] UUID of the logical partition.
355
+ # @param sys_uuid [String] UUID of the managed system of the virtual switch.
356
+ # @param vswitch_uuid [String] UUID of the virtual switch.
357
+ # @param args [Hash] The network adapter properties.
358
+ # @return [IbmPowerHmc::ClientNetworkAdapter] The created network adapter.
359
+ def network_adapter_lpar_create(lpar_uuid, sys_uuid, vswitch_uuid, **args)
360
+ method_url = "/rest/api/uom/LogicalPartition/#{lpar_uuid}/ClientNetworkAdapter"
361
+ headers = {
362
+ :content_type => "application/vnd.ibm.powervm.uom+xml; type=ClientNetworkAdapter"
363
+ }
364
+ args[:vswitch_href] = "/rest/api/uom/ManagedSystem/#{sys_uuid}/VirtualSwitch/#{vswitch_uuid}"
365
+ netadap = ClientNetworkAdapter.marshal(args)
366
+ response = request(:put, method_url, headers, netadap.xml.to_s)
367
+ Parser.new(response.body).object(:ClientNetworkAdapter)
368
+ end
369
+
370
+ ##
371
+ # @!method network_adapter_lpar_delete(lpar_uuid, netadap_uuid)
372
+ # Delete a virtual ethernet network adapter attached to a logical partition.
373
+ # @param lpar_uuid [String] UUID of the logical partition.
374
+ # @param netadap_uuid [String] UUID of the adapter to delete.
375
+ def network_adapter_lpar_delete(lpar_uuid, netadap_uuid)
376
+ method_url = "/rest/api/uom/LogicalPartition/#{lpar_uuid}/ClientNetworkAdapter/#{netadap_uuid}"
377
+ request(:delete, method_url)
378
+ # Returns HTTP 204 if ok
379
+ end
380
+
328
381
  ##
329
382
  # @!method sriov_elp_lpar(lpar_uuid, sriov_elp_uuid = nil)
330
383
  # Retrieve one or all SR-IOV ethernet logical ports attached to a logical partition.
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IbmPowerHmc
4
+ # Job Request
5
+ class JobRequest < AbstractRest
6
+ def operation
7
+ singleton("RequestedOperation/OperationName")
8
+ end
9
+
10
+ def operation=(operation)
11
+ elem = xml.elements["RequestedOperation"]
12
+ elem = xml.add_element("RequestedOperation", "schemaVersion" => "V1_1_0") if elem.nil?
13
+ elem.add_element("OperationName").text = operation
14
+ end
15
+
16
+ def group
17
+ singleton("RequestedOperation/GroupName")
18
+ end
19
+
20
+ def group=(group)
21
+ elem = xml.elements["RequestedOperation"]
22
+ elem = xml.add_element("RequestedOperation", "schemaVersion" => "V1_1_0") if elem.nil?
23
+ elem.add_element("GroupName").text = group
24
+ end
25
+
26
+ def params
27
+ params = {}
28
+ xml.each_element("JobParameters/JobParameter") do |jobparam|
29
+ name = jobparam.elements["ParameterName"]&.text&.strip
30
+ value = jobparam.elements["ParameterValue"]&.text&.strip
31
+ params[name] = value unless name.nil?
32
+ end
33
+ params
34
+ end
35
+
36
+ def params=(params)
37
+ jobparams = xml.add_element("JobParameters", "schemaVersion" => "V1_1_0")
38
+ params.each do |key, value|
39
+ jobparam = jobparams.add_element("JobParameter", "schemaVersion" => "V1_1_0")
40
+ jobparam.add_element("ParameterName").text = key
41
+ jobparam.add_element("ParameterValue").text = value
42
+ end
43
+ end
44
+ end
45
+
46
+ # Job Response
47
+ class JobResponse < AbstractRest
48
+ ATTRS = {
49
+ :id => "JobID",
50
+ :status => "Status",
51
+ :message => "ResponseException/Message",
52
+ :target_uuid => "TargetUuid",
53
+ :linear_progress => "Progress/LinearProgress"
54
+ }.freeze
55
+
56
+ def url
57
+ singleton("RequestURL", "href")
58
+ end
59
+
60
+ def request
61
+ elem = xml.elements["JobRequestInstance"]
62
+ JobRequest.new(elem) unless elem.nil?
63
+ end
64
+
65
+ def started_at
66
+ timestamp("TimeStarted")
67
+ end
68
+
69
+ def completed_at
70
+ timestamp("TimeCompleted")
71
+ end
72
+
73
+ def results
74
+ results = {}
75
+ xml.each_element("Results/JobParameter") do |jobparam|
76
+ name = jobparam.elements["ParameterName"]&.text&.strip
77
+ value = jobparam.elements["ParameterValue"]&.text&.strip
78
+ results[name] = value unless name.nil?
79
+ end
80
+ results
81
+ end
82
+ end
83
+ end
@@ -87,6 +87,23 @@ module IbmPowerHmc
87
87
  self.class::ATTRS.each { |varname, xpath| define_attr(varname, xpath) }
88
88
  end
89
89
 
90
+ ##
91
+ # @!method marshal(attrs = {}, namespace = UOM_XMLNS, version = "V1_1_0")
92
+ # XML marshaling of object.
93
+ # @param attrs [Hash] The initial properties of the object.
94
+ # @param namespace [String] The XML namespace to use.
95
+ # @param version [String] The XML schema version to use.
96
+ def self.marshal(attrs = {}, namespace = UOM_XMLNS, version = "V1_1_0")
97
+ doc = REXML::Document.new("")
98
+ doc.add_element(name.split("::").last, "schemaVersion" => version)
99
+ doc.root.add_namespace(namespace)
100
+ obj = new(doc.root)
101
+ attrs.each do |varname, value|
102
+ obj.send("#{varname}=", value)
103
+ end
104
+ obj
105
+ end
106
+
90
107
  ##
91
108
  # @!method define_attr(varname, xpath)
92
109
  # Define an instance variable using the text of an XML element as value.
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'base64'
4
+
3
5
  module IbmPowerHmc
4
6
  # HMC information
5
7
  class ManagementConsole < AbstractRest
@@ -74,7 +76,7 @@ module IbmPowerHmc
74
76
 
75
77
  def capabilities
76
78
  xml.get_elements("AssociatedSystemCapabilities/*").map do |elem|
77
- elem.name unless elem.text&.strip != "true"
79
+ elem.name if elem.text&.strip == "true"
78
80
  end.compact
79
81
  end
80
82
 
@@ -141,6 +143,9 @@ module IbmPowerHmc
141
143
  :os => "OperatingSystemVersion",
142
144
  :ref_code => "ReferenceCode",
143
145
  :procs => "PartitionProcessorConfiguration/CurrentDedicatedProcessorConfiguration/CurrentProcessors",
146
+ :desired_procs => "PartitionProcessorConfiguration/DedicatedProcessorConfiguration/DesiredProcessors",
147
+ :minimum_procs => "PartitionProcessorConfiguration/DedicatedProcessorConfiguration/MinimumProcessors",
148
+ :maximum_procs => "PartitionProcessorConfiguration/DedicatedProcessorConfiguration/MaximumProcessors",
144
149
  :proc_units => "PartitionProcessorConfiguration/CurrentSharedProcessorConfiguration/CurrentProcessingUnits",
145
150
  :vprocs => "PartitionProcessorConfiguration/CurrentSharedProcessorConfiguration/AllocatedVirtualProcessors",
146
151
  :desired_proc_units => "PartitionProcessorConfiguration/SharedProcessorConfiguration/DesiredProcessingUnits",
@@ -174,6 +179,12 @@ module IbmPowerHmc
174
179
  uuids_from_links("SRIOVEthernetLogicalPorts")
175
180
  end
176
181
 
182
+ def capabilities
183
+ xml.get_elements("PartitionCapabilities/*").map do |elem|
184
+ elem.name if elem.text&.strip == "true"
185
+ end.compact
186
+ end
187
+
177
188
  def io_adapters
178
189
  collection_of("PartitionIOConfiguration/ProfileIOSlots/ProfileIOSlot/AssociatedIOSlot/RelatedIOAdapter", "*[1]")
179
190
  end
@@ -201,10 +212,20 @@ module IbmPowerHmc
201
212
 
202
213
  # VIOS information
203
214
  class VirtualIOServer < BasePartition
215
+ def capabilities
216
+ xml.get_elements("VirtualIOServerCapabilities/*").map do |elem|
217
+ elem.name if elem.text&.strip == "true"
218
+ end.compact.concat(super)
219
+ end
220
+
204
221
  def pvs
205
222
  collection_of("PhysicalVolumes", "PhysicalVolume")
206
223
  end
207
224
 
225
+ def vg_uuids
226
+ uuids_from_links("StoragePools")
227
+ end
228
+
208
229
  def rep
209
230
  elem = xml.elements["MediaRepositories/VirtualMediaRepository"]
210
231
  VirtualMediaRepository.new(elem) unless elem.nil?
@@ -295,6 +316,33 @@ module IbmPowerHmc
295
316
  }.freeze
296
317
  end
297
318
 
319
+ # Volume Group information
320
+ class VolumeGroup < AbstractRest
321
+ ATTRS = {
322
+ :udid => "UniqueDeviceID",
323
+ :size => "AvailableSize", # in GiB
324
+ :dev_count => "BackingDeviceCount",
325
+ :free_space => "FreeSpace", # in GiB
326
+ :capacity => "GroupCapacity",
327
+ :name => "GroupName",
328
+ :serial => "GroupSerialID",
329
+ :state => "GroupState",
330
+ :max_lvs => "MaximumLogicalVolumes"
331
+ }.freeze
332
+
333
+ def reps
334
+ collection_of("MediaRepositories", "VirtualMediaRepository")
335
+ end
336
+
337
+ def pvs
338
+ collection_of("PhysicalVolumes", "PhysicalVolume")
339
+ end
340
+
341
+ def lvs
342
+ collection_of("VirtualDisks", "VirtualDisk")
343
+ end
344
+ end
345
+
298
346
  # Empty parent class to match K2 schema definition
299
347
  class VirtualSCSIStorage < AbstractNonRest; end
300
348
 
@@ -307,8 +355,19 @@ module IbmPowerHmc
307
355
  :capacity => "VolumeCapacity", # in MiB
308
356
  :name => "VolumeName",
309
357
  :is_fc => "IsFibreChannelBacked",
358
+ :is_iscsi => "IsISCSIBacked",
310
359
  :udid => "VolumeUniqueID"
311
360
  }.freeze
361
+
362
+ def label
363
+ str = singleton("StorageLabel")
364
+ Base64.decode64(str) unless str.nil?
365
+ end
366
+
367
+ def page83
368
+ str = singleton("DescriptorPage83")
369
+ Base64.decode64(str) unless str.nil?
370
+ end
312
371
  end
313
372
 
314
373
  # Logical Volume information
@@ -318,9 +377,13 @@ module IbmPowerHmc
318
377
  :label => "DiskLabel",
319
378
  :capacity => "DiskCapacity", # in GiB
320
379
  :psize => "PartitionSize",
321
- :vg => "VolumeGroup",
322
380
  :udid => "UniqueDeviceID"
323
381
  }.freeze
382
+
383
+ def vg_uuid
384
+ href = singleton("VolumeGroup", "href")
385
+ uuid_from_href(href) unless href.nil?
386
+ end
324
387
  end
325
388
 
326
389
  # Virtual CD-ROM information
@@ -415,6 +478,10 @@ module IbmPowerHmc
415
478
  def vswitch_uuid
416
479
  uuids_from_links("AssociatedVirtualSwitch").first
417
480
  end
481
+
482
+ def vswitch_href=(href)
483
+ xml.add_element("AssociatedVirtualSwitch").add_element("link", "href" => href, "rel" => "related")
484
+ end
418
485
  end
419
486
 
420
487
  # Client Network Adapter information
@@ -849,25 +916,4 @@ module IbmPowerHmc
849
916
  :detail => "EventDetail"
850
917
  }.freeze
851
918
  end
852
-
853
- # Job Response
854
- class JobResponse < AbstractRest
855
- ATTRS = {
856
- :id => "JobID",
857
- :status => "Status",
858
- :operation => "JobRequestInstance/RequestedOperation/OperationName",
859
- :group => "JobRequestInstance/RequestedOperation/GroupName",
860
- :message => "ResponseException/Message"
861
- }.freeze
862
-
863
- def results
864
- results = {}
865
- xml.each_element("Results/JobParameter") do |jobparam|
866
- name = jobparam.elements["ParameterName"]&.text&.strip
867
- value = jobparam.elements["ParameterValue"]&.text&.strip
868
- results[name] = value unless name.nil?
869
- end
870
- results
871
- end
872
- end
873
919
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IbmPowerHmc
4
- VERSION = "0.20.0"
4
+ VERSION = "0.21.1"
5
5
  end
data/lib/ibm_power_hmc.rb CHANGED
@@ -14,6 +14,7 @@ module IbmPowerHmc
14
14
  require_relative "./ibm_power_hmc/apis/templates"
15
15
  require_relative "./ibm_power_hmc/apis/uom"
16
16
  require_relative "./ibm_power_hmc/schema/parser"
17
+ require_relative "./ibm_power_hmc/schema/job"
17
18
  require_relative "./ibm_power_hmc/schema/pcm"
18
19
  require_relative "./ibm_power_hmc/schema/sem"
19
20
  require_relative "./ibm_power_hmc/schema/templates"
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.20.0
4
+ version: 0.21.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - IBM Power
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-27 00:00:00.000000000 Z
11
+ date: 2022-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -62,6 +62,7 @@ files:
62
62
  - lib/ibm_power_hmc/apis/sem.rb
63
63
  - lib/ibm_power_hmc/apis/templates.rb
64
64
  - lib/ibm_power_hmc/apis/uom.rb
65
+ - lib/ibm_power_hmc/schema/job.rb
65
66
  - lib/ibm_power_hmc/schema/parser.rb
66
67
  - lib/ibm_power_hmc/schema/pcm.rb
67
68
  - lib/ibm_power_hmc/schema/sem.rb