ibm_power_hmc 0.20.0 → 0.21.1

Sign up to get free protection for your applications and to get access to all the features.
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