ibm_power_hmc 0.20.0 → 0.21.0

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: 2a66a6b3ab2a70a1c398c51dae01828b936b6f859d34bc957ad22101e9314e11
4
+ data.tar.gz: 0f92d6cafc9348975d179b17e6451d31edae23d96a3314f6c4b3d9bc76d97cfa
5
5
  SHA512:
6
- metadata.gz: 7b0cdb3f5348b221cd5fd147e63d391719b06324a49eec554fd1820d90f8000fb4000e005d5e638e6445be0608f7ea30a3a1db1d1345ac1cbf32526fd428f01f
7
- data.tar.gz: 06d590cf0b6f2d92fbdd685d511ebd499597a285a248807cbe2814e5d569ad237753c7b2196c03b40d9f4be25d08071f990dc3d9d3fad0b20e4f5a8ef7a64438
6
+ metadata.gz: 996802e21a82bfaf391a84fb1872998ecd662b19f0a600315c0445ad817d3220b723879a99272ff79ff15f7add22d12bef6be275ff8106816fe3289e2113ad61
7
+ data.tar.gz: a4dd65ac732a8e4cda2377df1d87b575c9947e1c5a7a41bff19a4eda333ed49c0f92a754a4e864e2d00d93f55a4e47e6862ab5a701c5f0f2091a6e5cbcf05522
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
 
@@ -174,6 +176,12 @@ module IbmPowerHmc
174
176
  uuids_from_links("SRIOVEthernetLogicalPorts")
175
177
  end
176
178
 
179
+ def capabilities
180
+ xml.get_elements("PartitionCapabilities/*").map do |elem|
181
+ elem.name if elem.text&.strip == "true"
182
+ end.compact
183
+ end
184
+
177
185
  def io_adapters
178
186
  collection_of("PartitionIOConfiguration/ProfileIOSlots/ProfileIOSlot/AssociatedIOSlot/RelatedIOAdapter", "*[1]")
179
187
  end
@@ -201,10 +209,20 @@ module IbmPowerHmc
201
209
 
202
210
  # VIOS information
203
211
  class VirtualIOServer < BasePartition
212
+ def capabilities
213
+ xml.get_elements("VirtualIOServerCapabilities/*").map do |elem|
214
+ elem.name if elem.text&.strip == "true"
215
+ end.compact.concat(super)
216
+ end
217
+
204
218
  def pvs
205
219
  collection_of("PhysicalVolumes", "PhysicalVolume")
206
220
  end
207
221
 
222
+ def vg_uuids
223
+ uuids_from_links("StoragePools")
224
+ end
225
+
208
226
  def rep
209
227
  elem = xml.elements["MediaRepositories/VirtualMediaRepository"]
210
228
  VirtualMediaRepository.new(elem) unless elem.nil?
@@ -295,6 +313,33 @@ module IbmPowerHmc
295
313
  }.freeze
296
314
  end
297
315
 
316
+ # Volume Group information
317
+ class VolumeGroup < AbstractRest
318
+ ATTRS = {
319
+ :udid => "UniqueDeviceID",
320
+ :size => "AvailableSize", # in GiB
321
+ :dev_count => "BackingDeviceCount",
322
+ :free_space => "FreeSpace", # in GiB
323
+ :capacity => "GroupCapacity",
324
+ :name => "GroupName",
325
+ :serial => "GroupSerialID",
326
+ :state => "GroupState",
327
+ :max_lvs => "MaximumLogicalVolumes"
328
+ }.freeze
329
+
330
+ def reps
331
+ collection_of("MediaRepositories", "VirtualMediaRepository")
332
+ end
333
+
334
+ def pvs
335
+ collection_of("PhysicalVolumes", "PhysicalVolume")
336
+ end
337
+
338
+ def lvs
339
+ collection_of("VirtualDisks", "VirtualDisk")
340
+ end
341
+ end
342
+
298
343
  # Empty parent class to match K2 schema definition
299
344
  class VirtualSCSIStorage < AbstractNonRest; end
300
345
 
@@ -307,8 +352,19 @@ module IbmPowerHmc
307
352
  :capacity => "VolumeCapacity", # in MiB
308
353
  :name => "VolumeName",
309
354
  :is_fc => "IsFibreChannelBacked",
355
+ :is_iscsi => "IsISCSIBacked",
310
356
  :udid => "VolumeUniqueID"
311
357
  }.freeze
358
+
359
+ def label
360
+ str = singleton("StorageLabel")
361
+ Base64.decode64(str) unless str.nil?
362
+ end
363
+
364
+ def page83
365
+ str = singleton("DescriptorPage83")
366
+ Base64.decode64(str) unless str.nil?
367
+ end
312
368
  end
313
369
 
314
370
  # Logical Volume information
@@ -318,9 +374,13 @@ module IbmPowerHmc
318
374
  :label => "DiskLabel",
319
375
  :capacity => "DiskCapacity", # in GiB
320
376
  :psize => "PartitionSize",
321
- :vg => "VolumeGroup",
322
377
  :udid => "UniqueDeviceID"
323
378
  }.freeze
379
+
380
+ def vg_uuid
381
+ href = singleton("VolumeGroup", "href")
382
+ uuid_from_href(href) unless href.nil?
383
+ end
324
384
  end
325
385
 
326
386
  # Virtual CD-ROM information
@@ -415,6 +475,10 @@ module IbmPowerHmc
415
475
  def vswitch_uuid
416
476
  uuids_from_links("AssociatedVirtualSwitch").first
417
477
  end
478
+
479
+ def vswitch_href=(href)
480
+ xml.add_element("AssociatedVirtualSwitch").add_element("link", "href" => href, "rel" => "related")
481
+ end
418
482
  end
419
483
 
420
484
  # Client Network Adapter information
@@ -849,25 +913,4 @@ module IbmPowerHmc
849
913
  :detail => "EventDetail"
850
914
  }.freeze
851
915
  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
916
  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.0"
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.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: 2022-10-27 00:00:00.000000000 Z
11
+ date: 2022-11-14 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